2014-07-07 00:19:45 +08:00
/*
Copyright ( C ) 2014 by Project Tox < https : //tox.im>
This file is part of qTox , a Qt - based graphical interface for Tox .
This program is libre 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 COPYING file for more details .
*/
2014-06-25 04:11:11 +08:00
# include "widget.h"
2014-08-11 16:00:08 +08:00
# include "ui_mainwindow.h"
2014-10-08 12:26:25 +08:00
# include "src/core.h"
# include "src/misc/settings.h"
# include "src/friend.h"
# include "src/friendlist.h"
# include "tool/friendrequestdialog.h"
# include "friendwidget.h"
# include "src/grouplist.h"
# include "src/group.h"
# include "groupwidget.h"
# include "form/groupchatform.h"
# include "src/misc/style.h"
# include "friendlistwidget.h"
2014-10-24 04:07:44 +08:00
# include "src/video/camera.h"
2014-10-08 12:26:25 +08:00
# include "form/chatform.h"
# include "maskablepixmapwidget.h"
2014-11-10 00:55:38 +08:00
# include "src/historykeeper.h"
# include "src/autoupdate.h"
2014-11-17 02:04:45 +08:00
# include "src/audio.h"
2014-11-27 21:13:35 +08:00
# include "src/platform/timer.h"
2015-01-29 21:56:53 +08:00
# include "systemtrayicon.h"
2015-02-06 19:28:49 +08:00
# include "src/nexus.h"
2015-02-16 07:24:42 +08:00
# include "src/widget/gui.h"
2015-02-08 00:18:25 +08:00
# include "src/offlinemsgengine.h"
2015-02-07 02:51:03 +08:00
# include <cassert>
2014-06-25 04:11:11 +08:00
# include <QMessageBox>
# include <QDebug>
2014-07-01 10:12:17 +08:00
# include <QFile>
# include <QString>
2014-09-24 22:51:16 +08:00
# include <QBuffer>
2014-07-01 10:12:17 +08:00
# include <QPainter>
# include <QMouseEvent>
2014-07-02 05:50:07 +08:00
# include <QClipboard>
2014-09-11 21:44:34 +08:00
# include <QThread>
2015-02-05 06:11:21 +08:00
# include <QDialogButtonBox>
2014-10-16 17:47:58 +08:00
# include <QTimer>
2014-10-09 06:31:20 +08:00
# include <QStyleFactory>
2014-10-18 07:06:30 +08:00
# include <QTranslator>
2015-02-13 22:23:21 +08:00
# include <QString>
# include <QByteArray>
# include <QImageReader>
# include <QList>
2015-02-22 20:21:42 +08:00
# include <QDesktopServices>
# include <QProcess>
2014-10-18 07:06:30 +08:00
# include <tox/tox.h>
2014-06-25 04:11:11 +08:00
2015-02-07 02:51:03 +08:00
# ifdef Q_OS_ANDROID
# define IS_ON_DESKTOP_GUI 0
# else
# define IS_ON_DESKTOP_GUI 1
# endif
2015-02-20 20:26:41 +08:00
bool toxActivateEventHandler ( const QByteArray & )
2014-11-26 01:11:05 +08:00
{
2015-02-20 20:26:41 +08:00
if ( ! Widget : : getInstance ( ) - > isActiveWindow ( ) )
Widget : : getInstance ( ) - > forceShow ( ) ;
return true ;
2014-11-26 01:11:05 +08:00
}
2014-06-25 04:11:11 +08:00
Widget * Widget : : instance { nullptr } ;
2014-08-11 16:00:08 +08:00
Widget : : Widget ( QWidget * parent )
: QMainWindow ( parent ) ,
2015-02-06 08:27:07 +08:00
icon { nullptr } ,
2014-08-11 16:00:08 +08:00
ui ( new Ui : : MainWindow ) ,
2014-12-12 00:49:11 +08:00
activeChatroomWidget { nullptr } ,
eventFlag ( false ) ,
2015-02-06 08:27:07 +08:00
eventIcon ( false )
2014-10-18 22:54:52 +08:00
{
2014-10-18 07:06:30 +08:00
translator = new QTranslator ;
setTranslation ( ) ;
2014-10-15 23:35:58 +08:00
}
void Widget : : init ( )
2014-06-25 04:11:11 +08:00
{
ui - > setupUi ( this ) ;
2014-11-28 17:16:37 +08:00
2015-03-11 19:01:10 +08:00
QIcon themeIcon = QIcon : : fromTheme ( " qtox " ) ;
if ( ! themeIcon . isNull ( ) )
setWindowIcon ( themeIcon ) ;
2014-12-12 00:49:11 +08:00
timer = new QTimer ( ) ;
timer - > start ( 1000 ) ;
2015-02-08 00:18:25 +08:00
offlineMsgTimer = new QTimer ( ) ;
offlineMsgTimer - > start ( 15000 ) ;
2014-12-02 04:02:44 +08:00
2014-11-28 17:16:37 +08:00
//restore window state
restoreGeometry ( Settings : : getInstance ( ) . getWindowGeometry ( ) ) ;
restoreState ( Settings : : getInstance ( ) . getWindowState ( ) ) ;
ui - > mainSplitter - > restoreState ( Settings : : getInstance ( ) . getSplitterState ( ) ) ;
2015-02-07 02:16:01 +08:00
statusOnline = new QAction ( tr ( " Online " , " Button to set your status to 'Online' " ) , this ) ;
statusOnline - > setIcon ( QIcon ( " :img/status/dot_online.png " ) ) ;
connect ( statusOnline , SIGNAL ( triggered ( ) ) , this , SLOT ( setStatusOnline ( ) ) ) ;
statusAway = new QAction ( tr ( " Away " , " Button to set your status to 'Away' " ) , this ) ;
statusAway - > setIcon ( QIcon ( " :img/status/dot_idle.png " ) ) ;
connect ( statusAway , SIGNAL ( triggered ( ) ) , this , SLOT ( setStatusAway ( ) ) ) ;
statusBusy = new QAction ( tr ( " Busy " , " Button to set your status to 'Busy' " ) , this ) ;
statusBusy - > setIcon ( QIcon ( " :img/status/dot_busy.png " ) ) ;
connect ( statusBusy , SIGNAL ( triggered ( ) ) , this , SLOT ( setStatusBusy ( ) ) ) ;
2014-08-11 16:00:08 +08:00
ui - > statusbar - > hide ( ) ;
ui - > menubar - > hide ( ) ;
2014-10-04 16:54:50 +08:00
layout ( ) - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
2014-11-16 01:29:41 +08:00
ui - > friendList - > setStyleSheet ( Style : : resolve ( Style : : getStylesheet ( " :ui/friendList/friendList.css " ) ) ) ;
2014-07-01 10:12:17 +08:00
2014-10-18 22:54:52 +08:00
profilePicture = new MaskablePixmapWidget ( this , QSize ( 40 , 40 ) , " :/img/avatar_mask.png " ) ;
2014-09-27 23:58:56 +08:00
profilePicture - > setPixmap ( QPixmap ( " :/img/contact_dark.png " ) ) ;
2014-09-28 01:13:46 +08:00
profilePicture - > setClickable ( true ) ;
2014-11-03 07:26:23 +08:00
ui - > myProfile - > insertWidget ( 0 , profilePicture ) ;
ui - > myProfile - > insertSpacing ( 1 , 7 ) ;
2014-09-26 22:39:29 +08:00
2014-06-25 04:11:11 +08:00
ui - > mainContent - > setLayout ( new QVBoxLayout ( ) ) ;
ui - > mainHead - > setLayout ( new QVBoxLayout ( ) ) ;
2014-06-26 04:43:28 +08:00
ui - > mainHead - > layout ( ) - > setMargin ( 0 ) ;
ui - > mainHead - > layout ( ) - > setSpacing ( 0 ) ;
2014-10-09 06:31:20 +08:00
2014-11-16 01:29:41 +08:00
ui - > tooliconsZone - > setStyleSheet ( Style : : resolve ( " QPushButton{background-color:@themeDark;border:none;}QPushButton:hover{background-color:@themeMediumDark;border:none;} " ) ) ;
2014-12-12 02:05:52 +08:00
if ( QStyleFactory : : keys ( ) . contains ( Settings : : getInstance ( ) . getStyle ( ) )
2014-10-09 06:31:20 +08:00
& & Settings : : getInstance ( ) . getStyle ( ) ! = " None " )
{
ui - > mainHead - > setStyle ( QStyleFactory : : create ( Settings : : getInstance ( ) . getStyle ( ) ) ) ;
ui - > mainContent - > setStyle ( QStyleFactory : : create ( Settings : : getInstance ( ) . getStyle ( ) ) ) ;
}
ui - > mainHead - > setStyleSheet ( Style : : getStylesheet ( " :ui/settings/mainHead.css " ) ) ;
2014-10-07 17:50:36 +08:00
ui - > mainContent - > setStyleSheet ( Style : : getStylesheet ( " :ui/settings/mainContent.css " ) ) ;
2014-11-03 07:26:23 +08:00
ui - > statusHead - > setStyleSheet ( Style : : getStylesheet ( " :/ui/window/statusPanel.css " ) ) ;
2014-08-11 16:00:08 +08:00
2014-08-22 23:19:16 +08:00
contactListWidget = new FriendListWidget ( ) ;
ui - > friendList - > setWidget ( contactListWidget ) ;
2014-08-12 01:46:14 +08:00
ui - > friendList - > setLayoutDirection ( Qt : : RightToLeft ) ;
2014-06-25 04:11:11 +08:00
2014-09-01 17:08:02 +08:00
ui - > statusLabel - > setEditable ( true ) ;
2014-10-04 16:24:20 +08:00
ui - > statusPanel - > setStyleSheet ( Style : : getStylesheet ( " :/ui/window/statusPanel.css " ) ) ;
2014-07-06 03:30:00 +08:00
2014-07-06 04:54:27 +08:00
QMenu * statusButtonMenu = new QMenu ( ui - > statusButton ) ;
2015-02-07 02:16:01 +08:00
statusButtonMenu - > addAction ( statusOnline ) ;
statusButtonMenu - > addAction ( statusAway ) ;
statusButtonMenu - > addAction ( statusBusy ) ;
2014-07-06 04:54:27 +08:00
ui - > statusButton - > setMenu ( statusButtonMenu ) ;
2014-08-11 19:56:52 +08:00
// disable proportional scaling
2014-08-11 20:07:27 +08:00
ui - > mainSplitter - > setStretchFactor ( 0 , 0 ) ;
ui - > mainSplitter - > setStretchFactor ( 1 , 1 ) ;
2014-06-25 04:11:11 +08:00
2014-10-04 16:24:20 +08:00
ui - > statusButton - > setProperty ( " status " , " offline " ) ;
Style : : repolish ( ui - > statusButton ) ;
2014-07-06 21:51:24 +08:00
2014-09-03 06:01:04 +08:00
// Disable some widgets until we're connected to the DHT
ui - > statusButton - > setEnabled ( false ) ;
2014-11-16 04:30:20 +08:00
Style : : setThemeColor ( Settings : : getInstance ( ) . getThemeColor ( ) ) ;
2015-02-07 02:01:31 +08:00
reloadTheme ( ) ;
2014-10-18 22:54:52 +08:00
filesForm = new FilesForm ( ) ;
addFriendForm = new AddFriendForm ;
2015-03-04 04:29:01 +08:00
profileForm = new ProfileForm ( ) ;
2014-10-18 22:54:52 +08:00
settingsWidget = new SettingsWidget ( ) ;
2014-06-25 04:11:11 +08:00
2015-02-06 19:28:49 +08:00
Core * core = Nexus : : getCore ( ) ;
2014-10-18 22:54:52 +08:00
connect ( core , SIGNAL ( fileDownloadFinished ( const QString & ) ) , filesForm , SLOT ( onFileDownloadComplete ( const QString & ) ) ) ;
connect ( core , SIGNAL ( fileUploadFinished ( const QString & ) ) , filesForm , SLOT ( onFileUploadComplete ( const QString & ) ) ) ;
2015-02-06 19:28:49 +08:00
connect ( settingsWidget , & SettingsWidget : : setShowSystemTray , this , & Widget : : onSetShowSystemTray ) ;
2015-03-04 04:29:01 +08:00
connect ( core , SIGNAL ( selfAvatarChanged ( QPixmap ) ) , profileForm , SLOT ( onSelfAvatarLoaded ( QPixmap ) ) ) ;
2014-06-25 04:11:11 +08:00
connect ( ui - > addButton , SIGNAL ( clicked ( ) ) , this , SLOT ( onAddClicked ( ) ) ) ;
connect ( ui - > groupButton , SIGNAL ( clicked ( ) ) , this , SLOT ( onGroupClicked ( ) ) ) ;
connect ( ui - > transferButton , SIGNAL ( clicked ( ) ) , this , SLOT ( onTransferClicked ( ) ) ) ;
connect ( ui - > settingsButton , SIGNAL ( clicked ( ) ) , this , SLOT ( onSettingsClicked ( ) ) ) ;
2015-03-11 10:01:13 +08:00
connect ( profilePicture , & MaskablePixmapWidget : : clicked , this , & Widget : : showProfile ) ;
connect ( ui - > nameLabel , & CroppingLabel : : clicked , this , & Widget : : showProfile ) ;
2014-10-18 22:54:52 +08:00
connect ( ui - > statusLabel , SIGNAL ( textChanged ( QString , QString ) ) , this , SLOT ( onStatusMessageChanged ( QString , QString ) ) ) ;
2014-11-28 17:16:37 +08:00
connect ( ui - > mainSplitter , & QSplitter : : splitterMoved , this , & Widget : : onSplitterMoved ) ;
2014-10-18 22:54:52 +08:00
connect ( addFriendForm , SIGNAL ( friendRequested ( QString , QString ) ) , this , SIGNAL ( friendRequested ( QString , QString ) ) ) ;
2014-12-12 00:49:11 +08:00
connect ( timer , & QTimer : : timeout , this , & Widget : : onUserAwayCheck ) ;
connect ( timer , & QTimer : : timeout , this , & Widget : : onEventIconTick ) ;
2015-02-20 18:56:20 +08:00
connect ( timer , & QTimer : : timeout , this , & Widget : : onTryCreateTrayIcon ) ;
2015-02-13 13:27:49 +08:00
connect ( offlineMsgTimer , & QTimer : : timeout , this , & Widget : : processOfflineMsgs ) ;
2014-06-25 04:11:11 +08:00
2014-10-18 22:54:52 +08:00
addFriendForm - > show ( * ui ) ;
2014-11-10 07:31:29 +08:00
# if (AUTOUPDATE_ENABLED)
if ( Settings : : getInstance ( ) . getCheckUpdates ( ) )
AutoUpdater : : checkUpdatesAsyncInteractive ( ) ;
# endif
2015-02-20 18:56:20 +08:00
if ( ! Settings : : getInstance ( ) . getShowSystemTray ( ) )
show ( ) ;
2014-10-18 22:54:52 +08:00
}
void Widget : : setTranslation ( )
{
// Load translations
QCoreApplication : : removeTranslator ( translator ) ;
QString locale ;
if ( ( locale = Settings : : getInstance ( ) . getTranslation ( ) ) . isEmpty ( ) )
locale = QLocale : : system ( ) . name ( ) . section ( ' _ ' , 0 , 0 ) ;
2014-11-02 21:24:06 +08:00
if ( locale = = " en " )
return ;
2014-10-18 22:54:52 +08:00
if ( translator - > load ( locale , " :translations/ " ) )
qDebug ( ) < < " Loaded translation " < < locale ;
else
qDebug ( ) < < " Error loading translation " < < locale ;
QCoreApplication : : installTranslator ( translator ) ;
2014-06-25 04:11:11 +08:00
}
2014-11-27 01:58:30 +08:00
void Widget : : updateTrayIcon ( )
{
2015-03-11 19:01:10 +08:00
if ( ! icon )
return ;
2014-12-12 00:49:11 +08:00
QString status ;
if ( eventIcon )
status = " event " ;
2014-11-27 01:58:30 +08:00
else
2014-12-12 00:49:11 +08:00
{
status = ui - > statusButton - > property ( " status " ) . toString ( ) ;
if ( ! status . length ( ) )
status = " offline " ;
}
2015-03-11 19:01:10 +08:00
QIcon ico = QIcon : : fromTheme ( " qtox- " + status ) ;
if ( ico . isNull ( ) )
{
QString color = Settings : : getInstance ( ) . getLightTrayIcon ( ) ? " light " : " dark " ;
ico = QIcon ( " :img/taskbar/ " + color + " /taskbar_ " + status + " .svg " ) ;
}
icon - > setIcon ( ico ) ;
2014-11-27 01:58:30 +08:00
}
2014-06-25 04:11:11 +08:00
Widget : : ~ Widget ( )
{
2015-02-07 02:01:31 +08:00
qDebug ( ) < < " Widget: Deleting Widget " ;
2015-01-05 16:54:03 +08:00
AutoUpdater : : abortUpdates ( ) ;
2015-02-20 18:56:20 +08:00
if ( icon )
icon - > hide ( ) ;
2015-01-24 22:31:11 +08:00
hideMainForms ( ) ;
2015-03-04 04:29:01 +08:00
delete profileForm ;
2014-09-30 17:44:27 +08:00
delete settingsWidget ;
2014-10-18 22:54:52 +08:00
delete addFriendForm ;
delete filesForm ;
2014-12-12 00:49:11 +08:00
delete timer ;
2015-02-08 00:18:25 +08:00
delete offlineMsgTimer ;
2014-06-25 04:11:11 +08:00
2014-11-07 22:55:32 +08:00
FriendList : : clear ( ) ;
2014-11-20 17:13:13 +08:00
GroupList : : clear ( ) ;
2014-10-21 02:03:44 +08:00
delete trayMenu ;
2014-06-25 04:11:11 +08:00
delete ui ;
2014-10-28 06:56:21 +08:00
delete translator ;
2014-09-30 17:44:27 +08:00
instance = nullptr ;
2014-06-25 04:11:11 +08:00
}
Widget * Widget : : getInstance ( )
{
2015-02-07 02:51:03 +08:00
assert ( IS_ON_DESKTOP_GUI ) ; // Widget must only be used on Desktop platforms
2014-06-25 04:11:11 +08:00
if ( ! instance )
instance = new Widget ( ) ;
return instance ;
}
2014-08-11 16:00:08 +08:00
void Widget : : closeEvent ( QCloseEvent * event )
2014-07-03 14:43:23 +08:00
{
2014-12-12 02:05:52 +08:00
if ( Settings : : getInstance ( ) . getShowSystemTray ( ) & & Settings : : getInstance ( ) . getCloseToTray ( ) = = true )
2014-10-20 03:47:06 +08:00
{
event - > ignore ( ) ;
this - > hide ( ) ;
}
else
{
2014-11-28 17:16:37 +08:00
saveWindowGeometry ( ) ;
saveSplitterGeometry ( ) ;
2015-02-01 07:03:42 +08:00
qApp - > exit ( 0 ) ;
2014-10-20 03:47:06 +08:00
QWidget : : closeEvent ( event ) ;
}
2014-07-03 14:43:23 +08:00
}
2014-07-01 10:12:17 +08:00
2014-10-20 19:50:12 +08:00
void Widget : : changeEvent ( QEvent * event )
{
if ( event - > type ( ) = = QEvent : : WindowStateChange )
{
2014-12-12 02:05:52 +08:00
if ( isMinimized ( ) & & Settings : : getInstance ( ) . getMinimizeToTray ( ) )
2014-10-20 19:50:12 +08:00
{
this - > hide ( ) ;
}
}
2014-07-03 14:43:23 +08:00
}
2014-07-01 10:12:17 +08:00
2014-11-28 17:16:37 +08:00
void Widget : : resizeEvent ( QResizeEvent * event )
{
Q_UNUSED ( event ) ;
saveWindowGeometry ( ) ;
2015-01-26 01:43:30 +08:00
emit resized ( ) ;
2014-11-28 17:16:37 +08:00
}
2014-06-25 04:11:11 +08:00
QString Widget : : getUsername ( )
{
2015-02-06 19:28:49 +08:00
return Nexus : : getCore ( ) - > getUsername ( ) ;
2014-06-25 04:11:11 +08:00
}
2014-09-24 22:51:16 +08:00
void Widget : : onSelfAvatarLoaded ( const QPixmap & pic )
{
2014-09-26 22:39:29 +08:00
profilePicture - > setPixmap ( pic ) ;
2014-09-24 22:51:16 +08:00
}
2014-06-25 04:11:11 +08:00
void Widget : : onConnected ( )
{
2014-09-03 06:01:04 +08:00
ui - > statusButton - > setEnabled ( true ) ;
2014-11-18 09:40:36 +08:00
if ( beforeDisconnect = = Status : : Offline )
emit statusSet ( Status : : Online ) ;
else
emit statusSet ( beforeDisconnect ) ;
2014-06-25 04:11:11 +08:00
}
void Widget : : onDisconnected ( )
{
2014-11-18 09:40:36 +08:00
QString stat = ui - > statusButton - > property ( " status " ) . toString ( ) ;
if ( stat = = " online " )
beforeDisconnect = Status : : Online ;
else if ( stat = = " busy " )
beforeDisconnect = Status : : Busy ;
else if ( stat = = " away " )
beforeDisconnect = Status : : Away ;
else
beforeDisconnect = Status : : Offline ;
2014-09-03 06:01:04 +08:00
ui - > statusButton - > setEnabled ( false ) ;
2014-06-25 04:11:11 +08:00
emit statusSet ( Status : : Offline ) ;
}
void Widget : : onFailedToStartCore ( )
{
QMessageBox critical ( this ) ;
2014-10-06 04:49:44 +08:00
critical . setText ( tr ( " Toxcore failed to start, the application will terminate after you close this message. " ) ) ;
2014-06-25 04:11:11 +08:00
critical . setIcon ( QMessageBox : : Critical ) ;
critical . exec ( ) ;
qApp - > quit ( ) ;
}
2014-10-06 04:49:44 +08:00
void Widget : : onBadProxyCore ( )
{
QMessageBox critical ( this ) ;
critical . setText ( tr ( " toxcore failed to start with your proxy settings. qTox cannot run; please modify your "
" settings and restart. " , " popup text " ) ) ;
critical . setIcon ( QMessageBox : : Critical ) ;
critical . exec ( ) ;
onSettingsClicked ( ) ;
}
2014-06-25 04:11:11 +08:00
void Widget : : onStatusSet ( Status status )
{
2014-07-06 06:03:53 +08:00
//We have to use stylesheets here, there's no way to
//prevent the button icon from moving when pressed otherwise
2014-10-04 16:24:20 +08:00
switch ( status )
2014-07-06 06:03:53 +08:00
{
2014-10-04 16:24:20 +08:00
case Status : : Online :
ui - > statusButton - > setProperty ( " status " , " online " ) ;
2015-03-07 01:00:54 +08:00
ui - > statusButton - > setIcon ( QIcon ( " :img/status/dot_online_2x.png " ) ) ;
2014-10-04 16:24:20 +08:00
break ;
case Status : : Away :
ui - > statusButton - > setProperty ( " status " , " away " ) ;
2015-03-07 01:00:54 +08:00
ui - > statusButton - > setIcon ( QIcon ( " :img/status/dot_idle_2x.png " ) ) ;
2014-10-04 16:24:20 +08:00
break ;
case Status : : Busy :
ui - > statusButton - > setProperty ( " status " , " busy " ) ;
2015-03-07 01:00:54 +08:00
ui - > statusButton - > setIcon ( QIcon ( " :img/status/dot_busy_2x.png " ) ) ;
2014-10-04 16:24:20 +08:00
break ;
case Status : : Offline :
ui - > statusButton - > setProperty ( " status " , " offline " ) ;
2015-03-07 01:00:54 +08:00
ui - > statusButton - > setIcon ( QIcon ( " :img/status/dot_away_2x.png " ) ) ;
2014-10-04 16:24:20 +08:00
break ;
2014-07-06 06:03:53 +08:00
}
2014-11-27 01:58:30 +08:00
updateTrayIcon ( ) ;
2014-06-25 04:11:11 +08:00
}
2014-11-15 08:28:44 +08:00
void Widget : : setWindowTitle ( const QString & title )
{
2015-02-27 05:08:32 +08:00
QString tmp = title ;
2015-02-27 05:10:35 +08:00
/// <[^>]*> Regexp to remove HTML tags, in case someone used them in title
2015-02-27 05:08:32 +08:00
QMainWindow : : setWindowTitle ( " qTox - " + tmp . remove ( QRegExp ( " <[^>]*> " ) ) ) ;
2014-11-15 08:28:44 +08:00
}
2015-01-26 18:43:34 +08:00
void Widget : : forceShow ( )
{
hide ( ) ; // Workaround to force minimized window to be restored
show ( ) ;
activateWindow ( ) ;
}
2014-06-25 04:11:11 +08:00
void Widget : : onAddClicked ( )
{
hideMainForms ( ) ;
2014-10-18 22:54:52 +08:00
addFriendForm - > show ( * ui ) ;
2014-11-15 08:28:44 +08:00
setWindowTitle ( tr ( " Add friend " ) ) ;
2014-06-25 04:11:11 +08:00
}
void Widget : : onGroupClicked ( )
{
2015-02-06 19:28:49 +08:00
Nexus : : getCore ( ) - > createGroup ( ) ;
2014-06-25 04:11:11 +08:00
}
void Widget : : onTransferClicked ( )
{
2014-07-12 00:05:18 +08:00
hideMainForms ( ) ;
2014-10-18 22:54:52 +08:00
filesForm - > show ( * ui ) ;
2014-11-15 08:28:44 +08:00
setWindowTitle ( tr ( " File transfers " ) ) ;
2014-09-02 00:20:28 +08:00
activeChatroomWidget = nullptr ;
2014-06-25 04:11:11 +08:00
}
2015-02-22 20:21:42 +08:00
void Widget : : confirmExecutableOpen ( const QFileInfo file )
2015-02-20 03:14:19 +08:00
{
2015-02-22 20:21:42 +08:00
static const QStringList dangerousExtensions = { " app " , " bat " , " com " , " cpl " , " dmg " , " exe " , " hta " , " jar " , " js " , " jse " , " lnk " , " msc " , " msh " , " msh1 " , " msh1xml " , " msh2 " , " msh2xml " , " mshxml " , " msi " , " msp " , " pif " , " ps1 " , " ps1xml " , " ps2 " , " ps2xml " , " psc1 " , " psc2 " , " py " , " reg " , " scf " , " sh " , " src " , " vb " , " vbe " , " vbs " , " ws " , " wsc " , " wsf " , " wsh " } ;
if ( dangerousExtensions . contains ( file . suffix ( ) ) )
2015-02-20 03:14:19 +08:00
{
2015-02-20 23:38:09 +08:00
if ( ! GUI : : askQuestion ( tr ( " Executable file " , " popup title " ) , tr ( " You have asked qTox to open an executable file. Executable files can potentially damage your computer. Are you sure want to open this file? " , " popup text " ) , false , true ) )
2015-02-20 03:14:19 +08:00
{
2015-02-22 20:21:42 +08:00
return ;
2015-02-20 03:14:19 +08:00
}
2015-02-22 20:21:42 +08:00
// The user wants to run this file, so make it executable and run it
QFile ( file . filePath ( ) ) . setPermissions ( file . permissions ( ) | QFile : : ExeOwner | QFile : : ExeUser | QFile : : ExeGroup | QFile : : ExeOther ) ;
QProcess : : startDetached ( file . filePath ( ) ) ;
}
else
{
QDesktopServices : : openUrl ( QUrl ( " file:// " + file . filePath ( ) , QUrl : : TolerantMode ) ) ;
2015-02-20 03:14:19 +08:00
}
}
2014-10-21 02:03:44 +08:00
void Widget : : onIconClick ( QSystemTrayIcon : : ActivationReason reason )
2014-10-08 22:17:05 +08:00
{
2015-01-26 18:43:34 +08:00
switch ( reason )
{
2014-10-21 02:03:44 +08:00
case QSystemTrayIcon : : Trigger :
2014-11-26 01:11:05 +08:00
{
2015-01-26 18:43:34 +08:00
if ( isHidden ( ) )
{
show ( ) ;
activateWindow ( ) ;
}
2015-01-30 07:40:20 +08:00
else if ( isMinimized ( ) )
{
2015-01-26 18:43:34 +08:00
forceShow ( ) ;
2015-01-30 07:40:20 +08:00
}
2015-01-26 18:43:34 +08:00
else
2015-01-30 07:40:20 +08:00
{
2015-01-26 18:43:34 +08:00
hide ( ) ;
2015-01-30 07:40:20 +08:00
}
2015-01-26 18:43:34 +08:00
break ;
2014-11-26 01:11:05 +08:00
}
2015-01-26 18:43:34 +08:00
case QSystemTrayIcon : : DoubleClick :
forceShow ( ) ;
2014-10-21 02:03:44 +08:00
break ;
case QSystemTrayIcon : : MiddleClick :
2015-01-26 18:43:34 +08:00
hide ( ) ;
2014-10-21 02:03:44 +08:00
break ;
2015-01-30 00:33:17 +08:00
case QSystemTrayIcon : : Unknown :
if ( isHidden ( ) )
forceShow ( ) ;
break ;
2014-10-21 02:03:44 +08:00
default :
2015-01-26 18:43:34 +08:00
break ;
2014-10-21 02:03:44 +08:00
}
2014-10-08 22:17:05 +08:00
}
2014-06-25 04:11:11 +08:00
void Widget : : onSettingsClicked ( )
{
hideMainForms ( ) ;
2014-09-30 17:44:27 +08:00
settingsWidget - > show ( * ui ) ;
2014-11-15 08:28:44 +08:00
setWindowTitle ( tr ( " Settings " ) ) ;
2014-09-02 00:20:28 +08:00
activeChatroomWidget = nullptr ;
2014-06-25 04:11:11 +08:00
}
2015-03-11 10:01:13 +08:00
void Widget : : showProfile ( ) // onAvatarClicked, onUsernameClicked
{
hideMainForms ( ) ;
profileForm - > show ( * ui ) ;
setWindowTitle ( tr ( " Profile " ) ) ;
activeChatroomWidget = nullptr ;
}
2014-06-25 04:11:11 +08:00
void Widget : : hideMainForms ( )
{
QLayoutItem * item ;
while ( ( item = ui - > mainHead - > layout ( ) - > takeAt ( 0 ) ) ! = 0 )
item - > widget ( ) - > hide ( ) ;
while ( ( item = ui - > mainContent - > layout ( ) - > takeAt ( 0 ) ) ! = 0 )
item - > widget ( ) - > hide ( ) ;
2014-10-04 16:54:50 +08:00
2014-09-02 00:20:28 +08:00
if ( activeChatroomWidget ! = nullptr )
2014-06-27 09:47:16 +08:00
{
2014-09-02 00:20:28 +08:00
activeChatroomWidget - > setAsInactiveChatroom ( ) ;
2014-06-27 09:47:16 +08:00
}
2014-06-25 04:11:11 +08:00
}
void Widget : : onUsernameChanged ( const QString & newUsername , const QString & oldUsername )
{
2015-01-21 19:10:41 +08:00
setUsername ( oldUsername ) ; // restore old username until Core tells us to set it
2015-02-06 19:28:49 +08:00
Nexus : : getCore ( ) - > setUsername ( newUsername ) ;
2014-06-25 04:11:11 +08:00
}
void Widget : : setUsername ( const QString & username )
{
ui - > nameLabel - > setText ( username ) ;
2015-01-21 19:10:41 +08:00
ui - > nameLabel - > setToolTip ( username ) ; // for overlength names
2015-01-23 01:43:44 +08:00
QString sanename = username ;
sanename . remove ( QRegExp ( " [ \\ t \\ n \\ v \\ f \\ r \\ x0000] " ) ) ;
nameMention = QRegExp ( " \\ b " + QRegExp : : escape ( username ) + " \\ b " , Qt : : CaseInsensitive ) ;
sanitizedNameMention = QRegExp ( " \\ b " + QRegExp : : escape ( sanename ) + " \\ b " , Qt : : CaseInsensitive ) ;
2014-06-25 04:11:11 +08:00
}
void Widget : : onStatusMessageChanged ( const QString & newStatusMessage , const QString & oldStatusMessage )
{
ui - > statusLabel - > setText ( oldStatusMessage ) ; // restore old status message until Core tells us to set it
2014-07-16 00:04:26 +08:00
ui - > statusLabel - > setToolTip ( oldStatusMessage ) ; // for overlength messsages
2015-02-06 19:28:49 +08:00
Nexus : : getCore ( ) - > setStatusMessage ( newStatusMessage ) ;
2014-06-25 04:11:11 +08:00
}
void Widget : : setStatusMessage ( const QString & statusMessage )
{
ui - > statusLabel - > setText ( statusMessage ) ;
2014-07-16 00:04:26 +08:00
ui - > statusLabel - > setToolTip ( statusMessage ) ; // for overlength messsages
2014-06-25 04:11:11 +08:00
}
2015-02-03 07:56:51 +08:00
void Widget : : reloadHistory ( )
{
for ( auto f : FriendList : : getAllFriends ( ) )
f - > getChatForm ( ) - > loadHistory ( QDateTime : : currentDateTime ( ) . addDays ( - 7 ) , true ) ;
}
2014-06-25 04:11:11 +08:00
void Widget : : addFriend ( int friendId , const QString & userId )
{
2014-11-01 13:30:04 +08:00
//qDebug() << "Widget: Adding friend with id" << userId;
2014-11-16 22:48:18 +08:00
ToxID userToxId = ToxID : : fromString ( userId ) ;
Friend * newfriend = FriendList : : addFriend ( friendId , userToxId ) ;
2015-03-12 08:23:22 +08:00
contactListWidget - > moveWidget ( newfriend - > getFriendWidget ( ) , Status : : Offline , 0 ) ;
2014-11-07 22:55:32 +08:00
2015-02-06 19:28:49 +08:00
Core * core = Nexus : : getCore ( ) ;
2015-03-12 08:23:22 +08:00
connect ( newfriend , & Friend : : displayedNameChanged , contactListWidget , & FriendListWidget : : moveWidget ) ;
2015-01-26 21:09:19 +08:00
connect ( settingsWidget , & SettingsWidget : : compactToggled , newfriend - > getFriendWidget ( ) , & GenericChatroomWidget : : onCompactChanged ) ;
2014-11-06 23:26:22 +08:00
connect ( newfriend - > getFriendWidget ( ) , SIGNAL ( chatroomWidgetClicked ( GenericChatroomWidget * ) ) , this , SLOT ( onChatroomWidgetClicked ( GenericChatroomWidget * ) ) ) ;
connect ( newfriend - > getFriendWidget ( ) , SIGNAL ( removeFriend ( int ) ) , this , SLOT ( removeFriend ( int ) ) ) ;
connect ( newfriend - > getFriendWidget ( ) , SIGNAL ( copyFriendIdToClipboard ( int ) ) , this , SLOT ( copyFriendIdToClipboard ( int ) ) ) ;
connect ( newfriend - > getFriendWidget ( ) , SIGNAL ( chatroomWidgetClicked ( GenericChatroomWidget * ) ) , newfriend - > getChatForm ( ) , SLOT ( focusInput ( ) ) ) ;
connect ( newfriend - > getChatForm ( ) , SIGNAL ( sendMessage ( int , QString ) ) , core , SLOT ( sendMessage ( int , QString ) ) ) ;
connect ( newfriend - > getChatForm ( ) , & GenericChatForm : : sendAction , core , & Core : : sendAction ) ;
connect ( newfriend - > getChatForm ( ) , SIGNAL ( sendFile ( int32_t , QString , QString , long long ) ) , core , SLOT ( sendFile ( int32_t , QString , QString , long long ) ) ) ;
connect ( newfriend - > getChatForm ( ) , SIGNAL ( answerCall ( int ) ) , core , SLOT ( answerCall ( int ) ) ) ;
connect ( newfriend - > getChatForm ( ) , SIGNAL ( hangupCall ( int ) ) , core , SLOT ( hangupCall ( int ) ) ) ;
2015-01-25 11:57:20 +08:00
connect ( newfriend - > getChatForm ( ) , SIGNAL ( rejectCall ( int ) ) , core , SLOT ( rejectCall ( int ) ) ) ;
2014-11-06 23:26:22 +08:00
connect ( newfriend - > getChatForm ( ) , SIGNAL ( startCall ( int ) ) , core , SLOT ( startCall ( int ) ) ) ;
connect ( newfriend - > getChatForm ( ) , SIGNAL ( startVideoCall ( int , bool ) ) , core , SLOT ( startCall ( int , bool ) ) ) ;
connect ( newfriend - > getChatForm ( ) , SIGNAL ( cancelCall ( int , int ) ) , core , SLOT ( cancelCall ( int , int ) ) ) ;
connect ( newfriend - > getChatForm ( ) , SIGNAL ( micMuteToggle ( int ) ) , core , SLOT ( micMuteToggle ( int ) ) ) ;
connect ( newfriend - > getChatForm ( ) , SIGNAL ( volMuteToggle ( int ) ) , core , SLOT ( volMuteToggle ( int ) ) ) ;
2014-11-18 10:15:44 +08:00
connect ( newfriend - > getChatForm ( ) , & ChatForm : : aliasChanged , newfriend - > getFriendWidget ( ) , & FriendWidget : : setAlias ) ;
2014-11-06 23:26:22 +08:00
connect ( core , & Core : : fileReceiveRequested , newfriend - > getChatForm ( ) , & ChatForm : : onFileRecvRequest ) ;
connect ( core , & Core : : avInvite , newfriend - > getChatForm ( ) , & ChatForm : : onAvInvite ) ;
connect ( core , & Core : : avStart , newfriend - > getChatForm ( ) , & ChatForm : : onAvStart ) ;
connect ( core , & Core : : avCancel , newfriend - > getChatForm ( ) , & ChatForm : : onAvCancel ) ;
connect ( core , & Core : : avEnd , newfriend - > getChatForm ( ) , & ChatForm : : onAvEnd ) ;
connect ( core , & Core : : avRinging , newfriend - > getChatForm ( ) , & ChatForm : : onAvRinging ) ;
connect ( core , & Core : : avStarting , newfriend - > getChatForm ( ) , & ChatForm : : onAvStarting ) ;
connect ( core , & Core : : avEnding , newfriend - > getChatForm ( ) , & ChatForm : : onAvEnding ) ;
connect ( core , & Core : : avRequestTimeout , newfriend - > getChatForm ( ) , & ChatForm : : onAvRequestTimeout ) ;
connect ( core , & Core : : avPeerTimeout , newfriend - > getChatForm ( ) , & ChatForm : : onAvPeerTimeout ) ;
connect ( core , & Core : : avMediaChange , newfriend - > getChatForm ( ) , & ChatForm : : onAvMediaChange ) ;
connect ( core , & Core : : avCallFailed , newfriend - > getChatForm ( ) , & ChatForm : : onAvCallFailed ) ;
connect ( core , & Core : : avRejected , newfriend - > getChatForm ( ) , & ChatForm : : onAvRejected ) ;
connect ( core , & Core : : friendAvatarChanged , newfriend - > getChatForm ( ) , & ChatForm : : onAvatarChange ) ;
connect ( core , & Core : : friendAvatarChanged , newfriend - > getFriendWidget ( ) , & FriendWidget : : onAvatarChange ) ;
connect ( core , & Core : : friendAvatarRemoved , newfriend - > getChatForm ( ) , & ChatForm : : onAvatarRemoved ) ;
connect ( core , & Core : : friendAvatarRemoved , newfriend - > getFriendWidget ( ) , & FriendWidget : : onAvatarRemoved ) ;
2014-09-24 23:55:54 +08:00
// Try to get the avatar from the cache
2014-09-28 06:19:30 +08:00
QPixmap avatar = Settings : : getInstance ( ) . getSavedAvatar ( userId ) ;
2014-09-24 23:55:54 +08:00
if ( ! avatar . isNull ( ) )
{
2014-11-01 13:30:04 +08:00
//qWarning() << "Widget: loadded avatar for id" << userId;
2014-11-06 23:26:22 +08:00
newfriend - > getChatForm ( ) - > onAvatarChange ( friendId , avatar ) ;
newfriend - > getFriendWidget ( ) - > onAvatarChange ( friendId , avatar ) ;
2014-09-24 23:55:54 +08:00
}
2014-06-27 01:45:47 +08:00
}
2014-11-10 03:23:43 +08:00
void Widget : : addFriendFailed ( const QString & , const QString & errorInfo )
2014-06-27 01:45:47 +08:00
{
2014-11-10 08:04:35 +08:00
QString info = QString ( tr ( " Couldn't request friendship " ) ) ;
2014-12-12 02:05:52 +08:00
if ( ! errorInfo . isEmpty ( ) ) {
2014-11-10 03:23:43 +08:00
info = info + ( QString ( " : " ) + errorInfo ) ;
}
QMessageBox : : critical ( 0 , " Error " , info ) ;
2014-06-25 04:11:11 +08:00
}
void Widget : : onFriendStatusChanged ( int friendId , Status status )
{
Friend * f = FriendList : : findFriend ( friendId ) ;
if ( ! f )
return ;
2015-01-02 08:57:31 +08:00
contactListWidget - > moveWidget ( f - > getFriendWidget ( ) , status , f - > getEventFlag ( ) ) ;
2014-08-22 23:19:16 +08:00
2014-11-09 09:01:02 +08:00
bool isActualChange = f - > getStatus ( ) ! = status ;
2014-11-06 23:26:22 +08:00
f - > setStatus ( status ) ;
f - > getFriendWidget ( ) - > updateStatusLight ( ) ;
2014-10-11 07:18:32 +08:00
2014-10-18 07:06:30 +08:00
//won't print the message if there were no messages before
2014-12-12 02:05:52 +08:00
if ( ! f - > getChatForm ( ) - > isEmpty ( )
2014-11-10 16:09:20 +08:00
& & Settings : : getInstance ( ) . getStatusChangeNotificationEnabled ( ) )
2014-10-18 07:06:30 +08:00
{
QString fStatus = " " ;
2014-11-06 23:26:22 +08:00
switch ( f - > getStatus ( ) ) {
2014-10-18 07:06:30 +08:00
case Status : : Away :
fStatus = tr ( " away " , " contact status " ) ; break ;
case Status : : Busy :
fStatus = tr ( " busy " , " contact status " ) ; break ;
case Status : : Offline :
2015-02-18 21:02:10 +08:00
fStatus = tr ( " offline " , " contact status " ) ;
f - > getChatForm ( ) - > setFriendTyping ( false ) ; // Hide the "is typing" message when a friend goes offline
break ;
2014-10-18 07:06:30 +08:00
default :
fStatus = tr ( " online " , " contact status " ) ; break ;
}
2014-11-09 09:01:02 +08:00
if ( isActualChange )
f - > getChatForm ( ) - > addSystemInfoMessage ( tr ( " %1 is now %2 " , " e.g. \" Dubslow is now online \" " ) . arg ( f - > getDisplayedName ( ) ) . arg ( fStatus ) ,
2015-01-05 01:21:35 +08:00
ChatMessage : : INFO , QDateTime : : currentDateTime ( ) ) ;
2014-10-18 07:06:30 +08:00
}
2014-11-10 19:30:56 +08:00
if ( isActualChange & & status ! = Status : : Offline )
{ // wait a little
2015-02-08 00:18:25 +08:00
QTimer : : singleShot ( 250 , f - > getChatForm ( ) - > getOfflineMsgEngine ( ) , SLOT ( deliverOfflineMsgs ( ) ) ) ;
2014-11-10 19:30:56 +08:00
}
2014-06-25 04:11:11 +08:00
}
void Widget : : onFriendStatusMessageChanged ( int friendId , const QString & message )
{
Friend * f = FriendList : : findFriend ( friendId ) ;
if ( ! f )
return ;
2014-09-29 02:09:10 +08:00
QString str = message ; str . replace ( ' \n ' , ' ' ) ;
str . remove ( ' \r ' ) ; str . remove ( QChar ( ( char ) 0 ) ) ; // null terminator...
f - > setStatusMessage ( str ) ;
2014-06-25 04:11:11 +08:00
}
void Widget : : onFriendUsernameChanged ( int friendId , const QString & username )
{
Friend * f = FriendList : : findFriend ( friendId ) ;
if ( ! f )
return ;
2014-09-29 02:09:10 +08:00
QString str = username ; str . replace ( ' \n ' , ' ' ) ;
str . remove ( ' \r ' ) ; str . remove ( QChar ( ( char ) 0 ) ) ; // null terminator...
f - > setName ( str ) ;
2014-06-25 04:11:11 +08:00
}
2014-09-02 00:20:28 +08:00
void Widget : : onChatroomWidgetClicked ( GenericChatroomWidget * widget )
2014-06-25 04:11:11 +08:00
{
2015-02-28 01:56:47 +08:00
qDebug ( ) < < " active chat " ;
2014-06-25 04:11:11 +08:00
hideMainForms ( ) ;
2014-09-02 00:20:28 +08:00
widget - > setChatForm ( * ui ) ;
if ( activeChatroomWidget ! = nullptr )
2014-06-27 09:47:16 +08:00
{
2014-09-02 00:20:28 +08:00
activeChatroomWidget - > setAsInactiveChatroom ( ) ;
2014-06-27 09:47:16 +08:00
}
2014-09-02 00:20:28 +08:00
activeChatroomWidget = widget ;
2014-06-27 09:47:16 +08:00
widget - > setAsActiveChatroom ( ) ;
2014-11-15 08:28:44 +08:00
setWindowTitle ( widget - > getName ( ) ) ;
2014-09-02 00:20:28 +08:00
widget - > resetEventFlags ( ) ;
widget - > updateStatusLight ( ) ;
2014-06-25 04:11:11 +08:00
}
2014-10-02 14:01:23 +08:00
void Widget : : onFriendMessageReceived ( int friendId , const QString & message , bool isAction )
2014-06-25 04:11:11 +08:00
{
Friend * f = FriendList : : findFriend ( friendId ) ;
if ( ! f )
return ;
2014-10-14 13:49:27 +08:00
QDateTime timestamp = QDateTime : : currentDateTime ( ) ;
2014-11-10 01:02:43 +08:00
f - > getChatForm ( ) - > addMessage ( f - > getToxID ( ) , message , isAction , timestamp , true ) ;
2014-10-14 22:36:17 +08:00
2015-01-21 19:10:41 +08:00
HistoryKeeper : : getInstance ( ) - > addChatEntry ( f - > getToxID ( ) . publicKey , isAction ? " /me " + message : message ,
f - > getToxID ( ) . publicKey , timestamp , true ) ;
2014-06-28 00:12:43 +08:00
2015-01-21 19:10:41 +08:00
f - > setEventFlag ( static_cast < GenericChatroomWidget * > ( f - > getFriendWidget ( ) ) ! = activeChatroomWidget ) ;
newMessageAlert ( f - > getFriendWidget ( ) ) ;
2014-11-06 23:26:22 +08:00
f - > getFriendWidget ( ) - > updateStatusLight ( ) ;
2014-06-25 04:11:11 +08:00
}
2014-11-01 22:19:11 +08:00
void Widget : : onReceiptRecieved ( int friendId , int receipt )
{
Friend * f = FriendList : : findFriend ( friendId ) ;
if ( ! f )
return ;
2015-02-08 00:18:25 +08:00
f - > getChatForm ( ) - > getOfflineMsgEngine ( ) - > dischargeReceipt ( receipt ) ;
2014-11-01 22:19:11 +08:00
}
2014-11-10 16:09:20 +08:00
void Widget : : newMessageAlert ( GenericChatroomWidget * chat )
2014-06-28 05:36:44 +08:00
{
2015-01-21 19:10:41 +08:00
bool inactiveWindow = isMinimized ( ) | | ! isActiveWindow ( ) ;
if ( ! inactiveWindow & & activeChatroomWidget ! = nullptr & & chat = = activeChatroomWidget )
return ;
2014-07-01 10:25:00 +08:00
QApplication : : alert ( this ) ;
2014-08-30 21:15:23 +08:00
2014-12-12 00:49:11 +08:00
if ( inactiveWindow )
eventFlag = true ;
2015-01-21 19:10:41 +08:00
if ( Settings : : getInstance ( ) . getShowWindow ( ) )
2014-11-10 08:23:41 +08:00
{
2015-01-21 19:10:41 +08:00
show ( ) ;
if ( inactiveWindow & & Settings : : getInstance ( ) . getShowInFront ( ) )
setWindowState ( Qt : : WindowActive ) ;
2014-11-10 08:23:41 +08:00
}
2015-01-21 19:10:41 +08:00
static QFile sndFile ( " :audio/notification.pcm " ) ;
2014-08-30 21:15:23 +08:00
static QByteArray sndData ;
2015-01-21 19:10:41 +08:00
2014-08-30 21:15:23 +08:00
if ( sndData . isEmpty ( ) )
{
sndFile . open ( QIODevice : : ReadOnly ) ;
sndData = sndFile . readAll ( ) ;
sndFile . close ( ) ;
}
2014-11-17 02:04:45 +08:00
Audio : : playMono16Sound ( sndData ) ;
2014-06-28 05:36:44 +08:00
}
2014-10-08 10:20:38 +08:00
void Widget : : playRingtone ( )
{
QApplication : : alert ( this ) ;
static QFile sndFile1 ( " :audio/ToxicIncomingCall.pcm " ) ; // for whatever reason this plays slower/downshifted from what any other program plays the file as... but whatever
static QByteArray sndData1 ;
if ( sndData1 . isEmpty ( ) )
{
sndFile1 . open ( QIODevice : : ReadOnly ) ;
sndData1 = sndFile1 . readAll ( ) ;
sndFile1 . close ( ) ;
}
2014-11-17 02:04:45 +08:00
Audio : : playMono16Sound ( sndData1 ) ;
2014-10-08 10:20:38 +08:00
}
2014-06-25 04:11:11 +08:00
void Widget : : onFriendRequestReceived ( const QString & userId , const QString & message )
{
FriendRequestDialog dialog ( this , userId , message ) ;
if ( dialog . exec ( ) = = QDialog : : Accepted )
emit friendRequestAccepted ( userId ) ;
}
2014-11-12 07:00:24 +08:00
void Widget : : removeFriend ( Friend * f , bool fake )
2014-06-25 04:11:11 +08:00
{
2014-11-06 23:26:22 +08:00
f - > getFriendWidget ( ) - > setAsInactiveChatroom ( ) ;
if ( static_cast < GenericChatroomWidget * > ( f - > getFriendWidget ( ) ) = = activeChatroomWidget )
2014-11-12 06:27:30 +08:00
{
2014-09-02 00:20:28 +08:00
activeChatroomWidget = nullptr ;
2014-11-12 06:27:30 +08:00
onAddClicked ( ) ;
}
2014-11-12 07:00:24 +08:00
FriendList : : removeFriend ( f - > getFriendID ( ) , fake ) ;
2015-02-06 19:28:49 +08:00
Nexus : : getCore ( ) - > removeFriend ( f - > getFriendID ( ) , fake ) ;
2014-06-25 04:11:11 +08:00
delete f ;
2014-11-06 08:22:50 +08:00
if ( ui - > mainHead - > layout ( ) - > isEmpty ( ) )
2014-06-25 04:11:11 +08:00
onAddClicked ( ) ;
2014-11-02 16:45:44 +08:00
contactListWidget - > hide ( ) ;
contactListWidget - > show ( ) ;
2014-06-25 04:11:11 +08:00
}
2014-07-23 17:22:09 +08:00
void Widget : : removeFriend ( int friendId )
{
2014-11-12 07:00:24 +08:00
removeFriend ( FriendList : : findFriend ( friendId ) , false ) ;
2014-07-23 17:22:09 +08:00
}
2014-10-09 16:07:26 +08:00
void Widget : : clearContactsList ( )
{
2014-11-07 22:55:32 +08:00
QList < Friend * > friends = FriendList : : getAllFriends ( ) ;
for ( Friend * f : friends )
2014-11-12 07:00:24 +08:00
removeFriend ( f , true ) ;
2014-11-20 17:13:13 +08:00
QList < Group * > groups = GroupList : : getAllGroups ( ) ;
for ( Group * g : groups )
2014-11-12 07:00:24 +08:00
removeGroup ( g , true ) ;
2014-10-09 16:07:26 +08:00
}
2014-07-02 05:50:07 +08:00
void Widget : : copyFriendIdToClipboard ( int friendId )
{
Friend * f = FriendList : : findFriend ( friendId ) ;
if ( f ! = nullptr )
{
QClipboard * clipboard = QApplication : : clipboard ( ) ;
2015-02-06 19:28:49 +08:00
clipboard - > setText ( Nexus : : getCore ( ) - > getFriendAddress ( f - > getFriendID ( ) ) , QClipboard : : Clipboard ) ;
2014-07-02 05:50:07 +08:00
}
}
2014-11-13 07:13:11 +08:00
void Widget : : onGroupInviteReceived ( int32_t friendId , uint8_t type , QByteArray invite )
2014-06-25 04:11:11 +08:00
{
2014-11-11 23:05:01 +08:00
if ( type = = TOX_GROUPCHAT_TYPE_TEXT | | type = = TOX_GROUPCHAT_TYPE_AV )
2014-06-25 04:11:11 +08:00
{
2015-02-17 06:53:33 +08:00
if ( GUI : : askQuestion ( tr ( " Group invite " , " popup title " ) , tr ( " %1 has invited you to a groupchat. Would you like to join? " , " popup text " ) . arg ( Nexus : : getCore ( ) - > getFriendUsername ( friendId ) ) , true , false ) )
2014-11-11 23:05:01 +08:00
{
2015-02-16 07:24:42 +08:00
int groupId = Nexus : : getCore ( ) - > joinGroupchat ( friendId , type , ( uint8_t * ) invite . data ( ) , invite . length ( ) ) ;
if ( groupId < 0 )
{
qWarning ( ) < < " Widget::onGroupInviteReceived: Unable to accept group invite " ;
return ;
}
2014-11-11 23:05:01 +08:00
}
}
else
{
qWarning ( ) < < " Widget::onGroupInviteReceived: Unknown groupchat type: " < < type ;
2014-06-25 04:11:11 +08:00
return ;
}
}
2014-11-23 23:55:49 +08:00
void Widget : : onGroupMessageReceived ( int groupnumber , int peernumber , const QString & message , bool isAction )
2014-06-25 04:11:11 +08:00
{
Group * g = GroupList : : findGroup ( groupnumber ) ;
if ( ! g )
return ;
2014-11-23 23:55:49 +08:00
ToxID author = Core : : getInstance ( ) - > getGroupPeerToxID ( groupnumber , peernumber ) ;
2015-01-23 01:43:44 +08:00
bool targeted = ! author . isMine ( ) & & ( message . contains ( nameMention ) | | message . contains ( sanitizedNameMention ) ) ;
2014-12-04 01:47:07 +08:00
if ( targeted & & ! isAction )
2014-11-23 23:22:29 +08:00
g - > getChatForm ( ) - > addAlertMessage ( author , message , QDateTime : : currentDateTime ( ) ) ;
2014-10-20 19:05:45 +08:00
else
2014-11-23 23:55:49 +08:00
g - > getChatForm ( ) - > addMessage ( author , message , isAction , QDateTime : : currentDateTime ( ) , true ) ;
2014-06-28 07:10:02 +08:00
2015-01-21 19:10:41 +08:00
g - > setEventFlag ( static_cast < GenericChatroomWidget * > ( g - > getGroupWidget ( ) ) ! = activeChatroomWidget ) ;
if ( targeted | | Settings : : getInstance ( ) . getGroupAlwaysNotify ( ) )
newMessageAlert ( g - > getGroupWidget ( ) ) ;
if ( targeted )
g - > setMentionedFlag ( true ) ; // useful for highlighting line or desktop notifications
g - > getGroupWidget ( ) - > updateStatusLight ( ) ;
2014-06-25 04:11:11 +08:00
}
void Widget : : onGroupNamelistChanged ( int groupnumber , int peernumber , uint8_t Change )
{
Group * g = GroupList : : findGroup ( groupnumber ) ;
if ( ! g )
{
2014-11-14 02:43:32 +08:00
qDebug ( ) < < " Widget::onGroupNamelistChanged: Group " < < groupnumber < < " not found, creating it " ;
2014-06-25 04:11:11 +08:00
g = createGroup ( groupnumber ) ;
}
2015-02-06 19:28:49 +08:00
QString name = Nexus : : getCore ( ) - > getGroupPeerName ( groupnumber , peernumber ) ;
2014-06-25 04:11:11 +08:00
TOX_CHAT_CHANGE change = static_cast < TOX_CHAT_CHANGE > ( Change ) ;
if ( change = = TOX_CHAT_CHANGE_PEER_ADD )
2014-09-12 00:05:02 +08:00
{
if ( name . isEmpty ( ) )
name = tr ( " <Unknown> " , " Placeholder when we don't know someone's name in a group chat " ) ;
2015-01-03 17:17:53 +08:00
2014-11-23 23:22:29 +08:00
// g->addPeer(peernumber,name);
g - > regeneratePeerList ( ) ;
2015-01-03 03:29:39 +08:00
// g->getChatForm()->addSystemInfoMessage(tr("%1 has joined the chat").arg(name), "white", QDateTime::currentDateTime());
2014-10-20 19:34:17 +08:00
// we can't display these messages until irungentoo fixes peernumbers
// https://github.com/irungentoo/toxcore/issues/1128
2014-09-12 00:05:02 +08:00
}
2014-06-25 04:11:11 +08:00
else if ( change = = TOX_CHAT_CHANGE_PEER_DEL )
2014-10-20 19:34:17 +08:00
{
2014-11-23 23:22:29 +08:00
// g->removePeer(peernumber);
g - > regeneratePeerList ( ) ;
2015-01-03 03:29:39 +08:00
// g->getChatForm()->addSystemInfoMessage(tr("%1 has left the chat").arg(name), "white", QDateTime::currentDateTime());
2014-10-20 19:34:17 +08:00
}
else if ( change = = TOX_CHAT_CHANGE_PEER_NAME ) // core overwrites old name before telling us it changed...
2015-02-06 19:28:49 +08:00
g - > updatePeer ( peernumber , Nexus : : getCore ( ) - > getGroupPeerName ( groupnumber , peernumber ) ) ;
2014-06-25 04:11:11 +08:00
}
2014-11-06 08:22:50 +08:00
void Widget : : onGroupTitleChanged ( int groupnumber , const QString & author , const QString & title )
{
Group * g = GroupList : : findGroup ( groupnumber ) ;
if ( ! g )
return ;
g - > setName ( title ) ;
if ( ! author . isEmpty ( ) )
2015-01-05 01:21:35 +08:00
g - > getChatForm ( ) - > addSystemInfoMessage ( tr ( " %1 has set the title to %2 " ) . arg ( author , title ) , ChatMessage : : INFO , QDateTime : : currentDateTime ( ) ) ;
2014-11-06 08:22:50 +08:00
}
2014-11-12 07:00:24 +08:00
void Widget : : removeGroup ( Group * g , bool fake )
2014-06-25 04:11:11 +08:00
{
2014-11-23 23:22:29 +08:00
g - > getGroupWidget ( ) - > setAsInactiveChatroom ( ) ;
if ( static_cast < GenericChatroomWidget * > ( g - > getGroupWidget ( ) ) = = activeChatroomWidget )
2014-10-30 17:44:26 +08:00
{
2014-09-02 00:20:28 +08:00
activeChatroomWidget = nullptr ;
2014-10-30 17:44:26 +08:00
onAddClicked ( ) ;
}
2014-11-23 23:22:29 +08:00
GroupList : : removeGroup ( g - > getGroupId ( ) , fake ) ;
2015-02-06 19:28:49 +08:00
Nexus : : getCore ( ) - > removeGroup ( g - > getGroupId ( ) , fake ) ;
2014-06-25 04:11:11 +08:00
delete g ;
if ( ui - > mainHead - > layout ( ) - > isEmpty ( ) )
onAddClicked ( ) ;
2014-11-02 16:45:44 +08:00
contactListWidget - > hide ( ) ;
contactListWidget - > show ( ) ;
2014-06-25 04:11:11 +08:00
}
2014-10-09 16:07:26 +08:00
void Widget : : removeGroup ( int groupId )
{
removeGroup ( GroupList : : findGroup ( groupId ) ) ;
}
2014-06-25 04:11:11 +08:00
Group * Widget : : createGroup ( int groupId )
{
Group * g = GroupList : : findGroup ( groupId ) ;
if ( g )
{
qWarning ( ) < < " Widget::createGroup: Group already exists " ;
return g ;
}
QString groupName = QString ( " Groupchat #%1 " ) . arg ( groupId ) ;
2014-11-13 20:11:23 +08:00
Group * newgroup = GroupList : : addGroup ( groupId , groupName , true ) ;
2014-08-22 23:19:16 +08:00
QLayout * layout = contactListWidget - > getGroupLayout ( ) ;
2014-11-23 23:22:29 +08:00
layout - > addWidget ( newgroup - > getGroupWidget ( ) ) ;
newgroup - > getGroupWidget ( ) - > updateStatusLight ( ) ;
2015-02-06 19:28:49 +08:00
Core * core = Nexus : : getCore ( ) ;
2015-02-18 11:07:56 +08:00
connect ( settingsWidget , & SettingsWidget : : compactToggled , newgroup - > getGroupWidget ( ) , & GenericChatroomWidget : : onCompactChanged ) ;
2014-11-23 23:22:29 +08:00
connect ( newgroup - > getGroupWidget ( ) , SIGNAL ( chatroomWidgetClicked ( GenericChatroomWidget * ) ) , this , SLOT ( onChatroomWidgetClicked ( GenericChatroomWidget * ) ) ) ;
connect ( newgroup - > getGroupWidget ( ) , SIGNAL ( removeGroup ( int ) ) , this , SLOT ( removeGroup ( int ) ) ) ;
connect ( newgroup - > getGroupWidget ( ) , SIGNAL ( chatroomWidgetClicked ( GenericChatroomWidget * ) ) , newgroup - > getChatForm ( ) , SLOT ( focusInput ( ) ) ) ;
connect ( newgroup - > getChatForm ( ) , SIGNAL ( sendMessage ( int , QString ) ) , core , SLOT ( sendGroupMessage ( int , QString ) ) ) ;
connect ( newgroup - > getChatForm ( ) , SIGNAL ( sendAction ( int , QString ) ) , core , SLOT ( sendGroupAction ( int , QString ) ) ) ;
connect ( newgroup - > getChatForm ( ) , & GroupChatForm : : groupTitleChanged , core , & Core : : changeGroupTitle ) ;
2014-06-25 04:11:11 +08:00
return newgroup ;
}
2014-06-30 05:38:48 +08:00
void Widget : : onEmptyGroupCreated ( int groupId )
{
createGroup ( groupId ) ;
}
2014-07-01 03:14:51 +08:00
bool Widget : : isFriendWidgetCurActiveWidget ( Friend * f )
{
if ( ! f )
return false ;
2014-09-02 00:20:28 +08:00
2014-11-06 23:26:22 +08:00
return ( activeChatroomWidget = = static_cast < GenericChatroomWidget * > ( f - > getFriendWidget ( ) ) ) ;
2014-07-01 03:14:51 +08:00
}
2014-07-01 10:12:17 +08:00
2014-07-03 06:27:30 +08:00
bool Widget : : event ( QEvent * e )
2014-07-01 10:12:17 +08:00
{
2014-12-12 00:49:11 +08:00
switch ( e - > type ( ) )
{
2014-10-16 17:47:58 +08:00
case QEvent : : WindowActivate :
if ( activeChatroomWidget ! = nullptr )
{
activeChatroomWidget - > resetEventFlags ( ) ;
activeChatroomWidget - > updateStatusLight ( ) ;
}
2014-12-12 00:49:11 +08:00
if ( eventFlag )
{
eventFlag = false ;
eventIcon = false ;
updateTrayIcon ( ) ;
}
2014-10-16 17:47:58 +08:00
default :
break ;
2014-07-03 06:27:30 +08:00
}
2014-07-01 10:12:17 +08:00
return QWidget : : event ( e ) ;
}
2014-11-26 20:34:08 +08:00
void Widget : : onUserAwayCheck ( )
2014-11-15 07:43:38 +08:00
{
2014-12-02 08:14:06 +08:00
# ifdef QTOX_PLATFORM_EXT
2014-11-27 02:27:20 +08:00
uint32_t autoAwayTime = Settings : : getInstance ( ) . getAutoAwayTime ( ) * 60 * 1000 ;
2014-11-15 07:43:38 +08:00
2014-12-02 05:28:53 +08:00
if ( ui - > statusButton - > property ( " status " ) . toString ( ) = = " online " )
2014-10-16 17:47:58 +08:00
{
2014-12-02 05:28:53 +08:00
if ( autoAwayTime & & Platform : : getIdleTime ( ) > = autoAwayTime )
2014-11-26 20:34:08 +08:00
{
2014-12-02 05:28:53 +08:00
qDebug ( ) < < " Widget: auto away activated at " < < QTime : : currentTime ( ) . toString ( ) ;
emit statusSet ( Status : : Away ) ;
autoAwayActive = true ;
2014-11-26 20:34:08 +08:00
}
}
2014-12-02 05:28:53 +08:00
else if ( ui - > statusButton - > property ( " status " ) . toString ( ) = = " away " )
2014-10-16 17:47:58 +08:00
{
2014-12-02 05:28:53 +08:00
if ( autoAwayActive & & ( ! autoAwayTime | | Platform : : getIdleTime ( ) < autoAwayTime ) )
2014-11-26 20:34:08 +08:00
{
2014-12-02 05:28:53 +08:00
qDebug ( ) < < " Widget: auto away deactivated at " < < QTime : : currentTime ( ) . toString ( ) ;
emit statusSet ( Status : : Online ) ;
autoAwayActive = false ;
2014-11-26 20:34:08 +08:00
}
2014-10-16 17:47:58 +08:00
}
2014-12-02 05:28:53 +08:00
else if ( autoAwayActive )
2014-11-26 20:34:08 +08:00
autoAwayActive = false ;
2014-12-02 08:14:06 +08:00
# endif
2014-10-16 17:47:58 +08:00
}
2014-12-12 00:49:11 +08:00
void Widget : : onEventIconTick ( )
{
if ( eventFlag )
{
eventIcon ^ = true ;
updateTrayIcon ( ) ;
}
}
2015-02-20 18:56:20 +08:00
void Widget : : onTryCreateTrayIcon ( )
{
static int32_t tries = 15 ;
if ( ! icon & & tries - - )
{
if ( QSystemTrayIcon : : isSystemTrayAvailable ( ) )
{
icon = new SystemTrayIcon ;
updateTrayIcon ( ) ;
trayMenu = new QMenu ;
actionQuit = new QAction ( tr ( " &Quit " ) , this ) ;
connect ( actionQuit , SIGNAL ( triggered ( ) ) , qApp , SLOT ( quit ( ) ) ) ;
trayMenu - > addAction ( statusOnline ) ;
trayMenu - > addAction ( statusAway ) ;
trayMenu - > addAction ( statusBusy ) ;
trayMenu - > addSeparator ( ) ;
trayMenu - > addAction ( actionQuit ) ;
icon - > setContextMenu ( trayMenu ) ;
connect ( icon , SIGNAL ( activated ( QSystemTrayIcon : : ActivationReason ) ) ,
this , SLOT ( onIconClick ( QSystemTrayIcon : : ActivationReason ) ) ) ;
if ( Settings : : getInstance ( ) . getShowSystemTray ( ) )
{
icon - > show ( ) ;
setHidden ( Settings : : getInstance ( ) . getAutostartInTray ( ) ) ;
}
else
show ( ) ;
}
else if ( ! isVisible ( ) )
show ( ) ;
}
else
{
disconnect ( timer , & QTimer : : timeout , this , & Widget : : onTryCreateTrayIcon ) ;
if ( ! icon )
{
qWarning ( ) < < " Widget: No system tray detected! " ;
show ( ) ;
}
}
}
2014-07-06 04:54:27 +08:00
void Widget : : setStatusOnline ( )
{
2015-02-06 19:28:49 +08:00
Nexus : : getCore ( ) - > setStatus ( Status : : Online ) ;
2014-07-06 04:54:27 +08:00
}
void Widget : : setStatusAway ( )
{
2015-02-06 19:28:49 +08:00
Nexus : : getCore ( ) - > setStatus ( Status : : Away ) ;
2014-07-06 04:54:27 +08:00
}
void Widget : : setStatusBusy ( )
2014-07-04 01:33:08 +08:00
{
2015-02-06 19:28:49 +08:00
Nexus : : getCore ( ) - > setStatus ( Status : : Busy ) ;
2014-07-04 01:33:08 +08:00
}
2014-07-21 02:17:06 +08:00
2014-09-24 00:35:06 +08:00
void Widget : : onMessageSendResult ( int friendId , const QString & message , int messageId )
{
Q_UNUSED ( message )
2014-11-10 19:30:56 +08:00
Q_UNUSED ( messageId )
2014-09-24 00:35:06 +08:00
Friend * f = FriendList : : findFriend ( friendId ) ;
if ( ! f )
return ;
}
void Widget : : onGroupSendResult ( int groupId , const QString & message , int result )
{
Q_UNUSED ( message )
Group * g = GroupList : : findGroup ( groupId ) ;
if ( ! g )
return ;
if ( result = = - 1 )
2015-01-05 01:21:35 +08:00
g - > getChatForm ( ) - > addSystemInfoMessage ( tr ( " Message failed to send " ) , ChatMessage : : INFO , QDateTime : : currentDateTime ( ) ) ;
2014-09-24 00:35:06 +08:00
}
2014-10-16 00:18:32 +08:00
2015-01-04 19:20:36 +08:00
void Widget : : onFriendTypingChanged ( int friendId , bool isTyping )
{
Friend * f = FriendList : : findFriend ( friendId ) ;
if ( ! f )
return ;
f - > getChatForm ( ) - > setFriendTyping ( isTyping ) ;
}
2015-02-20 18:56:20 +08:00
void Widget : : onSetShowSystemTray ( bool newValue )
{
if ( icon )
icon - > setVisible ( newValue ) ;
2014-11-14 04:33:11 +08:00
}
2014-11-28 06:35:56 +08:00
void Widget : : saveWindowGeometry ( )
{
Settings : : getInstance ( ) . setWindowGeometry ( saveGeometry ( ) ) ;
Settings : : getInstance ( ) . setWindowState ( saveState ( ) ) ;
}
void Widget : : saveSplitterGeometry ( )
{
Settings : : getInstance ( ) . setSplitterState ( ui - > mainSplitter - > saveState ( ) ) ;
}
2014-11-28 17:16:37 +08:00
void Widget : : onSplitterMoved ( int pos , int index )
{
Q_UNUSED ( pos ) ;
Q_UNUSED ( index ) ;
saveSplitterGeometry ( ) ;
}
2014-11-14 04:33:11 +08:00
2015-02-13 13:27:49 +08:00
void Widget : : processOfflineMsgs ( )
{
if ( OfflineMsgEngine : : globalMutex . tryLock ( ) )
{
QList < Friend * > frnds = FriendList : : getAllFriends ( ) ;
for ( Friend * f : frnds )
{
f - > getChatForm ( ) - > getOfflineMsgEngine ( ) - > deliverOfflineMsgs ( ) ;
}
OfflineMsgEngine : : globalMutex . unlock ( ) ;
}
}
2014-11-10 21:06:35 +08:00
void Widget : : clearAllReceipts ( )
{
QList < Friend * > frnds = FriendList : : getAllFriends ( ) ;
for ( Friend * f : frnds )
{
2015-02-08 00:18:25 +08:00
f - > getChatForm ( ) - > getOfflineMsgEngine ( ) - > removeAllReciepts ( ) ;
2014-11-10 21:06:35 +08:00
}
2014-11-15 03:12:23 +08:00
}
2014-11-16 04:30:20 +08:00
void Widget : : reloadTheme ( )
{
2015-02-07 19:46:55 +08:00
QString statusPanelStyle = Style : : getStylesheet ( " :/ui/window/statusPanel.css " ) ;
2014-11-16 04:30:20 +08:00
ui - > tooliconsZone - > setStyleSheet ( Style : : resolve ( " QPushButton{background-color:@themeDark;border:none;}QPushButton:hover{background-color:@themeMediumDark;border:none;} " ) ) ;
2015-02-07 19:46:55 +08:00
ui - > statusPanel - > setStyleSheet ( statusPanelStyle ) ;
ui - > statusHead - > setStyleSheet ( statusPanelStyle ) ;
2014-11-16 04:30:20 +08:00
ui - > friendList - > setStyleSheet ( Style : : getStylesheet ( " :ui/friendList/friendList.css " ) ) ;
ui - > statusButton - > setStyleSheet ( Style : : getStylesheet ( " :ui/statusButton/statusButton.css " ) ) ;
for ( Friend * f : FriendList : : getAllFriends ( ) )
f - > getFriendWidget ( ) - > reloadTheme ( ) ;
2014-11-20 17:13:13 +08:00
for ( Group * g : GroupList : : getAllGroups ( ) )
2014-11-23 23:22:29 +08:00
g - > getGroupWidget ( ) - > reloadTheme ( ) ;
2014-11-16 04:30:20 +08:00
}
2015-02-28 01:56:47 +08:00
void Widget : : nextContact ( )
{
// dont know how to get current/previous/next contact from friendlistwidget
qDebug ( ) < < " next contact " ;
}
void Widget : : previousContact ( )
{
qDebug ( ) < < " previous contact " ;
}