From 7e208e33021b40a47732140662450cbb1b390c7e Mon Sep 17 00:00:00 2001 From: Bill Winslow Date: Wed, 23 Jul 2014 05:00:55 -0500 Subject: [PATCH 001/149] updated bootstrap.sh so I don't have to not-add it and other minutiae --- bootstrap.sh | 67 ++++++++++++++++++++++++++-------- widget/filetransfertwidget.cpp | 4 +- 2 files changed, 54 insertions(+), 17 deletions(-) diff --git a/bootstrap.sh b/bootstrap.sh index cc25129f8..4114f26db 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -19,6 +19,8 @@ TOX_CORE_DIR=libtoxcore-latest # the default value is 'false' and will be set to 'true' # if this script gets the parameter -t or --tox TOX_ONLY=false +GLOBAL=false +KEEP=false if [ -z "$BASE_DIR" ]; then echo "internal error detected!" @@ -41,9 +43,16 @@ fi ########## check input parameters ########## -if [ $# -ge 1 ] ; then +while [ $# -ge 1 ] ; do if [ ${1} = "-t" -o ${1} = "--tox" ] ; then TOX_ONLY=true + shift + elif [ ${1} = "-g" -o ${1} = "--global" ] ; then + GLOBAL=true + shift + elif [ ${1} = "-k" -o ${1} = "--keep" ]; then + KEEP=true + shift else if [ ${1} != "-h" -a ${1} != "--help" ] ; then echo "[ERROR] Unknown parameter \"${1}\"" @@ -54,21 +63,26 @@ if [ $# -ge 1 ] ; then echo "Use this script to install/update libsodium and libtoxcore in ${INSTALL_DIR}" echo "" echo "usage:" - echo " ${0} [-t|--tox|-h|--help]" + echo " ${0} [-t|--tox|-h|--help|-g|--global|-k|--keep]" echo "" echo "parameters:" - echo " -h|--help: displays this help" - echo " -t|--tox : only install/update libtoxcore" - echo " requires an already installed libsodium" + echo " -h|--help : displays this help" + echo " -t|--tox : only install/update libtoxcore" + echo " requires an already installed libsodium" + echo " -g|--global: installs libtox* and libsodium globally" + echo " (also disables local configure prefixes)" + echo " -k|--keep : does not delete the build directories afterwards" echo "" echo "example usages:" echo " ${0} -- to install libsodium and libtoxcore" echo " ${0} -t -- to update already installed libtoxcore" exit 1 fi -fi - +done +echo "Tox only: $TOX_ONLY" +echo "Global : $GLOBAL" +echo "Keep : $KEEP" ############### prepare step ############### # create BASE_DIR directory if necessary @@ -91,9 +105,21 @@ if [[ $TOX_ONLY = "false" ]]; then pushd ${BASE_DIR}/${SODIUM_DIR} git checkout tags/0.5.0 ./autogen.sh - ./configure --prefix=${BASE_DIR}/ + + if [[ $GLOBAL = "false" ]]; then + ./configure --prefix=${BASE_DIR}/ + else + ./configure + fi + make -j2 check - make install + + if [[ $GLOBAL = "false" ]]; then + make install + else + sudo make install + fi + popd fi @@ -103,14 +129,25 @@ fi git clone https://github.com/irungentoo/toxcore.git ${BASE_DIR}/${TOX_CORE_DIR} pushd ${BASE_DIR}/${TOX_CORE_DIR} ./autogen.sh -./configure --prefix=${BASE_DIR}/ --with-libsodium-headers=${BASE_DIR}/include --with-libsodium-libs=${BASE_DIR}/lib +if [[ $GLOBAL = "false" ]]; then + ./configure --prefix=${BASE_DIR}/ --with-libsodium-headers=${BASE_DIR}/include --with-libsodium-libs=${BASE_DIR}/lib +else + ./configure +fi + make -j2 -make install + +if [[ $GLOBAL = "false" ]]; then + make install +else + sudo make install +fi + popd - - ############### cleanup step ############### # remove cloned repositories -rm -rf ${BASE_DIR}/${SODIUM_DIR} -rm -rf ${BASE_DIR}/${TOX_CORE_DIR} +if [[ $KEEP = "false" ]]; then + rm -rf ${BASE_DIR}/${SODIUM_DIR} + rm -rf ${BASE_DIR}/${TOX_CORE_DIR} +fi diff --git a/widget/filetransfertwidget.cpp b/widget/filetransfertwidget.cpp index 568ce93a2..e90d8b2d0 100644 --- a/widget/filetransfertwidget.cpp +++ b/widget/filetransfertwidget.cpp @@ -286,7 +286,7 @@ void FileTransfertWidget::acceptRecvRequest() QString path; while (true) { - path = QFileDialog::getSaveFileName(0,tr("Save a file","Title of the file saving dialog"),QDir::currentPath()+'/'+filename->text()); + path = QFileDialog::getSaveFileName(this,tr("Save a file","Title of the file saving dialog"),QDir::currentPath()+'/'+filename->text()); if (path.isEmpty()) return; else @@ -297,7 +297,7 @@ void FileTransfertWidget::acceptRecvRequest() if (isWritable(path)) break; else - QMessageBox::warning(0, tr("Location not writable","Title of permissions popup"), tr("You do not have permission to write that location. Choose another, or cancel the save dialog.", "text of permissions popup")); + QMessageBox::warning(this, tr("Location not writable","Title of permissions popup"), tr("You do not have permission to write that location. Choose another, or cancel the save dialog.", "text of permissions popup")); } } From 751f828c3ef06bd291059dcdc1f95f74d78297d3 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Wed, 23 Jul 2014 12:50:12 +0200 Subject: [PATCH 002/149] Fix build settings on Windows I was missing GetAdaptersInfo@8, linked with iphlpapi --- qtox.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qtox.pro b/qtox.pro index e12cc4cd1..77a6fe9b7 100644 --- a/qtox.pro +++ b/qtox.pro @@ -40,7 +40,7 @@ INSTALLS += target INCLUDEPATH += libs/include win32 { - LIBS += $$PWD/libs/lib/libtoxav.a $$PWD/libs/lib/libopus.a $$PWD/libs/lib/libvpx.a $$PWD/libs/lib/libtoxcore.a -lws2_32 $$PWD/libs/lib/libsodium.a -lpthread + LIBS += $$PWD/libs/lib/libtoxav.a $$PWD/libs/lib/libopus.a $$PWD/libs/lib/libvpx.a $$PWD/libs/lib/libtoxcore.a -lws2_32 $$PWD/libs/lib/libsodium.a -lpthread -liphlpapi } else { LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lsodium -lvpx } From f080eb12e7a48359e5aa1ed352082a4d6e9cedcb Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 23 Jul 2014 23:41:05 +0200 Subject: [PATCH 003/149] added placeholder text for chat input widget --- widget/tool/chattextedit.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/widget/tool/chattextedit.cpp b/widget/tool/chattextedit.cpp index face13191..8f727cfbb 100644 --- a/widget/tool/chattextedit.cpp +++ b/widget/tool/chattextedit.cpp @@ -20,6 +20,7 @@ ChatTextEdit::ChatTextEdit(QWidget *parent) : QTextEdit(parent) { + setPlaceholderText("Type your message here..."); } void ChatTextEdit::keyPressEvent(QKeyEvent * event) From 9c0af06c0b41ad64136527b221e0defecacc4ab8 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 23 Jul 2014 23:52:55 +0200 Subject: [PATCH 004/149] use default invite message as placeholder text --- widget/form/addfriendform.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/widget/form/addfriendform.cpp b/widget/form/addfriendform.cpp index 76072b230..d83e9b5b3 100644 --- a/widget/form/addfriendform.cpp +++ b/widget/form/addfriendform.cpp @@ -35,6 +35,7 @@ AddFriendForm::AddFriendForm() : dns(this) toxIdLabel.setText(tr("Tox ID","Tox ID of the person you're sending a friend request to")); messageLabel.setText(tr("Message","The message you send in friend requests")); sendButton.setText(tr("Send friend request")); + message.setPlaceholderText(tr("Tox me maybe?","Default message in friend requests if the field is left blank. Write something appropriate!")); main->setLayout(&layout); layout.addWidget(&toxIdLabel); @@ -81,7 +82,7 @@ void AddFriendForm::showWarning(const QString &message) const QString AddFriendForm::getMessage() const { const QString msg = message.toPlainText(); - return !msg.isEmpty() ? msg : tr("Tox me maybe?","Default message in friend requests if the field is left blank. Write something appropriate!"); + return !msg.isEmpty() ? msg : message.placeholderText(); } void AddFriendForm::onSendTriggered() From f7e462272ac584735a54423dd247175193808098 Mon Sep 17 00:00:00 2001 From: Kevin Flynn Date: Wed, 23 Jul 2014 19:05:14 -0700 Subject: [PATCH 005/149] Fix friendList mixed horizontal & vertical scroll, improved scrollbar theme on OS X --- ui/friendList/friendList.css | 30 +++++++++++++++--------------- widget/widget.cpp | 6 +----- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/ui/friendList/friendList.css b/ui/friendList/friendList.css index 42bf69cc1..55b39e1e6 100644 --- a/ui/friendList/friendList.css +++ b/ui/friendList/friendList.css @@ -1,34 +1,34 @@ QScrollArea { - background: #414141!important; + background: #414141; } QScrollBar:vertical { - background: #414141!important; - width: 14px!important; - margin-top: 2px!important; - margin-bottom: 2px!important; + background: transparent; + width: 14px; + margin-top: 2px; + margin-bottom: 2px; } QScrollBar:handle:vertical { - background: #1c1c1c!important; - min-height: 20px!important; - border-radius: 3px!important; - margin-left: 3px!important; - margin-right: 1px!important; + background: rgba(18, 18, 18, 204); + min-height: 20px; + border-radius: 3px; + margin-left: 3px; + margin-right: 1px; } QScrollBar:handle:vertical:hover { - background: #2d2d2d!important; + background: rgba(35, 35, 35, 204); } QScrollBar:handle:vertical:pressed { - background: #171717!important; + background: rgba(13, 13, 13, 204); } -QScrollBar:add-line:vertical {height: 0px!important;subcontrol-position: bottom!important;subcontrol-origin: margin!important;} +QScrollBar:add-line:vertical {height: 0px;subcontrol-position: bottom;subcontrol-origin: margin;} -QScrollBar:sub-line:vertical {height: 0px!important;subcontrol-position: top!important;subcontrol-origin: margin!important;} +QScrollBar:sub-line:vertical {height: 0px;subcontrol-position: top;subcontrol-origin: margin;} QScrollBar:add-page:vertical, QScrollBar::sub-page:vertical { - background: none!important; + background: none; } diff --git a/widget/widget.cpp b/widget/widget.cpp index e0c8954ba..890b0447a 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -1213,11 +1213,7 @@ bool Widget::eventFilter(QObject *, QEvent *event) if (event->type() == QEvent::Wheel) { QWheelEvent * whlEvnt = static_cast< QWheelEvent * >( event ); - if (whlEvnt->angleDelta().x() != 0) - { - event->accept(); - return true; - } + whlEvnt->angleDelta().setX(0); } return false; } From ba8fb8914da32d1cd5ffb68dfa4f658aa6cadb6e Mon Sep 17 00:00:00 2001 From: Ansa89 Date: Thu, 24 Jul 2014 12:35:04 +0200 Subject: [PATCH 006/149] Italian translation: update --- translations/it.qm | Bin 5358 -> 5826 bytes translations/it.ts | 48 ++++++++++++++++++++++++++++++--------------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/translations/it.qm b/translations/it.qm index d8c42654a6c132df002f771a6cd33cd91d99646c..db9dc34f8061ef1e47ed6ea048c0eb17a743e420 100644 GIT binary patch delta 1007 zcmYLGU1$_n7(JVv+0ATrC)Gp{jd-!~7n43j4L(V!KQV~5+D4>QnaNl7zs`r*B9?2p)zjQz5vR8H2xiWLZV&f^14~TZZI30udu;cb5pJs zh^5UF6<2`@&+O|v&bpNObMJlTv*yjK(?EPO@y()p=j>xf%Yv3`m%zCXQf6$PthI^4@aQdODkjRJAgnP~LXXB3QO z#+Oae>TX6_#a1SUSWq!+*PPGtZ-w1(c|TCT+TLB@6U-m8clTcBQ<(Oi8rE57>>I74 zobZlEl|M!v#x5n-q_G77m*SS?nl!<^V25&@$WwWdSCKdvc#-pU|A4i$Us>CVPqCBm zJOpxZ;4y~iL@SpEms>IymF^2X2k788vv=$_fN)x%XvjiBsGTv3XYbTw1_m)XnJXE`GIa z8<&==f9J+m`&6gMs*)Eu=hH4J3Nq;M!cZF&sggfZL^&rC{#)Pb#V0wXLMa>?n3KU; zp#tGLc~|-bN)b9_$$E~j+UiFJtukvQQ`H_THlu~w+D_e(o}h;(-KTgvT}Yd?sb0y} z|BZIpZwJlwnbR}S{&(FkY4PMi;i`^;FC&>1t)9{`G6hRCM%>u(pi6~LG^w2s-=9#e~4q<^| zuyUo=jHo1{E*wlHDoD*hb`i+*qAvO+>MDqWA}D&-`1p9g??j-;z3|3zQl=NZK%tm0jgX+HmAiqQ?o&tm+G;F;Fl)gse_E(gDf%Kn6;)}S| z%7_=__jrE;$`(F1d;!1$zcl!r_^XA)s7*L1jPzdx+|xyLv<D!b$!qk)qwnY>86X7*s< zISI+Isj)?XUl32Mou>Y?qNVPp1^uG6>k#2}G10sp4ocoj+!_*~dL&onFd*iNsLn~b z&wV6lN#@R-r$Jw2XWt!w%_#k&2g!Gox%$U|>x}YNBcZNmu3tmdlwaqr$rJL&)Vcr- zD!Z-rw9o=_s}|05)8;N0>8E3+TCn^J0Csmq>rf0CUY2%sGnYVTEp diff --git a/translations/it.ts b/translations/it.ts index cde73cd0f..069303057 100644 --- a/translations/it.ts +++ b/translations/it.ts @@ -26,50 +26,50 @@ Invia richiesta d'amicizia - + Tox me maybe? Default message in friend requests if the field is left blank. Write something appropriate! Permettimi di aggiungerti alla mia lista contatti - + Please fill in a valid Tox ID Tox ID of the friend you're sending a friend request to Inserisci un Tox ID valido - + This address does not exist The DNS gives the Tox ID associated to toxme.se addresses Questo indirizzo non esiste - + Error while looking up DNS The DNS gives the Tox ID associated to toxme.se addresses Errore nel consultare il server DNS - + Unexpected number of text records Error with the DNS Numero inaspettato di text-records - + Unexpected number of values in text record Error with the DNS Numero inaspettato di valori nel text-record - + The DNS lookup does not contain any Tox ID Error with the DNS La risposta del server DNS non contiene nessun Tox ID - - + + The DNS lookup does not contain a valid Tox ID Error with the DNS La risposta del server DNS non contiene un Tox ID valido @@ -91,13 +91,13 @@ ChatForm - + Send a file Invia un file - - + + Save chat log Salva il log della chat @@ -113,11 +113,23 @@ FileTransfertWidget - + Save a file Title of the file saving dialog Salva file + + + Location not writable + Title of permissions popup + Errore + + + + You do not have permission to write that location. Choose another, or cancel the save dialog. + text of permissions popup + Non hai sufficienti permessi per scrivere in questa locazione. Scegli un'altra posizione, o annulla il salvataggio. + FilesForm @@ -128,12 +140,12 @@ Files inviati - + Downloads Ricevuti - + Uploads Inviati @@ -329,8 +341,12 @@ + View completed file transfers + Visualizza i trasferimenti completati + + (button inactive currently) - (bottone attualmente inattivo) + (bottone attualmente inattivo) From e01467e386a7b46a83ff7c7de0bbf6b7e3a089e0 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 25 Jul 2014 14:52:14 +0200 Subject: [PATCH 007/149] basic support for smileys --- qtox.pro | 8 ++- settings.cpp | 4 +- settings.h | 6 +- smileypack.cpp | 122 +++++++++++++++++++++++++++++++++++ smileypack.h | 43 ++++++++++++ widget/form/chatform.cpp | 2 + widget/form/settingsform.cpp | 23 +++++++ widget/form/settingsform.h | 6 +- 8 files changed, 204 insertions(+), 10 deletions(-) create mode 100644 smileypack.cpp create mode 100644 smileypack.h diff --git a/qtox.pro b/qtox.pro index 77a6fe9b7..f1d64f544 100644 --- a/qtox.pro +++ b/qtox.pro @@ -20,7 +20,7 @@ # See the COPYING file for more details. -QT += core gui network multimedia multimediawidgets +QT += core gui network multimedia multimediawidgets xml greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = qtox @@ -83,7 +83,8 @@ HEADERS += widget/form/addfriendform.h \ widget/videosurface.h \ widget/camera.h \ widget/netcamview.h \ - widget/tool/clickablelabel.h + widget/tool/clickablelabel.h \ + smileypack.h SOURCES += \ widget/form/addfriendform.cpp \ @@ -115,4 +116,5 @@ SOURCES += \ widget/videosurface.cpp \ widget/camera.cpp \ widget/netcamview.cpp \ - widget/tool/clickablelabel.cpp + widget/tool/clickablelabel.cpp \ + smileypack.cpp diff --git a/settings.cpp b/settings.cpp index 888d840a5..42e759f3e 100644 --- a/settings.cpp +++ b/settings.cpp @@ -258,12 +258,12 @@ void Settings::setAnimationEnabled(bool newValue) enableSmoothAnimation = newValue; } -QByteArray Settings::getSmileyPack() const +QString Settings::getSmileyPack() const { return smileyPack; } -void Settings::setSmileyPack(const QByteArray &value) +void Settings::setSmileyPack(const QString &value) { smileyPack = value; emit smileyPackChanged(); diff --git a/settings.h b/settings.h index d4f015635..95e16620f 100644 --- a/settings.h +++ b/settings.h @@ -83,8 +83,8 @@ public: bool isAnimationEnabled() const; void setAnimationEnabled(bool newValue); - QByteArray getSmileyPack() const; - void setSmileyPack(const QByteArray &value); + QString getSmileyPack() const; + void setSmileyPack(const QString &value); bool isCurstomEmojiFont() const; void setCurstomEmojiFont(bool value); @@ -142,7 +142,7 @@ private: // GUI bool enableSmoothAnimation; - QByteArray smileyPack; + QString smileyPack; bool customEmojiFont; QString emojiFontFamily; int emojiFontPointSize; diff --git a/smileypack.cpp b/smileypack.cpp new file mode 100644 index 000000000..f035704e7 --- /dev/null +++ b/smileypack.cpp @@ -0,0 +1,122 @@ +/* + Copyright (C) 2013 by Maxim Biro + + This file is part of Tox Qt GUI. + + 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 COPYING file for more details. +*/ + +#include "smileypack.h" +#include "settings.h" + +#include +#include +#include +#include + +SmileyPack::SmileyPack() +{ + load(Settings::getInstance().getSmileyPack()); + connect(&Settings::getInstance(), &Settings::smileyPackChanged, this, &SmileyPack::onSmileyPackChanged); +} + +SmileyPack& SmileyPack::getInstance() +{ + static SmileyPack smileyPack; + return smileyPack; +} + +bool SmileyPack::load(const QString& filename) +{ + // discard old data + lookupTable.clear(); + QDir::setSearchPaths("smiley", QStringList()); + + // open emoticons.xml + QFile xmlFile(filename); + if(!xmlFile.open(QIODevice::ReadOnly)) + return false; // cannot open file + + /* parse the cfg document + * sample: + * + * + * + * :) + * :-) + * + * + * :( + * :-( + * + * + */ + + QDomDocument doc; + doc.setContent(xmlFile.readAll()); + + QDomNodeList emoticonElements = doc.elementsByTagName("emoticon"); + for (int i = 0; i < emoticonElements.size(); ++i) + { + QString file = emoticonElements.at(i).attributes().namedItem("file").nodeValue(); + QDomElement stringElement = emoticonElements.at(i).firstChildElement("string"); + + while (!stringElement.isNull()) + { + QString rune = stringElement.text(); + lookupTable.insert(rune, file); // add it to the map + + stringElement = stringElement.nextSibling().toElement(); + } + } + + // Rich Text makes use of Qt's resource system, so + // let Qt know about our smilies + QFileInfo info(filename); + QDir::setSearchPaths("smiley", QStringList() << info.absolutePath()); + + // success! + return true; +} + +QString SmileyPack::replaceEmoticons(const QString &msg) const +{ + QString out = msg; + QRegExp exp("\\S*"); // matches words + + int index = msg.indexOf(exp); + int offset = 0; + + // if a word is key of a smiley, replace it by it's corresponding image in Rich Text + while (index >= 0 || exp.matchedLength() > 0) + { + QString key = exp.cap(); + if (lookupTable.contains(key)) + { + QString width = QString::number(16); + QString height = QString::number(16); + + QString img = lookupTable[key]; + QString imgRt = ""; + + out.replace(index + offset, key.length(), imgRt); + offset += imgRt.length() - key.length(); + } + index = msg.indexOf(exp, index + exp.matchedLength() + 1); + } + + return out; +} + +void SmileyPack::onSmileyPackChanged() +{ + load(Settings::getInstance().getSmileyPack()); +} diff --git a/smileypack.h b/smileypack.h new file mode 100644 index 000000000..559abb491 --- /dev/null +++ b/smileypack.h @@ -0,0 +1,43 @@ +/* + Copyright (C) 2013 by Maxim Biro + + This file is part of Tox Qt GUI. + + 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 COPYING file for more details. +*/ + +#ifndef SMILEYPACK_H +#define SMILEYPACK_H + +#include +#include +#include + +//maps emoticons to smilies +class SmileyPack : public QObject +{ + Q_OBJECT +public: + explicit SmileyPack(); + SmileyPack(SmileyPack&) = delete; + SmileyPack& operator=(const SmileyPack&) = delete; + + static SmileyPack& getInstance(); + + bool load(const QString &filename); + QString replaceEmoticons(const QString& msg) const; +protected: + QHash lookupTable; // matches an emoticon with it's corresponding smiley +private slots: + void onSmileyPackChanged(); +}; + +#endif // SMILEYPACK_H diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index 13d4b5271..07e7d9e4b 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -16,6 +16,7 @@ #include "chatform.h" #include "friend.h" +#include "smileypack.h" #include "widget/friendwidget.h" #include "widget/widget.h" #include "widget/filetransfertwidget.h" @@ -238,6 +239,7 @@ void ChatForm::addFriendMessage(QString message) void ChatForm::addMessage(QString author, QString message, QString date) { + message = SmileyPack::getInstance().replaceEmoticons(message); addMessage(new QLabel(author), new QLabel(message), new QLabel(date)); } diff --git a/widget/form/settingsform.cpp b/widget/form/settingsform.cpp index 1179497c5..9d2c71d00 100644 --- a/widget/form/settingsform.cpp +++ b/widget/form/settingsform.cpp @@ -20,6 +20,8 @@ #include #include #include +#include +#include SettingsForm::SettingsForm() : QObject() @@ -49,6 +51,9 @@ SettingsForm::SettingsForm() makeToxPortable.setText(tr("Make Tox portable","Text on a checkbox to make qTox a portable application")); makeToxPortable.setChecked(Settings::getInstance().getMakeToxPortable()); + smileyPackLabel.setText(tr("Smiley Pack", "Text on smiley pack label")); + smileyPackFilename.setText(Settings::getInstance().getSmileyPack()); + main->setLayout(&layout); layout.addWidget(&nameLabel); layout.addWidget(&name); @@ -60,6 +65,9 @@ SettingsForm::SettingsForm() layout.addWidget(&enableIPv6); layout.addWidget(&useTranslations); layout.addWidget(&makeToxPortable); + layout.addWidget(&smileyPackLabel); + layout.addWidget(&smileyPackFilename); + layout.addWidget(&smileyBrowseFileButton); layout.addStretch(); head->setLayout(&headLayout); @@ -70,6 +78,7 @@ SettingsForm::SettingsForm() connect(&useTranslations, SIGNAL(stateChanged(int)), this, SLOT(onUseTranslationUpdated())); connect(&makeToxPortable, SIGNAL(stateChanged(int)), this, SLOT(onMakeToxPortableUpdated())); connect(&idLabel, SIGNAL(clicked()), this, SLOT(copyIdClicked())); + connect(&smileyBrowseFileButton, SIGNAL(clicked()), this, SLOT(onBrowseSmileyFilename())); } SettingsForm::~SettingsForm() @@ -116,3 +125,17 @@ void SettingsForm::onMakeToxPortableUpdated() { Settings::getInstance().setMakeToxPortable(makeToxPortable.isChecked()); } + +void SettingsForm::onBrowseSmileyFilename() +{ + // directory containing a file called emoticons.xml + QString filename = QFileDialog::getOpenFileName(nullptr, tr("Select smiley pack"), QDir::currentPath(), "emoticons.xml"); + + // get relative path to app's local directory + QString relPath = QDir::current().relativeFilePath(filename); + + // save + Settings::getInstance().setSmileyPack(relPath); + smileyPackFilename.setText(relPath); +} + diff --git a/widget/form/settingsform.h b/widget/form/settingsform.h index 3342c5667..5cf2c5532 100644 --- a/widget/form/settingsform.h +++ b/widget/form/settingsform.h @@ -47,17 +47,19 @@ private slots: void onEnableIPv6Updated(); void onUseTranslationUpdated(); void onMakeToxPortableUpdated(); + void onBrowseSmileyFilename(); void copyIdClicked(); private: - QLabel headLabel, nameLabel, statusTextLabel; + QLabel headLabel, nameLabel, statusTextLabel, smileyPackLabel; QTextEdit id; ClickableLabel idLabel; QPushButton videoTest; QCheckBox enableIPv6, useTranslations, makeToxPortable; QVBoxLayout layout, headLayout; QWidget *main, *head; - + QLineEdit smileyPackFilename; + QToolButton smileyBrowseFileButton; public: QLineEdit name, statusText; }; From 326fd655cb2c0496cc9318580597515b45343b89 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 25 Jul 2014 15:01:15 +0200 Subject: [PATCH 008/149] cleanup --- smileypack.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/smileypack.h b/smileypack.h index 559abb491..990fcc6a0 100644 --- a/smileypack.h +++ b/smileypack.h @@ -26,7 +26,7 @@ class SmileyPack : public QObject { Q_OBJECT public: - explicit SmileyPack(); + SmileyPack(); SmileyPack(SmileyPack&) = delete; SmileyPack& operator=(const SmileyPack&) = delete; @@ -35,7 +35,7 @@ public: bool load(const QString &filename); QString replaceEmoticons(const QString& msg) const; protected: - QHash lookupTable; // matches an emoticon with it's corresponding smiley + QHash lookupTable; // matches an emoticon with its corresponding smiley private slots: void onSmileyPackChanged(); }; From 234d46a48087b084186a8adcc0bfc310e85c8ade Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 26 Jul 2014 10:05:32 +0200 Subject: [PATCH 009/149] cleanup --- smileypack.cpp | 4 ++-- smileypack.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/smileypack.cpp b/smileypack.cpp index f035704e7..52fb3eaac 100644 --- a/smileypack.cpp +++ b/smileypack.cpp @@ -95,8 +95,8 @@ QString SmileyPack::replaceEmoticons(const QString &msg) const int index = msg.indexOf(exp); int offset = 0; - // if a word is key of a smiley, replace it by it's corresponding image in Rich Text - while (index >= 0 || exp.matchedLength() > 0) + // if a word is key of a smiley, replace it by its corresponding image in Rich Text + while (index >= 0) { QString key = exp.cap(); if (lookupTable.contains(key)) diff --git a/smileypack.h b/smileypack.h index 990fcc6a0..d87e177ff 100644 --- a/smileypack.h +++ b/smileypack.h @@ -21,7 +21,7 @@ #include #include -//maps emoticons to smilies +//maps emoticons to smileys class SmileyPack : public QObject { Q_OBJECT From e4f897221fa6b6f8434164f908bf649cd35ca253 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 26 Jul 2014 10:28:57 +0200 Subject: [PATCH 010/149] private constructor --- smileypack.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/smileypack.h b/smileypack.h index d87e177ff..1c7db70b6 100644 --- a/smileypack.h +++ b/smileypack.h @@ -26,18 +26,20 @@ class SmileyPack : public QObject { Q_OBJECT public: - SmileyPack(); - SmileyPack(SmileyPack&) = delete; - SmileyPack& operator=(const SmileyPack&) = delete; - static SmileyPack& getInstance(); bool load(const QString &filename); QString replaceEmoticons(const QString& msg) const; -protected: - QHash lookupTable; // matches an emoticon with its corresponding smiley + private slots: void onSmileyPackChanged(); + +private: + SmileyPack(); + SmileyPack(SmileyPack&) = delete; + SmileyPack& operator=(const SmileyPack&) = delete; + + QHash lookupTable; // matches an emoticon to its corresponding smiley }; #endif // SMILEYPACK_H From 22375e3b8f51c5117cb4c8b06b7da8114d513705 Mon Sep 17 00:00:00 2001 From: Bill Winslow Date: Sun, 27 Jul 2014 15:55:22 -0500 Subject: [PATCH 011/149] Randomized the bootstrap table, to distribute load away from the first 5 --- core.cpp | 6 ++++-- widget/form/settingsform.cpp | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/core.cpp b/core.cpp index d49c95266..94afee0ee 100644 --- a/core.cpp +++ b/core.cpp @@ -108,6 +108,8 @@ void Core::start() return; } + qsrand(time(nullptr)); + loadConfiguration(); tox_callback_friend_request(tox, onFriendRequest, this); @@ -675,9 +677,9 @@ void Core::bootstrapDht() const Settings& s = Settings::getInstance(); QList dhtServerList = s.getDhtServerList(); - static int j = 0; - int i=0; int listSize = dhtServerList.size(); + static int j = qrand() % listSize; + int i=0; while (i<5) { const Settings::DhtServer& dhtServer = dhtServerList[j % listSize]; diff --git a/widget/form/settingsform.cpp b/widget/form/settingsform.cpp index 1179497c5..16eaedb70 100644 --- a/widget/form/settingsform.cpp +++ b/widget/form/settingsform.cpp @@ -48,6 +48,7 @@ SettingsForm::SettingsForm() useTranslations.setChecked(Settings::getInstance().getUseTranslations()); makeToxPortable.setText(tr("Make Tox portable","Text on a checkbox to make qTox a portable application")); makeToxPortable.setChecked(Settings::getInstance().getMakeToxPortable()); + makeToxPortable.setToolTip(tr("Save settings to the working directory instead of the usual conf dir","describes makeToxPortable checkbox")); main->setLayout(&layout); layout.addWidget(&nameLabel); From 5ec0b0d8df5d7982ffe0b3d4ca1712de0e121db5 Mon Sep 17 00:00:00 2001 From: Bill Winslow Date: Sun, 27 Jul 2014 18:30:48 -0500 Subject: [PATCH 012/149] Latest API update It's a reasonably big change, and someone should test sending and recieving video and audio --- core.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++++++---------- core.h | 2 +- 2 files changed, 64 insertions(+), 14 deletions(-) diff --git a/core.cpp b/core.cpp index 94afee0ee..1497eda66 100644 --- a/core.cpp +++ b/core.cpp @@ -1003,8 +1003,16 @@ void Core::onAvInvite(void* _toxav, int32_t call_index, void* core) return; } - int transType = toxav_get_peer_transmission_type(toxav, call_index, 0); - if (transType == TypeVideo) + ToxAvCSettings* transSettings = new ToxAvCSettings; + int err = toxav_get_peer_csettings(toxav, call_index, 0, transSettings); + if (err != ErrorNone) + { + qWarning() << "Core::onAvInvite: error getting call type"; + delete transSettings; + return; + } + + if (transSettings->call_type == TypeVideo) { qDebug() << QString("Core: AV invite from %1 with video").arg(friendId); emit static_cast(core)->avInvite(friendId, call_index, true); @@ -1014,6 +1022,8 @@ void Core::onAvInvite(void* _toxav, int32_t call_index, void* core) qDebug() << QString("Core: AV invite from %1 without video").arg(friendId); emit static_cast(core)->avInvite(friendId, call_index, false); } + + delete transSettings; } void Core::onAvStart(void* _toxav, int32_t call_index, void* core) @@ -1027,8 +1037,16 @@ void Core::onAvStart(void* _toxav, int32_t call_index, void* core) return; } - int transType = toxav_get_peer_transmission_type(toxav, call_index, 0); - if (transType == TypeVideo) + ToxAvCSettings* transSettings = new ToxAvCSettings; + int err = toxav_get_peer_csettings(toxav, call_index, 0, transSettings); + if (err != ErrorNone) + { + qWarning() << "Core::onAvStart: error getting call type"; + delete transSettings; + return; + } + + if (transSettings->call_type == TypeVideo) { qDebug() << QString("Core: AV start from %1 with video").arg(friendId); prepareCall(friendId, call_index, toxav, true); @@ -1040,6 +1058,8 @@ void Core::onAvStart(void* _toxav, int32_t call_index, void* core) prepareCall(friendId, call_index, toxav, false); emit static_cast(core)->avStart(friendId, call_index, false); } + + delete transSettings; } void Core::onAvCancel(void* _toxav, int32_t call_index, void* core) @@ -1112,8 +1132,17 @@ void Core::onAvStarting(void* _toxav, int32_t call_index, void* core) qWarning() << "Core: Received invalid AV starting"; return; } - int transType = toxav_get_peer_transmission_type(toxav, call_index, 0); - if (transType == TypeVideo) + + ToxAvCSettings* transSettings = new ToxAvCSettings; + int err = toxav_get_peer_csettings(toxav, call_index, 0, transSettings); + if (err != ErrorNone) + { + qWarning() << "Core::onAvStarting: error getting call type"; + delete transSettings; + return; + } + + if (transSettings->call_type == TypeVideo) { qDebug() << QString("Core: AV starting from %1 with video").arg(friendId); prepareCall(friendId, call_index, toxav, true); @@ -1125,6 +1154,8 @@ void Core::onAvStarting(void* _toxav, int32_t call_index, void* core) prepareCall(friendId, call_index, toxav, false); emit static_cast(core)->avStarting(friendId, call_index, false); } + + delete transSettings; } void Core::onAvEnding(void* _toxav, int32_t call_index, void* core) @@ -1181,6 +1212,7 @@ void Core::onAvPeerTimeout(void* _toxav, int32_t call_index, void* core) void Core::onAvMediaChange(void*, int32_t, void*) { // HALP, PLS COMPLETE MEH + qWarning() << "If you see this, please complain on GitHub about seeing me! (Don't forget to say what caused me!)"; } void Core::answerCall(int callId) @@ -1191,17 +1223,28 @@ void Core::answerCall(int callId) qWarning() << "Core: Received invalid AV answer peer ID"; return; } - int transType = toxav_get_peer_transmission_type(toxav, callId, 0); - if (transType == TypeVideo) + + ToxAvCSettings* transSettings = new ToxAvCSettings; + int err = toxav_get_peer_csettings(toxav, callId, 0, transSettings); + if (err != ErrorNone) + { + qWarning() << "Core::answerCall: error getting call settings"; + delete transSettings; + return; + } + + if (transSettings->call_type == TypeVideo) { qDebug() << QString("Core: answering call %1 with video").arg(callId); - toxav_answer(toxav, callId, TypeVideo); + toxav_answer(toxav, callId, transSettings); } else { qDebug() << QString("Core: answering call %1 without video").arg(callId); - toxav_answer(toxav, callId, TypeAudio); + toxav_answer(toxav, callId, transSettings); } + + delete transSettings; } void Core::hangupCall(int callId) @@ -1214,16 +1257,21 @@ void Core::hangupCall(int callId) void Core::startCall(int friendId, bool video) { int callId; + ToxAvCSettings cSettings = av_DefaultSettings; + cSettings.max_video_width = TOXAV_MAX_VIDEO_WIDTH; + cSettings.max_video_height = TOXAV_MAX_VIDEO_HEIGHT; if (video) { qDebug() << QString("Core: Starting new call with %1 with video").arg(friendId); - toxav_call(toxav, &callId, friendId, TypeVideo, TOXAV_RINGING_TIME); + cSettings.call_type = TypeVideo; + toxav_call(toxav, &callId, friendId, &cSettings, TOXAV_RINGING_TIME); calls[callId].videoEnabled=true; } else { qDebug() << QString("Core: Starting new call with %1 without video").arg(friendId); - toxav_call(toxav, &callId, friendId, TypeAudio, TOXAV_RINGING_TIME); + cSettings.call_type = TypeAudio; + toxav_call(toxav, &callId, friendId, &cSettings, TOXAV_RINGING_TIME); calls[callId].videoEnabled=false; } } @@ -1240,11 +1288,13 @@ void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled qDebug() << QString("Core: preparing call %1").arg(callId); calls[callId].callId = callId; calls[callId].friendId = friendId; + // the following three lines are also now redundant from startCall, but are + // necessary there for outbound and here for inbound calls[callId].codecSettings = av_DefaultSettings; calls[callId].codecSettings.max_video_width = TOXAV_MAX_VIDEO_WIDTH; calls[callId].codecSettings.max_video_height = TOXAV_MAX_VIDEO_HEIGHT; calls[callId].videoEnabled = videoEnabled; - toxav_prepare_transmission(toxav, callId, &calls[callId].codecSettings, videoEnabled); + toxav_prepare_transmission(toxav, callId, av_jbufdc, av_VADd, videoEnabled); // Prepare output QAudioFormat format; diff --git a/core.h b/core.h index 8de39b97e..819171d8d 100644 --- a/core.h +++ b/core.h @@ -100,7 +100,7 @@ public: QAudioOutput* audioOutput; QAudioInput* audioInput; QIODevice* audioInputDevice; - ToxAvCodecSettings codecSettings; + ToxAvCSettings codecSettings; QTimer *sendAudioTimer, *sendVideoTimer; int callId; int friendId; From 84a3841122c59baca3e1650daeceed7c3cea9105 Mon Sep 17 00:00:00 2001 From: Bill Winslow Date: Sun, 27 Jul 2014 19:20:41 -0500 Subject: [PATCH 013/149] fix segfault on lack of audio formats --- core.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/core.cpp b/core.cpp index 1497eda66..612560fef 100644 --- a/core.cpp +++ b/core.cpp @@ -1352,6 +1352,11 @@ void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled Widget::getInstance()->getCamera()->suscribe(); } + else if (calls[callId].audioInput == nullptr && calls[callId].audioOutput == nullptr) + { + qWarning() << "Audio only call can neither play nor record audio, killing call"; + toxav_hangup(toxav, callId); + } } void Core::cleanupCall(int callId) @@ -1376,7 +1381,7 @@ void Core::cleanupCall(int callId) void Core::playCallAudio(ToxAv*, int32_t callId, int16_t *data, int length) { - if (!calls[callId].active) + if (!calls[callId].active || calls[callId].audioOutput == nullptr) return; calls[callId].audioBuffer.write((char*)data, length*2); int state = calls[callId].audioOutput->state(); @@ -1392,7 +1397,7 @@ void Core::playCallAudio(ToxAv*, int32_t callId, int16_t *data, int length) void Core::sendCallAudio(int callId, ToxAv* toxav) { - if (!calls[callId].active) + if (!calls[callId].active || calls[callId].audioInput == nullptr) return; int framesize = (calls[callId].codecSettings.audio_frame_duration * calls[callId].codecSettings.audio_sample_rate) / 1000; uint8_t buf[framesize*2], dest[framesize*2]; From f9cc5dbccd09dd2e9b379ade1dbdd545cb75e6d1 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 29 Jul 2014 10:50:39 +0200 Subject: [PATCH 014/149] smooth scaling --- smileypack.cpp | 48 ++++++++++++++++++++++++++++++++---------------- smileypack.h | 8 ++++++-- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/smileypack.cpp b/smileypack.cpp index 52fb3eaac..4ff7a90e9 100644 --- a/smileypack.cpp +++ b/smileypack.cpp @@ -37,15 +37,15 @@ SmileyPack& SmileyPack::getInstance() bool SmileyPack::load(const QString& filename) { // discard old data - lookupTable.clear(); - QDir::setSearchPaths("smiley", QStringList()); + assignmentTable.clear(); + cache.clear(); // open emoticons.xml QFile xmlFile(filename); if(!xmlFile.open(QIODevice::ReadOnly)) return false; // cannot open file - /* parse the cfg document + /* parse the cfg file * sample: * * @@ -72,22 +72,19 @@ bool SmileyPack::load(const QString& filename) while (!stringElement.isNull()) { QString rune = stringElement.text(); - lookupTable.insert(rune, file); // add it to the map + assignmentTable.insert(rune, file); stringElement = stringElement.nextSibling().toElement(); } } - // Rich Text makes use of Qt's resource system, so - // let Qt know about our smilies - QFileInfo info(filename); - QDir::setSearchPaths("smiley", QStringList() << info.absolutePath()); + path = QFileInfo(filename).absolutePath(); // success! return true; } -QString SmileyPack::replaceEmoticons(const QString &msg) const +QString SmileyPack::replaceEmoticons(const QString &msg) { QString out = msg; QRegExp exp("\\S*"); // matches words @@ -99,16 +96,17 @@ QString SmileyPack::replaceEmoticons(const QString &msg) const while (index >= 0) { QString key = exp.cap(); - if (lookupTable.contains(key)) + if (assignmentTable.contains(key)) { - QString width = QString::number(16); - QString height = QString::number(16); + QString file = assignmentTable[key]; + if (!cache.contains(file)) { + loadSmiley(file); + } - QString img = lookupTable[key]; - QString imgRt = ""; + QString imgRichText = ""; - out.replace(index + offset, key.length(), imgRt); - offset += imgRt.length() - key.length(); + out.replace(index + offset, key.length(), imgRichText); + offset += imgRichText.length() - key.length(); } index = msg.indexOf(exp, index + exp.matchedLength() + 1); } @@ -116,6 +114,24 @@ QString SmileyPack::replaceEmoticons(const QString &msg) const return out; } +void SmileyPack::loadSmiley(const QString &name) +{ + QSize size(16, 16); // TODO: adapt to text size + QString filename = path + "/" + name; + QImage img(filename); + + if (!img.isNull()) + { + QImage scaledImg = img.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation); + + QByteArray scaledImgData; + QBuffer buffer(&scaledImgData); + scaledImg.save(&buffer, "PNG"); + + cache.insert(name, scaledImgData.toBase64()); + } +} + void SmileyPack::onSmileyPackChanged() { load(Settings::getInstance().getSmileyPack()); diff --git a/smileypack.h b/smileypack.h index 1c7db70b6..b0395bc1c 100644 --- a/smileypack.h +++ b/smileypack.h @@ -29,7 +29,7 @@ public: static SmileyPack& getInstance(); bool load(const QString &filename); - QString replaceEmoticons(const QString& msg) const; + QString replaceEmoticons(const QString& msg); private slots: void onSmileyPackChanged(); @@ -39,7 +39,11 @@ private: SmileyPack(SmileyPack&) = delete; SmileyPack& operator=(const SmileyPack&) = delete; - QHash lookupTable; // matches an emoticon to its corresponding smiley + void loadSmiley(const QString& name); + + QHash assignmentTable; // matches an emoticon to its corresponding smiley + QHash cache; + QString path; // directory containing the cfg file }; #endif // SMILEYPACK_H From 57a7324d41b505effe673c728849647e250334b9 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 29 Jul 2014 10:59:58 +0200 Subject: [PATCH 015/149] fast concatenation --- smileypack.cpp | 4 ++-- smileypack.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/smileypack.cpp b/smileypack.cpp index 4ff7a90e9..33339f018 100644 --- a/smileypack.cpp +++ b/smileypack.cpp @@ -103,7 +103,7 @@ QString SmileyPack::replaceEmoticons(const QString &msg) loadSmiley(file); } - QString imgRichText = ""; + QString imgRichText = ""; out.replace(index + offset, key.length(), imgRichText); offset += imgRichText.length() - key.length(); @@ -117,7 +117,7 @@ QString SmileyPack::replaceEmoticons(const QString &msg) void SmileyPack::loadSmiley(const QString &name) { QSize size(16, 16); // TODO: adapt to text size - QString filename = path + "/" + name; + QString filename = path % "/" % name; QImage img(filename); if (!img.isNull()) diff --git a/smileypack.h b/smileypack.h index b0395bc1c..6ae7f7260 100644 --- a/smileypack.h +++ b/smileypack.h @@ -42,7 +42,7 @@ private: void loadSmiley(const QString& name); QHash assignmentTable; // matches an emoticon to its corresponding smiley - QHash cache; + QHash cache; QString path; // directory containing the cfg file }; From 133ff15154af77d670f5493002874a6296d330b7 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 29 Jul 2014 11:22:47 +0200 Subject: [PATCH 016/149] cleanup --- smileypack.cpp | 15 +++++++-------- smileypack.h | 4 ++-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/smileypack.cpp b/smileypack.cpp index 33339f018..16029515d 100644 --- a/smileypack.cpp +++ b/smileypack.cpp @@ -84,10 +84,9 @@ bool SmileyPack::load(const QString& filename) return true; } -QString SmileyPack::replaceEmoticons(const QString &msg) +QString SmileyPack::replaceEmoticons(QString msg) { - QString out = msg; - QRegExp exp("\\S*"); // matches words + QRegExp exp("\\S+"); // matches words int index = msg.indexOf(exp); int offset = 0; @@ -105,19 +104,19 @@ QString SmileyPack::replaceEmoticons(const QString &msg) QString imgRichText = ""; - out.replace(index + offset, key.length(), imgRichText); - offset += imgRichText.length() - key.length(); + msg.replace(index + offset, key.length(), imgRichText); + index += imgRichText.length() - key.length(); } - index = msg.indexOf(exp, index + exp.matchedLength() + 1); + index = msg.indexOf(exp, index + key.length()); } - return out; + return msg; } void SmileyPack::loadSmiley(const QString &name) { QSize size(16, 16); // TODO: adapt to text size - QString filename = path % "/" % name; + QString filename = path % '/' % name; QImage img(filename); if (!img.isNull()) diff --git a/smileypack.h b/smileypack.h index 6ae7f7260..155aa2a48 100644 --- a/smileypack.h +++ b/smileypack.h @@ -29,7 +29,7 @@ public: static SmileyPack& getInstance(); bool load(const QString &filename); - QString replaceEmoticons(const QString& msg); + QString replaceEmoticons(QString msg); private slots: void onSmileyPackChanged(); @@ -42,7 +42,7 @@ private: void loadSmiley(const QString& name); QHash assignmentTable; // matches an emoticon to its corresponding smiley - QHash cache; + QHash cache; // base64 representation of a smiley QString path; // directory containing the cfg file }; From b5ed0da09b892a53ede0a594d5ae5270fc603c01 Mon Sep 17 00:00:00 2001 From: Ansa89 Date: Tue, 29 Jul 2014 12:08:14 +0200 Subject: [PATCH 017/149] Italian translation: update --- translations/it.qm | Bin 5826 -> 6298 bytes translations/it.ts | 39 ++++++++++++++++++++++++++++----------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/translations/it.qm b/translations/it.qm index db9dc34f8061ef1e47ed6ea048c0eb17a743e420..4c8c5f1eac59191ad08d918872f408b5455c907f 100644 GIT binary patch delta 653 zcma)1O=uHQ7@WkUN!w&&vuP+8I4K0x2biQf@m=r+zZIzZ$BCQsf6G9R)0Ym2%#R<1{Z-Jim# z8z%c_zC05iE&8j4u>RD4zc;M!_kR@f`gANbwgeMYHhjuL$<6!++MnjT4W49oc^VjA)pAGkjBRPT zM;6h7c6?8v+g_fgU7a!A70E2?du`YX=j3Nr1V;%%JKq9Wo^j6SG-21FZ~H|1)*Q zqM%Ic1`SlaxAFk*d85>n!jnqb&YUNdD^x{_n{Iucy|C=MG?iO#3ET0MELp-W2ZV;# zC{=~&I^`axb2dG8*&X^yf^Wz z9Ft(m#J6fnf>YTUC8jVi@Sb4jQk~Agz;+5k^Hs2)dfv>yATo2ZDWhAuNGeZp_+y}T z!n`RP3K$r8uJD#@nFv(Q$a_NRGSE4dK>9NS5b&Ow9m>GKy_8R8MhcLp#%DY~j)8$g ylP{ ChatForm - + Send a file Invia un file - - + + Save chat log Salva il log della chat @@ -264,53 +264,70 @@ SettingsForm - + User Settings "Headline" of the window Impostazioni - + Name Username/nick Nome - + Status Status message Stato - + (click here to copy) Click on this text to copy TID to clipboard (clicca qui per copiare) - + Test video Text on a button to test the video/webcam Prova la webcam - + Enable IPv6 (recommended) Text on a checkbox to enable IPv6 Abilita IPv6 (consigliato) - + Use translations Text on a checkbox to enable translations Abilita traduzioni - + Make Tox portable Text on a checkbox to make qTox a portable application Rendi qTox portabile + + + Save settings to the working directory instead of the usual conf dir + describes makeToxPortable checkbox + Slava le impostazioni nella directory di lavoro corrente, invece della directory di default + + + + Smiley Pack + Text on smiley pack label + Emoticons + + + + Select smiley pack + Scegli pacchetto emoticons + Widget From 0d493f4bcfae834afdba466c502e11d3bedbe45b Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 30 Jul 2014 09:18:41 +0200 Subject: [PATCH 018/149] ability to detect smileyPacks --- smileypack.cpp | 22 ++++++++++++++++++++-- smileypack.h | 2 ++ widget/form/settingsform.cpp | 22 +++++++--------------- widget/form/settingsform.h | 6 +++--- 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/smileypack.cpp b/smileypack.cpp index 16029515d..822f263c0 100644 --- a/smileypack.cpp +++ b/smileypack.cpp @@ -34,6 +34,25 @@ SmileyPack& SmileyPack::getInstance() return smileyPack; } +QStringList SmileyPack::listSmileyPacks(const QString &path) +{ + QStringList smileyPacks; + + QDir dir(path); + foreach (const QString& subdirectory, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) + { + dir.cd(subdirectory); + + QFileInfoList entries = dir.entryInfoList(QStringList() << "emoticons.xml", QDir::Files); + if (entries.size() > 0) // does it contain a file called emoticons.xml? + smileyPacks << QDir(QCoreApplication::applicationDirPath()).relativeFilePath(entries[0].absoluteFilePath()); + + dir.cdUp(); + } + + return smileyPacks; +} + bool SmileyPack::load(const QString& filename) { // discard old data @@ -89,7 +108,6 @@ QString SmileyPack::replaceEmoticons(QString msg) QRegExp exp("\\S+"); // matches words int index = msg.indexOf(exp); - int offset = 0; // if a word is key of a smiley, replace it by its corresponding image in Rich Text while (index >= 0) @@ -104,7 +122,7 @@ QString SmileyPack::replaceEmoticons(QString msg) QString imgRichText = ""; - msg.replace(index + offset, key.length(), imgRichText); + msg.replace(index, key.length(), imgRichText); index += imgRichText.length() - key.length(); } index = msg.indexOf(exp, index + key.length()); diff --git a/smileypack.h b/smileypack.h index 155aa2a48..7273ac2aa 100644 --- a/smileypack.h +++ b/smileypack.h @@ -31,6 +31,8 @@ public: bool load(const QString &filename); QString replaceEmoticons(QString msg); + static QStringList listSmileyPacks(const QString& path); + private slots: void onSmileyPackChanged(); diff --git a/widget/form/settingsform.cpp b/widget/form/settingsform.cpp index 9d2c71d00..1b278c961 100644 --- a/widget/form/settingsform.cpp +++ b/widget/form/settingsform.cpp @@ -17,6 +17,7 @@ #include "settingsform.h" #include "widget/widget.h" #include "settings.h" +#include "smileypack.h" #include #include #include @@ -52,7 +53,8 @@ SettingsForm::SettingsForm() makeToxPortable.setChecked(Settings::getInstance().getMakeToxPortable()); smileyPackLabel.setText(tr("Smiley Pack", "Text on smiley pack label")); - smileyPackFilename.setText(Settings::getInstance().getSmileyPack()); + smileyPackBrowser.addItems(SmileyPack::listSmileyPacks("./smileys")); + smileyPackBrowser.setCurrentText(Settings::getInstance().getSmileyPack()); main->setLayout(&layout); layout.addWidget(&nameLabel); @@ -66,8 +68,7 @@ SettingsForm::SettingsForm() layout.addWidget(&useTranslations); layout.addWidget(&makeToxPortable); layout.addWidget(&smileyPackLabel); - layout.addWidget(&smileyPackFilename); - layout.addWidget(&smileyBrowseFileButton); + layout.addWidget(&smileyPackBrowser); layout.addStretch(); head->setLayout(&headLayout); @@ -78,7 +79,7 @@ SettingsForm::SettingsForm() connect(&useTranslations, SIGNAL(stateChanged(int)), this, SLOT(onUseTranslationUpdated())); connect(&makeToxPortable, SIGNAL(stateChanged(int)), this, SLOT(onMakeToxPortableUpdated())); connect(&idLabel, SIGNAL(clicked()), this, SLOT(copyIdClicked())); - connect(&smileyBrowseFileButton, SIGNAL(clicked()), this, SLOT(onBrowseSmileyFilename())); + connect(&smileyPackBrowser, SIGNAL(currentTextChanged(QString)), this, SLOT(onSmileyBrowserTextChanged(QString))); } SettingsForm::~SettingsForm() @@ -126,16 +127,7 @@ void SettingsForm::onMakeToxPortableUpdated() Settings::getInstance().setMakeToxPortable(makeToxPortable.isChecked()); } -void SettingsForm::onBrowseSmileyFilename() +void SettingsForm::onSmileyBrowserTextChanged(const QString &filename) { - // directory containing a file called emoticons.xml - QString filename = QFileDialog::getOpenFileName(nullptr, tr("Select smiley pack"), QDir::currentPath(), "emoticons.xml"); - - // get relative path to app's local directory - QString relPath = QDir::current().relativeFilePath(filename); - - // save - Settings::getInstance().setSmileyPack(relPath); - smileyPackFilename.setText(relPath); + Settings::getInstance().setSmileyPack(filename); } - diff --git a/widget/form/settingsform.h b/widget/form/settingsform.h index 5cf2c5532..5a6bbd93a 100644 --- a/widget/form/settingsform.h +++ b/widget/form/settingsform.h @@ -26,6 +26,7 @@ #include #include #include +#include #include "widget/tool/clickablelabel.h" #include "ui_widget.h" #include "widget/selfcamview.h" @@ -47,7 +48,7 @@ private slots: void onEnableIPv6Updated(); void onUseTranslationUpdated(); void onMakeToxPortableUpdated(); - void onBrowseSmileyFilename(); + void onSmileyBrowserTextChanged(const QString& filename); void copyIdClicked(); private: @@ -58,8 +59,7 @@ private: QCheckBox enableIPv6, useTranslations, makeToxPortable; QVBoxLayout layout, headLayout; QWidget *main, *head; - QLineEdit smileyPackFilename; - QToolButton smileyBrowseFileButton; + QComboBox smileyPackBrowser; public: QLineEdit name, statusText; }; From f7a357d671ca6ecc545ccde614fbfe1f9d82d247 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 30 Jul 2014 22:07:26 +0200 Subject: [PATCH 019/149] wire up the emote button --- smileypack.cpp | 29 ++++++++++++++++++++-- smileypack.h | 7 +++++- widget/form/chatform.cpp | 53 ++++++++++++++++++++++++++++++++++++++++ widget/form/chatform.h | 2 ++ 4 files changed, 88 insertions(+), 3 deletions(-) diff --git a/smileypack.cpp b/smileypack.cpp index 822f263c0..1e73ea2d0 100644 --- a/smileypack.cpp +++ b/smileypack.cpp @@ -58,6 +58,7 @@ bool SmileyPack::load(const QString& filename) // discard old data assignmentTable.clear(); cache.clear(); + emoticons.clear(); // open emoticons.xml QFile xmlFile(filename); @@ -88,13 +89,17 @@ bool SmileyPack::load(const QString& filename) QString file = emoticonElements.at(i).attributes().namedItem("file").nodeValue(); QDomElement stringElement = emoticonElements.at(i).firstChildElement("string"); + QStringList emoticonSet; // { ":)", ":-)" } etc. + while (!stringElement.isNull()) { - QString rune = stringElement.text(); - assignmentTable.insert(rune, file); + QString emoticon = stringElement.text(); + assignmentTable.insert(emoticon, file); + emoticonSet.push_back(emoticon); stringElement = stringElement.nextSibling().toElement(); } + emoticons.push_back(emoticonSet); } path = QFileInfo(filename).absolutePath(); @@ -131,6 +136,26 @@ QString SmileyPack::replaceEmoticons(QString msg) return msg; } +QList SmileyPack::getEmoticons() const +{ + return emoticons; +} + +QString SmileyPack::getRichText(const QString &key) +{ + QString file = assignmentTable[key]; + if (!cache.contains(file)) { + loadSmiley(file); + } + + return ""; +} + +QIcon SmileyPack::getIcon(const QString &key) +{ + return QIcon(path + '/' + assignmentTable[key]); +} + void SmileyPack::loadSmiley(const QString &name) { QSize size(16, 16); // TODO: adapt to text size diff --git a/smileypack.h b/smileypack.h index 7273ac2aa..69ea898cf 100644 --- a/smileypack.h +++ b/smileypack.h @@ -18,8 +18,9 @@ #define SMILEYPACK_H #include -#include #include +#include +#include //maps emoticons to smileys class SmileyPack : public QObject @@ -30,6 +31,9 @@ public: bool load(const QString &filename); QString replaceEmoticons(QString msg); + QList getEmoticons() const; + QString getRichText(const QString& key); + QIcon getIcon(const QString& key); static QStringList listSmileyPacks(const QString& path); @@ -46,6 +50,7 @@ private: QHash assignmentTable; // matches an emoticon to its corresponding smiley QHash cache; // base64 representation of a smiley QString path; // directory containing the cfg file + QList emoticons; }; #endif // SMILEYPACK_H diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index 07e7d9e4b..896f1c960 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -25,6 +25,8 @@ #include #include #include +#include +#include ChatForm::ChatForm(Friend* chatFriend) : f(chatFriend), curRow{0}, lockSliderToBottom{true} @@ -188,6 +190,7 @@ ChatForm::ChatForm(Friend* chatFriend) connect(msgEdit, SIGNAL(enterPressed()), this, SLOT(onSendTriggered())); connect(chatArea->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), this, SLOT(onSliderRangeChanged())); connect(chatArea, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onChatContextMenuRequested(QPoint))); + connect(emoteButton, SIGNAL(clicked()), this, SLOT(onEmoteButtonClicked())); } ChatForm::~ChatForm() @@ -652,3 +655,53 @@ void ChatForm::onSaveLogClicked() file.write(log.toUtf8()); file.close(); } + +void ChatForm::onEmoteButtonClicked() +{ + QList emoticons = SmileyPack::getInstance().getEmoticons(); + + QMenu menu; + QGridLayout* gridLayout = new QGridLayout; + menu.setLayout(gridLayout); + + int colCount = sqrt(emoticons.size()) + 1; + int row = 0; + int col = 0; + for (QStringList set : emoticons) + { + QPushButton* button = new QPushButton; + button->setIcon(SmileyPack::getInstance().getIcon(set[0])); + button->setToolTip(set.join(" ")); + button->setProperty("sequence", set[0]); + connect(button, &QPushButton::clicked, this, &ChatForm::onAddEmote); + + gridLayout->addWidget(button, row, ++col); + if (col >= colCount) + { + col = 0; + row++; + } + } + + QWidget* sender = qobject_cast(QObject::sender()); + if (sender) + { + QPoint pos(gridLayout->totalSizeHint().width() / 2, gridLayout->totalSizeHint().height()); + menu.exec(sender->mapToGlobal(-pos)); + } +} + +void ChatForm::onAddEmote() +{ + // hide the QMenu + QMenu* menu = qobject_cast(QObject::sender()->parent()); + if (menu) + menu->hide(); + + // insert the emoticon + QWidget* sender = qobject_cast(QObject::sender()); + if (sender) + msgEdit->insertPlainText(' ' + sender->property("sequence").toString() + ' '); + + msgEdit->setFocus(); // refocus so that you can continue typing +} diff --git a/widget/form/chatform.h b/widget/form/chatform.h index d6d44143b..a58dc3237 100644 --- a/widget/form/chatform.h +++ b/widget/form/chatform.h @@ -83,6 +83,8 @@ private slots: void onCancelCallTriggered(); void onChatContextMenuRequested(QPoint pos); void onSaveLogClicked(); + void onEmoteButtonClicked(); + void onAddEmote(); private: Friend* f; From f0306bb25fac0747b62e167ed3361212f8fa4f51 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Thu, 31 Jul 2014 16:08:44 +0200 Subject: [PATCH 020/149] cleanup --- smileypack.cpp | 52 ++++++++++++++++++++++++---------------- smileypack.h | 16 ++++++------- widget/form/chatform.cpp | 2 +- 3 files changed, 40 insertions(+), 30 deletions(-) diff --git a/smileypack.cpp b/smileypack.cpp index 1e73ea2d0..0ccc87af0 100644 --- a/smileypack.cpp +++ b/smileypack.cpp @@ -56,9 +56,10 @@ QStringList SmileyPack::listSmileyPacks(const QString &path) bool SmileyPack::load(const QString& filename) { // discard old data - assignmentTable.clear(); + filenameTable.clear(); cache.clear(); emoticons.clear(); + path.clear(); // open emoticons.xml QFile xmlFile(filename); @@ -80,6 +81,8 @@ bool SmileyPack::load(const QString& filename) * */ + path = QFileInfo(filename).absolutePath(); + QDomDocument doc; doc.setContent(xmlFile.readAll()); @@ -94,16 +97,15 @@ bool SmileyPack::load(const QString& filename) while (!stringElement.isNull()) { QString emoticon = stringElement.text(); - assignmentTable.insert(emoticon, file); + filenameTable.insert(emoticon, file); emoticonSet.push_back(emoticon); + cacheSmiley(file); // preload all smileys stringElement = stringElement.nextSibling().toElement(); } emoticons.push_back(emoticonSet); } - path = QFileInfo(filename).absolutePath(); - // success! return true; } @@ -118,14 +120,9 @@ QString SmileyPack::replaceEmoticons(QString msg) while (index >= 0) { QString key = exp.cap(); - if (assignmentTable.contains(key)) + if (filenameTable.contains(key)) { - QString file = assignmentTable[key]; - if (!cache.contains(file)) { - loadSmiley(file); - } - - QString imgRichText = ""; + QString imgRichText = getSmileyAsRichText(key); msg.replace(index, key.length(), imgRichText); index += imgRichText.length() - key.length(); @@ -141,22 +138,20 @@ QList SmileyPack::getEmoticons() const return emoticons; } -QString SmileyPack::getRichText(const QString &key) +QString SmileyPack::getSmileyAsRichText(const QString &key) { - QString file = assignmentTable[key]; - if (!cache.contains(file)) { - loadSmiley(file); - } - - return ""; + return ""; } QIcon SmileyPack::getIcon(const QString &key) { - return QIcon(path + '/' + assignmentTable[key]); + QPixmap pm; + pm.loadFromData(getCachedSmiley(key), "PNG"); + + return QIcon(pm); } -void SmileyPack::loadSmiley(const QString &name) +void SmileyPack::cacheSmiley(const QString &name) { QSize size(16, 16); // TODO: adapt to text size QString filename = path % '/' % name; @@ -170,10 +165,25 @@ void SmileyPack::loadSmiley(const QString &name) QBuffer buffer(&scaledImgData); scaledImg.save(&buffer, "PNG"); - cache.insert(name, scaledImgData.toBase64()); + cache.insert(name, scaledImgData); } } +QByteArray SmileyPack::getCachedSmiley(const QString &key) +{ + // valid key? + if (!filenameTable.contains(key)) + return QByteArray(); + + // cache it if needed + QString file = filenameTable.value(key); + if (!cache.contains(file)) { + cacheSmiley(file); + } + + return cache.value(file); +} + void SmileyPack::onSmileyPackChanged() { load(Settings::getInstance().getSmileyPack()); diff --git a/smileypack.h b/smileypack.h index 69ea898cf..b315d60d6 100644 --- a/smileypack.h +++ b/smileypack.h @@ -28,14 +28,13 @@ class SmileyPack : public QObject Q_OBJECT public: static SmileyPack& getInstance(); + static QStringList listSmileyPacks(const QString& path); bool load(const QString &filename); QString replaceEmoticons(QString msg); QList getEmoticons() const; - QString getRichText(const QString& key); - QIcon getIcon(const QString& key); - - static QStringList listSmileyPacks(const QString& path); + QString getSmileyAsRichText(const QString& key); + QIcon getIcon(const QString& key); private slots: void onSmileyPackChanged(); @@ -45,11 +44,12 @@ private: SmileyPack(SmileyPack&) = delete; SmileyPack& operator=(const SmileyPack&) = delete; - void loadSmiley(const QString& name); + void cacheSmiley(const QString& name); + QByteArray getCachedSmiley(const QString& key); - QHash assignmentTable; // matches an emoticon to its corresponding smiley - QHash cache; // base64 representation of a smiley - QString path; // directory containing the cfg file + QHash filenameTable; // matches an emoticon to its corresponding smiley ie. ":)" -> "happy.png" + QHash cache; // (scaled) representation of a smiley ie. "happy.png" -> data + QString path; // directory containing the cfg and image files QList emoticons; }; diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index 896f1c960..7dfdaf1d4 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -667,7 +667,7 @@ void ChatForm::onEmoteButtonClicked() int colCount = sqrt(emoticons.size()) + 1; int row = 0; int col = 0; - for (QStringList set : emoticons) + for (const QStringList& set : emoticons) { QPushButton* button = new QPushButton; button->setIcon(SmileyPack::getInstance().getIcon(set[0])); From 6fed143048b9cd7708bc4812bb7ea7e02827ebf2 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Thu, 31 Jul 2014 17:36:55 +0200 Subject: [PATCH 021/149] cleanup --- smileypack.cpp | 26 +++++++++++++++----------- smileypack.h | 12 ++++++------ widget/form/chatform.cpp | 4 ++-- widget/form/settingsform.cpp | 10 ++++++---- widget/form/settingsform.h | 2 +- 5 files changed, 30 insertions(+), 24 deletions(-) diff --git a/smileypack.cpp b/smileypack.cpp index 0ccc87af0..7dca525dc 100644 --- a/smileypack.cpp +++ b/smileypack.cpp @@ -34,9 +34,9 @@ SmileyPack& SmileyPack::getInstance() return smileyPack; } -QStringList SmileyPack::listSmileyPacks(const QString &path) +QList > SmileyPack::listSmileyPacks(const QString &path) { - QStringList smileyPacks; + QList > smileyPacks; QDir dir(path); foreach (const QString& subdirectory, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) @@ -45,7 +45,11 @@ QStringList SmileyPack::listSmileyPacks(const QString &path) QFileInfoList entries = dir.entryInfoList(QStringList() << "emoticons.xml", QDir::Files); if (entries.size() > 0) // does it contain a file called emoticons.xml? - smileyPacks << QDir(QCoreApplication::applicationDirPath()).relativeFilePath(entries[0].absoluteFilePath()); + { + QString packageName = dir.dirName(); + QString relPath = QDir(QCoreApplication::applicationDirPath()).relativeFilePath(entries[0].absoluteFilePath()); + smileyPacks << QPair(packageName, relPath); + } dir.cdUp(); } @@ -57,7 +61,7 @@ bool SmileyPack::load(const QString& filename) { // discard old data filenameTable.clear(); - cache.clear(); + imgCache.clear(); emoticons.clear(); path.clear(); @@ -110,7 +114,7 @@ bool SmileyPack::load(const QString& filename) return true; } -QString SmileyPack::replaceEmoticons(QString msg) +QString SmileyPack::smileyfied(QString msg) { QRegExp exp("\\S+"); // matches words @@ -122,7 +126,7 @@ QString SmileyPack::replaceEmoticons(QString msg) QString key = exp.cap(); if (filenameTable.contains(key)) { - QString imgRichText = getSmileyAsRichText(key); + QString imgRichText = getAsRichText(key); msg.replace(index, key.length(), imgRichText); index += imgRichText.length() - key.length(); @@ -138,12 +142,12 @@ QList SmileyPack::getEmoticons() const return emoticons; } -QString SmileyPack::getSmileyAsRichText(const QString &key) +QString SmileyPack::getAsRichText(const QString &key) { return ""; } -QIcon SmileyPack::getIcon(const QString &key) +QIcon SmileyPack::getAsIcon(const QString &key) { QPixmap pm; pm.loadFromData(getCachedSmiley(key), "PNG"); @@ -165,7 +169,7 @@ void SmileyPack::cacheSmiley(const QString &name) QBuffer buffer(&scaledImgData); scaledImg.save(&buffer, "PNG"); - cache.insert(name, scaledImgData); + imgCache.insert(name, scaledImgData); } } @@ -177,11 +181,11 @@ QByteArray SmileyPack::getCachedSmiley(const QString &key) // cache it if needed QString file = filenameTable.value(key); - if (!cache.contains(file)) { + if (!imgCache.contains(file)) { cacheSmiley(file); } - return cache.value(file); + return imgCache.value(file); } void SmileyPack::onSmileyPackChanged() diff --git a/smileypack.h b/smileypack.h index b315d60d6..dd315ab94 100644 --- a/smileypack.h +++ b/smileypack.h @@ -28,13 +28,13 @@ class SmileyPack : public QObject Q_OBJECT public: static SmileyPack& getInstance(); - static QStringList listSmileyPacks(const QString& path); + static QList> listSmileyPacks(const QString& path); bool load(const QString &filename); - QString replaceEmoticons(QString msg); + QString smileyfied(QString msg); QList getEmoticons() const; - QString getSmileyAsRichText(const QString& key); - QIcon getIcon(const QString& key); + QString getAsRichText(const QString& key); + QIcon getAsIcon(const QString& key); private slots: void onSmileyPackChanged(); @@ -48,9 +48,9 @@ private: QByteArray getCachedSmiley(const QString& key); QHash filenameTable; // matches an emoticon to its corresponding smiley ie. ":)" -> "happy.png" - QHash cache; // (scaled) representation of a smiley ie. "happy.png" -> data + QHash imgCache; // (scaled) representation of a smiley ie. "happy.png" -> data + QList emoticons; // {{ ":)", ":-)" }, {":(", ...}, ... } QString path; // directory containing the cfg and image files - QList emoticons; }; #endif // SMILEYPACK_H diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index 7dfdaf1d4..398579318 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -242,7 +242,7 @@ void ChatForm::addFriendMessage(QString message) void ChatForm::addMessage(QString author, QString message, QString date) { - message = SmileyPack::getInstance().replaceEmoticons(message); + message = SmileyPack::getInstance().smileyfied(message); addMessage(new QLabel(author), new QLabel(message), new QLabel(date)); } @@ -670,7 +670,7 @@ void ChatForm::onEmoteButtonClicked() for (const QStringList& set : emoticons) { QPushButton* button = new QPushButton; - button->setIcon(SmileyPack::getInstance().getIcon(set[0])); + button->setIcon(SmileyPack::getInstance().getAsIcon(set[0])); button->setToolTip(set.join(" ")); button->setProperty("sequence", set[0]); connect(button, &QPushButton::clicked, this, &ChatForm::onAddEmote); diff --git a/widget/form/settingsform.cpp b/widget/form/settingsform.cpp index 1b278c961..bc2518ede 100644 --- a/widget/form/settingsform.cpp +++ b/widget/form/settingsform.cpp @@ -53,8 +53,9 @@ SettingsForm::SettingsForm() makeToxPortable.setChecked(Settings::getInstance().getMakeToxPortable()); smileyPackLabel.setText(tr("Smiley Pack", "Text on smiley pack label")); - smileyPackBrowser.addItems(SmileyPack::listSmileyPacks("./smileys")); - smileyPackBrowser.setCurrentText(Settings::getInstance().getSmileyPack()); + for (auto entry : SmileyPack::listSmileyPacks("./smileys")) + smileyPackBrowser.addItem(entry.first, entry.second); + smileyPackBrowser.setCurrentIndex(smileyPackBrowser.findData(Settings::getInstance().getSmileyPack())); main->setLayout(&layout); layout.addWidget(&nameLabel); @@ -79,7 +80,7 @@ SettingsForm::SettingsForm() connect(&useTranslations, SIGNAL(stateChanged(int)), this, SLOT(onUseTranslationUpdated())); connect(&makeToxPortable, SIGNAL(stateChanged(int)), this, SLOT(onMakeToxPortableUpdated())); connect(&idLabel, SIGNAL(clicked()), this, SLOT(copyIdClicked())); - connect(&smileyPackBrowser, SIGNAL(currentTextChanged(QString)), this, SLOT(onSmileyBrowserTextChanged(QString))); + connect(&smileyPackBrowser, SIGNAL(currentIndexChanged(int)), this, SLOT(onSmileyBrowserIndexChanged(int))); } SettingsForm::~SettingsForm() @@ -127,7 +128,8 @@ void SettingsForm::onMakeToxPortableUpdated() Settings::getInstance().setMakeToxPortable(makeToxPortable.isChecked()); } -void SettingsForm::onSmileyBrowserTextChanged(const QString &filename) +void SettingsForm::onSmileyBrowserIndexChanged(int index) { + QString filename = smileyPackBrowser.itemData(index).toString(); Settings::getInstance().setSmileyPack(filename); } diff --git a/widget/form/settingsform.h b/widget/form/settingsform.h index 5a6bbd93a..db5a395cf 100644 --- a/widget/form/settingsform.h +++ b/widget/form/settingsform.h @@ -48,7 +48,7 @@ private slots: void onEnableIPv6Updated(); void onUseTranslationUpdated(); void onMakeToxPortableUpdated(); - void onSmileyBrowserTextChanged(const QString& filename); + void onSmileyBrowserIndexChanged(int index); void copyIdClicked(); private: From 566402a1bfafdcfd81a73b13245fc14e1c66c129 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 1 Aug 2014 14:32:51 +0200 Subject: [PATCH 022/149] a shiny new widget --- qtox.pro | 6 +- res.qrc | 3 + ui/emoticonWidget/dot_page.png | Bin 0 -> 233 bytes ui/emoticonWidget/dot_page_current.png | Bin 0 -> 263 bytes ui/emoticonWidget/emoticonWidget.css | 49 +++++++++ widget/emoticonswidget.cpp | 135 +++++++++++++++++++++++++ widget/emoticonswidget.h | 45 +++++++++ widget/form/chatform.cpp | 52 +++------- widget/form/chatform.h | 2 +- 9 files changed, 250 insertions(+), 42 deletions(-) create mode 100644 ui/emoticonWidget/dot_page.png create mode 100644 ui/emoticonWidget/dot_page_current.png create mode 100644 ui/emoticonWidget/emoticonWidget.css create mode 100644 widget/emoticonswidget.cpp create mode 100644 widget/emoticonswidget.h diff --git a/qtox.pro b/qtox.pro index f1d64f544..707599b6c 100644 --- a/qtox.pro +++ b/qtox.pro @@ -84,7 +84,8 @@ HEADERS += widget/form/addfriendform.h \ widget/camera.h \ widget/netcamview.h \ widget/tool/clickablelabel.h \ - smileypack.h + smileypack.h \ + widget/emoticonswidget.h SOURCES += \ widget/form/addfriendform.cpp \ @@ -117,4 +118,5 @@ SOURCES += \ widget/camera.cpp \ widget/netcamview.cpp \ widget/tool/clickablelabel.cpp \ - smileypack.cpp + smileypack.cpp \ + widget/emoticonswidget.cpp diff --git a/res.qrc b/res.qrc index cb2fa192b..67c2ecf50 100644 --- a/res.qrc +++ b/res.qrc @@ -111,5 +111,8 @@ ui/statusButton/menu_indicator.png translations/de.qm translations/it.qm + ui/emoticonWidget/dot_page.png + ui/emoticonWidget/dot_page_current.png + ui/emoticonWidget/emoticonWidget.css diff --git a/ui/emoticonWidget/dot_page.png b/ui/emoticonWidget/dot_page.png new file mode 100644 index 0000000000000000000000000000000000000000..c7c2aa172e2a03a298bf6f7f21c55384fc0617d4 GIT binary patch literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4u_bxCyDx`7I;J! z19e;nVMZs7*%d%R_7YEDSN3}xjO>gI1r>MZ1BJ>wT^vIsF859_>Gi%gTe~DWM4fi>6Pb literal 0 HcmV?d00001 diff --git a/ui/emoticonWidget/dot_page_current.png b/ui/emoticonWidget/dot_page_current.png new file mode 100644 index 0000000000000000000000000000000000000000..aa101903afbe49b8301478ab8d62053662ad07a4 GIT binary patch literal 263 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4u_bxCyDx`7I;J! z19e;nVMZs7*%d%R_7YEDSN3}xjBMIck2g2}0t!v>ba4!kxZHb6o9~c=h}*-@{^E`w z);b?#+7RryYeJL5W(E(ANiC`ZIqO{>9%xY7EHbHk + + 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. +*/ + +#include "emoticonswidget.h" +#include "smileypack.h" + +#include +#include +#include +#include +#include + +EmoticonsWidget::EmoticonsWidget(QWidget *parent) : + QMenu(parent) +{ + QFile f(":/ui/emoticonWidget/emoticonWidget.css"); + f.open(QFile::ReadOnly | QFile::Text); + QString pageButtonCss = f.readAll(); + setStyleSheet(pageButtonCss); + + setLayout(&layout); + layout.addWidget(&stack); + + QWidget* pageButtonsContainer = new QWidget; + QHBoxLayout* buttonLayout = new QHBoxLayout; + pageButtonsContainer->setLayout(buttonLayout); + + layout.addWidget(pageButtonsContainer); + + const int maxCols = 5; + const int maxRows = 3; + const int itemsPerPage = maxRows * maxCols; + + const QList& emoticons = SmileyPack::getInstance().getEmoticons(); + int itemCount = emoticons.size(); + int pageCount = (itemCount / itemsPerPage) + 1; + int currPage = 0; + int currItem = 0; + int row = 0; + int col = 0; + + // create pages + buttonLayout->addStretch(); + for (int i = 0; i < pageCount; i++) + { + QGridLayout* pageLayout = new QGridLayout; + pageLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), maxRows, 0); + pageLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, maxCols); + + QWidget* page = new QWidget; + page->setLayout(pageLayout); + stack.addWidget(page); + + QRadioButton* pageButton = new QRadioButton; + pageButton->setProperty("pageIndex", i); + pageButton->setChecked(i == 0); + buttonLayout->addWidget(pageButton); + + connect(pageButton, &QRadioButton::clicked, this, &EmoticonsWidget::onPageButtonClicked); + } + buttonLayout->addStretch(); + + for (const QStringList& set : emoticons) + { + QPushButton* button = new QPushButton; + button->setIcon(SmileyPack::getInstance().getAsIcon(set[0])); + button->setToolTip(set.join(" ")); + button->setProperty("sequence", set[0]); + button->setFlat(true); + + connect(button, &QPushButton::clicked, this, &EmoticonsWidget::onSmileyClicked); + + qobject_cast(stack.widget(currPage)->layout())->addWidget(button, row, col); + + col++; + currItem++; + + // next row + if (col >= maxCols) + { + col = 0; + row++; + } + + // next page + if (currItem >= itemsPerPage) + { + row = 0; + currItem = 0; + currPage++; + } + } + + // calculates sizeHint + layout.activate(); +} + +void EmoticonsWidget::onSmileyClicked() +{ + // hide the QMenu + QMenu::hide(); + + // emit insert emoticon + QWidget* sender = qobject_cast(QObject::sender()); + if (sender) + emit insertEmoticon(' ' + sender->property("sequence").toString() + ' '); +} + +void EmoticonsWidget::onPageButtonClicked() +{ + QWidget* sender = qobject_cast(QObject::sender()); + if (sender) + { + int page = sender->property("pageIndex").toInt(); + stack.setCurrentIndex(page); + } +} + +QSize EmoticonsWidget::sizeHint() const +{ + return layout.sizeHint(); +} diff --git a/widget/emoticonswidget.h b/widget/emoticonswidget.h new file mode 100644 index 000000000..559fb7443 --- /dev/null +++ b/widget/emoticonswidget.h @@ -0,0 +1,45 @@ +/* + Copyright (C) 2014 by Project Tox + + 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. +*/ + +#ifndef EMOTICONSWIDGET_H +#define EMOTICONSWIDGET_H + +#include +#include +#include + +class EmoticonsWidget : public QMenu +{ + Q_OBJECT +public: + explicit EmoticonsWidget(QWidget *parent = 0); + +signals: + void insertEmoticon(QString str); + +private slots: + void onSmileyClicked(); + void onPageButtonClicked(); + +private: + QStackedWidget stack; + QVBoxLayout layout; + +public: + virtual QSize sizeHint() const; +}; + +#endif // EMOTICONSWIDGET_H diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index 398579318..0e9e72f9f 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -20,6 +20,7 @@ #include "widget/friendwidget.h" #include "widget/widget.h" #include "widget/filetransfertwidget.h" +#include "widget/emoticonswidget.h" #include #include #include @@ -176,10 +177,10 @@ ChatForm::ChatForm(Friend* chatFriend) sendButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); fileButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); emoteButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); -// callButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); -// videoButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); -// msgEdit->setAttribute(Qt::WA_LayoutUsesWidgetRect); -// chatArea->setAttribute(Qt::WA_LayoutUsesWidgetRect); + // callButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); + // videoButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); + // msgEdit->setAttribute(Qt::WA_LayoutUsesWidgetRect); + // chatArea->setAttribute(Qt::WA_LayoutUsesWidgetRect); connect(Widget::getInstance()->getCore(), &Core::fileSendStarted, this, &ChatForm::startFileSend); connect(Widget::getInstance()->getCore(), &Core::videoFrameReceived, netcam, &NetCamView::updateDisplay); @@ -313,7 +314,7 @@ void ChatForm::onSliderRangeChanged() { QScrollBar* scroll = chatArea->verticalScrollBar(); if (lockSliderToBottom) - scroll->setValue(scroll->maximum()); + scroll->setValue(scroll->maximum()); } void ChatForm::startFileSend(ToxFile file) @@ -658,50 +659,23 @@ void ChatForm::onSaveLogClicked() void ChatForm::onEmoteButtonClicked() { - QList emoticons = SmileyPack::getInstance().getEmoticons(); - - QMenu menu; - QGridLayout* gridLayout = new QGridLayout; - menu.setLayout(gridLayout); - - int colCount = sqrt(emoticons.size()) + 1; - int row = 0; - int col = 0; - for (const QStringList& set : emoticons) - { - QPushButton* button = new QPushButton; - button->setIcon(SmileyPack::getInstance().getAsIcon(set[0])); - button->setToolTip(set.join(" ")); - button->setProperty("sequence", set[0]); - connect(button, &QPushButton::clicked, this, &ChatForm::onAddEmote); - - gridLayout->addWidget(button, row, ++col); - if (col >= colCount) - { - col = 0; - row++; - } - } + EmoticonsWidget widget; + connect(&widget, &EmoticonsWidget::insertEmoticon, this, &ChatForm::onEmoteInsertRequested); QWidget* sender = qobject_cast(QObject::sender()); if (sender) { - QPoint pos(gridLayout->totalSizeHint().width() / 2, gridLayout->totalSizeHint().height()); - menu.exec(sender->mapToGlobal(-pos)); + QPoint pos(widget.sizeHint().width() / 2, widget.sizeHint().height()); + widget.exec(sender->mapToGlobal(-pos - QPoint(0, 10))); } } -void ChatForm::onAddEmote() +void ChatForm::onEmoteInsertRequested(QString str) { - // hide the QMenu - QMenu* menu = qobject_cast(QObject::sender()->parent()); - if (menu) - menu->hide(); - // insert the emoticon QWidget* sender = qobject_cast(QObject::sender()); if (sender) - msgEdit->insertPlainText(' ' + sender->property("sequence").toString() + ' '); + msgEdit->insertPlainText(str); - msgEdit->setFocus(); // refocus so that you can continue typing + msgEdit->setFocus(); // refocus so that we can continue typing } diff --git a/widget/form/chatform.h b/widget/form/chatform.h index a58dc3237..064e05b29 100644 --- a/widget/form/chatform.h +++ b/widget/form/chatform.h @@ -84,7 +84,7 @@ private slots: void onChatContextMenuRequested(QPoint pos); void onSaveLogClicked(); void onEmoteButtonClicked(); - void onAddEmote(); + void onEmoteInsertRequested(QString str); private: Friend* f; From 51ac007baf1308bd8227631a3d9263a1e00fc7a1 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 1 Aug 2014 14:46:28 +0200 Subject: [PATCH 023/149] default settings --- settings.cpp | 4 +++- smileypack.h | 2 +- widget/form/settingsform.cpp | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/settings.cpp b/settings.cpp index 42e759f3e..2639731c5 100644 --- a/settings.cpp +++ b/settings.cpp @@ -15,6 +15,7 @@ */ #include "settings.h" +#include "smileypack.h" #include #include @@ -22,6 +23,7 @@ #include #include #include +#include const QString Settings::FILENAME = "settings.ini"; bool Settings::makeToxPortable{false}; @@ -92,7 +94,7 @@ void Settings::load() s.beginGroup("GUI"); enableSmoothAnimation = s.value("smoothAnimation", true).toBool(); - smileyPack = s.value("smileyPack").toByteArray(); + smileyPack = s.value("smileyPack", !SmileyPack::listSmileyPacks().empty() ? SmileyPack::listSmileyPacks()[0].second : "").toString(); customEmojiFont = s.value("customEmojiFont", true).toBool(); emojiFontFamily = s.value("emojiFontFamily", "DejaVu Sans").toString(); emojiFontPointSize = s.value("emojiFontPointSize", QApplication::font().pointSize()).toInt(); diff --git a/smileypack.h b/smileypack.h index dd315ab94..494d6db6e 100644 --- a/smileypack.h +++ b/smileypack.h @@ -28,7 +28,7 @@ class SmileyPack : public QObject Q_OBJECT public: static SmileyPack& getInstance(); - static QList> listSmileyPacks(const QString& path); + static QList> listSmileyPacks(const QString& path = "./smileys"); bool load(const QString &filename); QString smileyfied(QString msg); diff --git a/widget/form/settingsform.cpp b/widget/form/settingsform.cpp index bc2518ede..bf50e364a 100644 --- a/widget/form/settingsform.cpp +++ b/widget/form/settingsform.cpp @@ -53,7 +53,7 @@ SettingsForm::SettingsForm() makeToxPortable.setChecked(Settings::getInstance().getMakeToxPortable()); smileyPackLabel.setText(tr("Smiley Pack", "Text on smiley pack label")); - for (auto entry : SmileyPack::listSmileyPacks("./smileys")) + for (auto entry : SmileyPack::listSmileyPacks()) smileyPackBrowser.addItem(entry.first, entry.second); smileyPackBrowser.setCurrentIndex(smileyPackBrowser.findData(Settings::getInstance().getSmileyPack())); From 7292e1cc680312536f01470a89ff7ce5265e0560 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Fri, 1 Aug 2014 14:53:47 +0200 Subject: [PATCH 024/149] increased minimal height --- widget.ui | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/widget.ui b/widget.ui index 0364da3d8..3fd6e03bd 100644 --- a/widget.ui +++ b/widget.ui @@ -1,20 +1,4 @@ - - Widget @@ -23,13 +7,13 @@ 0 0 640 - 320 + 420 640 - 320 + 420 @@ -2131,8 +2115,8 @@ QSplitter:handle{ 0 0 - 256 - 199 + 255 + 299 From 6f853f699706e08d7057fbaebd142f32387f5baf Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Fri, 1 Aug 2014 22:24:02 +0200 Subject: [PATCH 025/149] Add missing ctime include --- core.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core.cpp b/core.cpp index 612560fef..a5f70695e 100644 --- a/core.cpp +++ b/core.cpp @@ -20,6 +20,8 @@ #include "settings.h" #include "widget/widget.h" +#include + #include #include #include From 158fea89a159160585020adf47053d74eeded18d Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sat, 2 Aug 2014 16:53:18 +0200 Subject: [PATCH 026/149] wrong header... --- smileypack.cpp | 6 +++--- smileypack.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/smileypack.cpp b/smileypack.cpp index 7dca525dc..e969de06a 100644 --- a/smileypack.cpp +++ b/smileypack.cpp @@ -1,9 +1,9 @@ /* - Copyright (C) 2013 by Maxim Biro + Copyright (C) 2014 by Project Tox - This file is part of Tox Qt GUI. + This file is part of qTox, a Qt-based graphical interface for Tox. - This program is free software: you can redistribute it and/or modify + 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. diff --git a/smileypack.h b/smileypack.h index 494d6db6e..7800f0c93 100644 --- a/smileypack.h +++ b/smileypack.h @@ -1,9 +1,9 @@ /* - Copyright (C) 2013 by Maxim Biro + Copyright (C) 2014 by Project Tox - This file is part of Tox Qt GUI. + This file is part of qTox, a Qt-based graphical interface for Tox. - This program is free software: you can redistribute it and/or modify + 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. From 3069a59b8cc2e054ed884c4db7d9804b488ed5e3 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 3 Aug 2014 00:29:56 +0200 Subject: [PATCH 027/149] Update to latest toxav Fix new callbacks including user data Thanks to @suhr in #178 for reporting the breakage. --- core.cpp | 8 ++++---- core.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core.cpp b/core.cpp index a5f70695e..f4933c3ae 100644 --- a/core.cpp +++ b/core.cpp @@ -141,8 +141,8 @@ void Core::start() toxav_register_callstate_callback(toxav, onAvRequestTimeout, av_OnRequestTimeout, this); toxav_register_callstate_callback(toxav, onAvPeerTimeout, av_OnPeerTimeout, this); - toxav_register_audio_recv_callback(toxav, playCallAudio); - toxav_register_video_recv_callback(toxav, playCallVideo); + toxav_register_audio_recv_callback(toxav, playCallAudio, this); + toxav_register_video_recv_callback(toxav, playCallVideo, this); uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE]; tox_get_address(tox, friendAddress); @@ -1381,7 +1381,7 @@ void Core::cleanupCall(int callId) calls[callId].audioBuffer.clear(); } -void Core::playCallAudio(ToxAv*, int32_t callId, int16_t *data, int length) +void Core::playCallAudio(ToxAv*, int32_t callId, int16_t *data, int length, void *user_data) { if (!calls[callId].active || calls[callId].audioOutput == nullptr) return; @@ -1427,7 +1427,7 @@ void Core::sendCallAudio(int callId, ToxAv* toxav) calls[callId].sendAudioTimer->start(); } -void Core::playCallVideo(ToxAv*, int32_t callId, vpx_image_t* img) +void Core::playCallVideo(ToxAv*, int32_t callId, vpx_image_t* img, void *user_data) { if (!calls[callId].active || !calls[callId].videoEnabled) return; diff --git a/core.h b/core.h index 819171d8d..704022442 100644 --- a/core.h +++ b/core.h @@ -266,9 +266,9 @@ private: static void prepareCall(int friendId, int callId, ToxAv *toxav, bool videoEnabled); static void cleanupCall(int callId); - static void playCallAudio(ToxAv *toxav, int32_t callId, int16_t *data, int length); // Callback + static void playCallAudio(ToxAv *toxav, int32_t callId, int16_t *data, int length, void *user_data); // Callback static void sendCallAudio(int callId, ToxAv* toxav); - static void playCallVideo(ToxAv* toxav, int32_t callId, vpx_image_t* img); + static void playCallVideo(ToxAv* toxav, int32_t callId, vpx_image_t* img, void *user_data); void sendCallVideo(int callId); void checkConnection(); From 9380a2fe013df2672b96f09ca70ac6e6d91df2c6 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 3 Aug 2014 18:19:32 +0200 Subject: [PATCH 028/149] hand-crafted smiley pack using inkscape used as default smiley pack --- smileys/default/cool.png | Bin 0 -> 1382 bytes smileys/default/crying.png | Bin 0 -> 1368 bytes smileys/default/emoticons.xml | 69 ++++ smileys/default/happy.png | Bin 0 -> 1220 bytes smileys/default/laugh.png | Bin 0 -> 1240 bytes smileys/default/plain.png | Bin 0 -> 1015 bytes smileys/default/raw.svg | 718 ++++++++++++++++++++++++++++++++++ smileys/default/sad.png | Bin 0 -> 1156 bytes smileys/default/smile.png | Bin 0 -> 1296 bytes smileys/default/stunned.png | Bin 0 -> 1088 bytes smileys/default/tongue.png | Bin 0 -> 1131 bytes smileys/default/uncertain.png | Bin 0 -> 1139 bytes smileys/default/wink.png | Bin 0 -> 1128 bytes 13 files changed, 787 insertions(+) create mode 100644 smileys/default/cool.png create mode 100644 smileys/default/crying.png create mode 100644 smileys/default/emoticons.xml create mode 100644 smileys/default/happy.png create mode 100644 smileys/default/laugh.png create mode 100644 smileys/default/plain.png create mode 100644 smileys/default/raw.svg create mode 100644 smileys/default/sad.png create mode 100644 smileys/default/smile.png create mode 100644 smileys/default/stunned.png create mode 100644 smileys/default/tongue.png create mode 100644 smileys/default/uncertain.png create mode 100644 smileys/default/wink.png diff --git a/smileys/default/cool.png b/smileys/default/cool.png new file mode 100644 index 0000000000000000000000000000000000000000..32f918af750677d0f56eb15309fca69c4906aded GIT binary patch literal 1382 zcmV-s1)2JZP)%$odq;@~bH$aYvJ(y)G1MujMyNnBAkc?HcgWDO zyhT!Tolnh${9IHui_nH*J3>jiUn^W!(An7-LO7um$Je*W$$v%O8Bv=Q90nRKgA)#5 z!a*pu!L~pva0OD6Fq(q+FvLf2CLIjWDbU{7DyJWlT&d0o`?X@9(YQ6`n5qz{N2LM? z5KF+V`#6q^MmV^>l|xWSR6u?vs*1I64A@mw3bmDB^z_#r4abF^euyOj_|8@AZfcRy z+!$-xT9g)!DaFnu6;M6z@k!G#8lIgG0Uz`Zuu}_wYROd~FY|K|wO`=C#mn%^Sr|;h z?HG)V!MsvfQVqVM*$D@SH22~bqhpG)Qejc$1VxsxV++*PfxyAWRyj~W-WgGwwBq;5 z5>&%B5H!XZlv0@nkV>U+UAKVP@Au>P`}5*Ogk&(16&yAi zx3&_qyV(%=*_Ss_x&;F^iz^Be>#l7-#~#fAm~b zH3N+`p0V}QmfJ}+|- z+AM=p6~c(X^;-daK0RY5N-3`P76abK6@eRfg4nj6Q7NSq*KP%Y1XUsL7o2ox15R33 zqRK|GJsiNODgA?iB2tc-b+Tgrct&!iAXseSh&5|`uvn)*E#UwrHpKQTQDy6d!$yRX za4@@h*1q7*D!XmltXh_Te6N1q&B#1c{L1>VOl&v^2qg)JjTVMF#5*$6__%G5^ViC7 zrBKTHXU1u6O5~C6*>#t$8x@EYX5FxOgg0NkpNUQLXicqFPz~N$oyLo`V;uRgkE(Jj zFQb*qCONXF8_VRMiZ9g-^V$1135QHU#-D$16{EB9X&zB5v=Az^!qtkrLv+iULDn`5 zbK$R2?hX2=Uo^t1`a}V78e7-&v$i3@r5k1RC;U9OaEMoy#`B25D@Ie*u);zy;0oFm zZy*m zjHh7bJ1{y9mm^Rb$c{NKboJs)I-K9oD%q+AAkgl(=$`)k3IC44w!QH79!QSNPCS_O z;;#3?SNrmb!LwA3ixy~4_hrZ%Tjeyu!B`Ud9%NryJRgo7^5lHE6^?!jeFNF?#IPrE z<9l%G0(|)?Y+avE-1orqa;|VF*Ue5dkV>765S{XHD%ZnxT!K%I!XI7Ub0`Qk3*cH0 zOgc~=g6J3C=b292JAjDr{f1U%_i*rN_xeW{oVn!5+kG2WEQ7b2;Po~6dtxr`_5bDD obMcgJEctjUceUyGuWzaU04LKr8o4^{+5i9m07*qoM6N<$f_0dRGXMYp literal 0 HcmV?d00001 diff --git a/smileys/default/crying.png b/smileys/default/crying.png new file mode 100644 index 0000000000000000000000000000000000000000..05387b8fa3c30f0ca2a862b281f9b61b3d33a2a8 GIT binary patch literal 1368 zcmV-e1*iInP)xr=2rgLKFO7X3yIHUjN?boORivs@yG_YsDY3DaE2tAQvSQpmcQM(ZwM=>Mb=ttQvLe2bgt-mkvhM+7Is0J4JEbNR_ ztc;0};s?JEjDVvMj=*3TdIq59I(Edy0vZ&m7F6i*dlVOG2(rZpn=OO$=oGB%0LYz= z0w~ZKg3H&iZ3lz0b$$igAYLd={A8`97-ct5mOTjyvcNK9m)#k*1Fc=q*#|(KBdjhd z*TGnhZ_HlAD7!^inV$){lkZ(L3d_Ls97s)uwr*A$1(5RCCot+vO+hvTW%-%N{Rqb* zcQWK>B0yO~kS(!uw;p>#P!<~DSXLS`J!gD`V{!2+boHZ-@?`WQymfMcYRljhWW_JE z9jH43JHLa_Kw^Qj=i$R$@K;Ox-0-*K3`dWvsjAU9J}@mCasu%Sm#>HYN8NGG6lgsF z6a1q&dwzn-_lBJc?B5Pc7LDdy4Z)>O5Mk;3a;-N2s#N+c>}(I=%U7WOmly}vpzd%y z?~Ct8#;WjTT|6f{06q&_l}Z59Tq}NrWf`ehUU8g~3_feLEif^jH`eCG5g;QK3t?Gv zt@usIrW7SD!-EWvl@4oHjQpQ71727Z&wFPTq)u?hlTzWWm%aUEOazp)kWHx%i$c^* znTfD-12iSQPTN2pHLq>QGVx#Cv&GPU5DuS$=StiScp<7|3vQDLe<$uxpvZj-nVUMONHw>CGF8z{aNa ztO>q?<9Kt7xYZCP(;##^ig9jJS!X}gPV$X*03NpvlalPs`>rvcru2=}rG3NpBSoGZ zN5N4HLbp$$LvYLDgd}gLD~c}hZMcMgdh>YmrPB#FdF<*uu>2_SW5){KPb4Z99xpv^ptla(=z}F{Q-*;qN+3oWslFI;)z1xSOaJGLi!|ldL1 + + + + :) + :-) + + + + 😎 + 8-) + 8) + + + + 😲 + :O + :-O + + + + 😋 + :p + :P + + + + 😕 + :/ + :-/ + + + + 😉 + ;) + ;-) + + + + 😖 + :( + :-( + + + + 😢 + ;( + ;-( + + + + 😃 + :D + :-D + + + + 😐 + :| + :-| + + + + 😄 + ;D + ;-D + + + diff --git a/smileys/default/happy.png b/smileys/default/happy.png new file mode 100644 index 0000000000000000000000000000000000000000..e53bb0541f65b0826f942033286693c66a1e8911 GIT binary patch literal 1220 zcmV;#1UvhQP)Yi1$BkgEVkT!}1f@-c*2=JcF(>g@L}~;M0#yMAH2D_pFr#K(vW=jDS z7)U_h1zgu+Q1(^Uvmd4lO%v~kN{&&E19inqpsWZSGj-U_aV_-3Vc-$~C#=wTUs$iC z<^-lZix}m&2%Ad_p=9aoMSUCtE0;m;Lg*c2vrzyEr|v-7nmQxw1?ox*k+}$`QnD0E z3lX3$7NI%y-o&=YB2r_7Z;JAemCNQwIF<8%Lwp3a%Kd&3POMzupkuIQMe{EV6SZT< z-ySB!JEO7@s9I5glc~7ce}a3Th7CKR`;VCg-Z%oQHo?n>r{8l7tSG<%s>by^aa9@u z4sLON=1KRy58rpeR~>LTk~ych-^)AyJG^}qe*SfOPH{d299&fz08Cd@f(W&tT%4KS z<0ZM7uT#lc2m!~t7Jh1iW7T zU*PMgu-u>&8o`=u8uvV4#5)a93Jt=bRgBI4Sf3MC!72t}&?xkScP#o`O~UoDnTBVN zYvIypdd$}mYs0?K`)?+Ph%;Yw+6*+UbqheaLGz zd$vx-6wm3Pv{i&PX#hlM9dmI85?)ep0etcnSPS7j5FehM@bNF<)6?+EGwID{AOT}8 zjtH$V-rL8`UToa@0I=!~_-Mb^qt`y=_4aHya16FKL(Lj^v2il)TF+VmG2dKHoM8%0 zuEq4kCkJeL0M35kZQuIsaHtg$DYcPGd>Ed46JB~3o_G+xe$U%MpPo3l7NgMQ$I?7p zXGEG6TFQ#jE!2esG`#8+VeTS$s1jC}!}22N>xW-@;Pg4TmV~B8cxRXQz&`yKJ#mG7 zRrT7EQ5;0Rix3_6aMP^Rw?DwK&*98DubQuqd8;cefk$iL`7o?5OCQsJ5qbwvRZgy} zC(Xl6>FBCfq|qq!#Hky-mhN8H-{bwjE5_jw2rWrprOy=ideRDwQ|o4qr0?tDA<&Yby;s45H9AKl^~cXc?S;gL!xT{=HJml~UZ zKVzVlXAKUu;HAuap%lj$YK%Z7c)9vsD8*5s%Af>|V9i1jcMfF4+YM2I1|e=0V;8=y z-<7O_RSZJhrw|joZ81L&5|eQ5pWFgh*Ft{sTTe}UzoHEJaJhi-_T&6Kui?2J-creh zN{S(NY_@zo>2s`Q&=+v%zXpl135rUWLQx^S^Ez~V1lzZ7r>Uvwj-b(KlwG@a@zQ2k zlD3k@CIBH3aOn4~3F*|Cu=I{i(yHJHu=7PYbj;A#*GqkUJtZY2i-sRP+DAdY;qBM# zOr7F69hBZRtvclc5TR?@<>ldVs0e^R55D@q^5`p*960bXLqoAU8vXk_p!R{;^6)rJ zyEr0rK{B@|&0ZvFeE?YX5PZ4UWi);nzkl%=sBx{~t@hcnYdvcPL{jE*CbcMZxR#TH zBc1~RXnqDxeQs%f)8*e$hi%(JY}l}Yf`Wo9SR#?2r>BP#Cr+?sJsjR=@#oF94~~Fq zF$x{2x(p9D5SC7bJvC*S7HV`H+TInu?N_GjYc_p_AJMbf5(j* zH|c1HeQ$uIC9T+153aDcp;h&_%nR*HGKb*Lo{Z&Ij#8fgz8G+ zg+|Mc5Y*LVJ`=kN7vrcZN1kXU!^6$V=&Dwv-6#x>&@y==)4i@=>s{btEnG=JX|W=b zogU}7*CSSFpKG80U%owE_vyrvsrzzPo2y)(QvU<%EAhALzcG#g0000TvZguKj+@*)FjiXlgY$bNLu198{M=`Q(P;Q zAT&%=LbQK?c9o5r#1;gFZiFse)k4W;1`84tTuNz@MiCXs&XS3!qm${7$*(%jyT`@L z8{hm0O~{z~U0v=w?|$xm@7{C1S5%e#YB?*>vd0LPGXi}mNra+89*>o{Wqv5FmHmz< z`++ZI<&r8B2%{*mpx+42DdykN*hHBVVfI{Fzc>_pF(VfRZUDm(iqQDJI$T<;$cF0z zxpr=x>(C5pf-hvH!zg!vvD67T-2>J%zV>8!4svTy*Z|-&Crn;Q>rOZ((l8e>${i6d z49!;MI3w<+r^7AKZc$UW4~;Hb1il`n$2f@Gj4Xt1=O>c&T{nL8m`~Zu8P@B&g-pXQVF>IKHT~o-gpJhoN67H z=z_uqv9e=C7BXBB<n)4_+{}Z6mUfO-QckTemy=41svzdnYd*hVY9S# zH1N_EAZ*4h^JXZm6_mNsHr{{z+ZEsGpv(=WwGsgkVYce=W}ytd4Jr2R8Tk6UgM+^O z7={Mx`wC^KdRP%=AyiTyWMm;?Is4K;eR28Y5$rrZIQ&$~&x(OO2j8#aRXx5rKdu)b ztQ$B zU?4>vWXSG%xVBiS{5q@_QC04qAE(a4HDq*ECo*Xia%+rj|J644de;e)jrRHf<=ex0 lN;j5zJ(as!quPB-{RgE@mK1k_x`qG%002ovPDHLkV1kV2)yn_? literal 0 HcmV?d00001 diff --git a/smileys/default/raw.svg b/smileys/default/raw.svg new file mode 100644 index 000000000..e9953ee3b --- /dev/null +++ b/smileys/default/raw.svg @@ -0,0 +1,718 @@ + + + + + qTox + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + qTox + + Created for the qTox project. Inspired by the "Never mind!" smiley pack. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/smileys/default/sad.png b/smileys/default/sad.png new file mode 100644 index 0000000000000000000000000000000000000000..2460dceb0ae4965d96ff35a2daab66c4994ec32e GIT binary patch literal 1156 zcmV-~1bh35P)CLt;0!wORKqEgzVDMAs& zLI{P1td)>b5K15XcnN|O(hsO8=A{rt6l);_!Y)Q6_|O+0lzb{^Ya0(=bRB$WxE;=i8o@?h()bH1&SYGPGJU{$zqG4 zx>k*C*Pm<$J{FQDRoW1mQ3@0NMsOU(Y#9)32=9jVKHWo0V(9sak!5zXyMuJ>2LZ@YLs!FiRia{Q>6+nS- z1pfFJ+jcN0SB?g_3hAIU_;5(_jM4+NlodfuDOe_T+QVf#Ff|L|MF2i`g!W^tx{_?; zNm+{+rALI*)qbehw{vJhmVtxike>_FbDTB`Ag#$KuxU?YK{|n!YCp0YaIz})LA4(N zT1J9gN*-H3_K~0*H^R52g~-A3?0}Os@ej;KQAc?$aS7LVF3@EeoSM??gJJ#dIBS0o z>+rFVGyx4&C0Lm**U%j}au!a$4wHXv4Y+m#o;U?>cc+h82C7Q1fQB`m3so7opjgkG0i*T$G== zovgfE@K|nJ1Pb%gZ3OV;V<9w;hs5iN*fffv&{wbp8F=pv@a912et7NW%r<2{xOo|F zdg4zR_?R*6gUZgPM&?v(}&WZBb)79`;&ejXamhP{@?P(A=X9Oz1jn#Xh1V@ER zgW@-WW405xvmhgGHbn6oggHks&i2##uH+~IRhBN_h4VTxfw8>$je-xRnmdKwUs%9sm(~<2J8^BT$|p#4g{5iyy)VK{tw> zI1DEnq3&@vtp4x|4Bm$RuigIZ9q?pzx}R_a;x?8Dy^xerM}so#u{iQf_2%TV5QU~U zVfZI_^%Pt_4+qN99Y2V{^**@vDdc$IRyQ1eYGd4X;Kym~xXpL<0X+suDOI7vb}&=3 zn;o7w4`cVB?;ZH~VrDQvt{2`q3wQcpe-S)?0Y>j`j8Dyi?O+r-5`F9NhJX&DTnR72 z%!1n&U2&a$(FLt9WQL}yrV_sS1P;}@p95Tf;YDzitI5@DN&zV{8YHwWH)(g{fIumLFuTdhK_F_SEwE|5djq>k++JHtUhR)l!x1SL%PP WLCDwdrkno&0000SP*4J2quPy(Wnh1E?86-h#`=4iX`|T5`)I5eK`v>rU{8u==hj8Ev2Oo z+s-|oi`!{uI&CP>i2r0V=broB^Sk%tobUS|QB{_z-gfbixNO2 z0i0kS)5aaeyv`eKn2x!yUp!y22bX!a>JiSFOY;DFnIQ zrvM7XM<99w*R>dwBkLP^6EZ;=@XmJ0HOeWVzN7#uL*SVCkKJCbh3f+lzXiZ2R%qVX zpcAPvzIpE=MmZ(Iwu)jXE4p)NQjUQ&r4Y!5{z0}G1(1f+8A$u4o-hZ2`if%YUcjj; zD}st*1gP%{b13!R?6h}Et4u{c?e$j=@%jmLCkW zYsb#)9%kV^?Xnf9S+x>pp~cnlGgQ9<&%FlM{#+dJ_6d0K1$g~<<~_&2s+BlE%?!_j ztJ36ia7zjo9`s-fOm75Jd$7_o~er{%r0KotbLS1jW_IZ>cMxYG5 zT>W1t$x)%)pcEUynx!P}WsniC8ln^%gh8tqyY#YtPqGSDF$jY`g_z)##hfe{9fx0k zUtZutt0BklwWku^zbJqCaJh!@>Tz%9SfuxOC|& zCMT!a*9DI(o`DqU4%0s4;WDh$_m|=0&*AHcLo{ZYPAL8? zp`uK9zSgp*0jes~pNS1a{~)T$xebk^dANBQUDb*-8-?ow)Q?Z5yVs}Ic|UNm7H*D0 zus{*XOpo*2>p3el&$rM2FW;W3`*dPS*L^vw&DV0DQvU^ac63ZU&h35x0000=^HM#f2QR4!2nxLjMLg9)$YqxZ5LP@ejMXHjMmL#GEH=EGSR~z%r z zbv~&DK9`X5sth9Zp)}>%jo_SO9?r%F%9IEbr(^oXf#AuwoDsMVL<1Ht+<*-?LVXZ| z0WbniVP_Y%cVKN3*0%6=JuHw^7>*9;^drJWl5wsXVZ<6-M+>$s1hU^!00mMR_+u5% za~PD-(*uk_DX0WKn~-{=j062`&Ct~f))WuhU!H@-6-ccEFzJM$7h}3z7!xSUMT{~o z!iCNVv>$tPXinC^$rI2}2TN%#7zL16;TzbqrnxvHK!0ZhIS9B=?Z==qf&l%=IM)jM z@~=G^morAV-P(klJaIVSLf!obRyI(lyp-F7`IQS?w+7eMdiY?-?;V%@ddS1)5^^4h zcC=v2ZLXQ0;e|Kg)wf~cugZY;Z^E;$!@D<1`>cVE7Az3W@_e`|g8_@z7AimK$S3f_ zJbXC|H{#`EmX`gvyMMw5x8T>`OJmwX5U_Zv3<8+>gai@#!VTC;-*Iz8`R78_*FnJg z&mz!NUm7DoxB-jMH=mGTAmh<1hNf_11v2pAI}khqt;gZY#qu$2VYu}k-25CaorCUY z%EyHpA+=6Z#?dRYaW0GU>8VaQdZcm!ho$@f!kr}$xNHR4!9S}XhjJVho;D~EBREsb z!F>oa;#WhIh(Sm@#kktb`hnyWoMI5tMqwHJviLZZaa9HpdQlp3^+vE(G5__(8p^l`V@C$`>m9-4Q8^|s3UvD%++ZC} zupVmt;P-(MunOr6Y@}g%9hUFmW?UQ~t}xsk(Hjp47l}tXYlIQUVA~sUngbx)O$AUO zk%B+&;<^@ta_&fk^H2&ZfltPy)+kqj{^q@Kun8Qqx!Lw|EzB-KVikZdt?=qo1G-Td zl|MqxPjv3**rUvA2OLf47y1fWXYp7M8&Mm_H%mqdrgFV<(eK6$Lj?L~K z^6;sc90$7F8*$1lu8CXl?$iN4u!CwPS`{B)(%EvSZ;mSL3 z={mgpJREwgd|a>|600<%EIl$AWk{6EPlVx-nym*=E#3bIew+h=AtTTVUasB^D*(o@0uETJPf_hz^T6CcFXI4uoiHb z@O2Gn`eszdm+ui#iW5y|I}G)fhu``YKAMKU{gAQX0!&^P91IV`4{j>XL0>68}Q;BoOrIZO(F#u7e|CK$maH} z*^6hbPenS=2zTy#vnkY?>!sSwa;;~rfOyVa=Fc#NVb@}2mnws|G(u+^Tu&C)U%Ly> z9xaWZT>{r)6ozwkd3bk3Z=jq@tir-dWdk_#I*iiK~zYI&6i7PTxAr;f9Jc?X_HK+P97x+No(B&K{sh$xX^`F zYY-YHEre(g#Eo_ptaXvvfS^ziv86(x7D5DPv>;Kz2QHK*X>_3?ab=stT4N^DXeJMx z%>9mwn@MISlVrw(*8l2q@A=N}e$Vs&L{%wNqfznCx-{dkU!WSL0wJz2iOX2fVX!W& z$wKoNes2V86|*k6PiY!-gK zh3i@j%ISmc^uk)u8u(CDN{rG6v{mhfeU;#t+-950wJ<&nu>=4gTA{Nktc#g3zMOv% zqx6Yzq_zU8_Y@CJ%Q0|ZFO=?ti8x1$0!TP>1hV=x5}^lZtF1t`0?t(R9;mHAfVSZX zr!v2-4Eu0IT8!{bWdJ#_cYDB@x;6#VbEs7wN-x5do(r6D40d1T_Jd(%?bzkr!wP&P zDu;o_nsS_ci)-*lsDBzBdlANNt`B(aBHZ^BoIJbsn`5A+90zDz=6P^cI(!apRWN_j zo_FB8QTS{K&PMXbOiX%l*M5W7FTqd0tc|G(g3rNKr31i>M#YcN8Y;zEZy)b2&HtRK zlAYjlyk`*zl&p;rAXJKj&^j6wzi-y1Sqyb3rF+ERE6Nut8non zICcp3-;+NsR0gpGfmutl3`OV?<=qErVb_lJe_*@x_Y(Xt0Rmk{pc=fh`gSPIQQ>Zb zQegyZ3OTs9K}Ni4h*Dt?;#M)X@Up%oSp};Ygt$?d1g|XK4y8Gw{O-eL4CB?~|GMD* zxCMVEU?~N4_k!7=3N9}D9BUc(1sw(xFgG*5@pj9VwQ&9e==&6Yz7CfU&6bLCq2egZe;@@+%AHbF*7Rp@pt zW_)`61aH0vfl_$;rQ*QgSt{3J6uQ&zR#G&!>lKvKu>?&1wYKq%DX&_cJ5d}IynL|) zSfw}9&E^53`%@ZZ?~36I%Z;4>RY?{mq@ZbI$*Ys#2;ZBjQUqv|-UCP=^vkm{XX+;j-Ui zyg8)FQpb~0;1dz)RHYB03#Br1-3YF$nCqi4k1{I4@UD=KtqUFvOS`}z&}v&afpV-s z1#I$x&juslDkM{IEeY`jh%e%#94sKJaICdg&)*MVN|F*T|xG*&fv8w=_c7^^uA-$HJ zW9L1K7-dL=?uH=LZMku1MwWr?wNPFL({pqi1&~no8_1c{M4011PeTw{4>((OTc9C` z06oz#1KF|V*B%W^yAi&wu0*!iZVWhEm;Q#?dDK-pGK+9|<^qG3!ELO*dBDWaaO_Pu z|HH~ydhNLBzlUY`L_|7)*7_=}n^{}{?~lRm$KZ_*VDFRg&PZOxHmvXyl#jRGzfF9V%*Z(`nu#QxQaoTGYT`{wZ&VZ3`dl|3=WsU z>&Lf38IJ2RW&9T72=noUjfJRsZ8cx<1wfehTa26LkS0+^bkI2f}kYD5K3GO&S0ZhEon!EU|K+18wl$894Z|S3uTMEDrmggNr}GGu?Ty z1f(1+5r!dM+tX$*nzlYUdgXCAbre4R3R(`q$6pqPrW|xe7# u=iBH1mv7J3ZQ8Nq>bC6F^0m>s)c*ipo5z=40KumK0000 Date: Sun, 3 Aug 2014 18:31:08 +0200 Subject: [PATCH 029/149] tweak --- smileys/default/raw.svg | 55 +++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/smileys/default/raw.svg b/smileys/default/raw.svg index e9953ee3b..d2e921d77 100644 --- a/smileys/default/raw.svg +++ b/smileys/default/raw.svg @@ -16,7 +16,7 @@ version="1.1" inkscape:version="0.48.5 r10040" sodipodi:docname="raw.svg" - inkscape:export-filename="/home/paul/Dev/qTox/smileys/default/raw.png" + inkscape:export-filename="./raw.png" inkscape:export-xdpi="360" inkscape:export-ydpi="360"> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3881-1" - id="linearGradient3887-0" - x1="11.216473" - y1="234.94836" - x2="14.142681" - y2="245.0323" - gradientUnits="userSpaceOnUse" /> <linearGradient id="linearGradient3881-1"> <stop @@ -241,7 +232,7 @@ inkscape:label=""> <path transform="matrix(0.88628187,0,0,0.88628187,1.8194901,823.65453)" - d="m 32,240 a 16,16 0 1 1 -32,0 16,16 0 1 1 32,0 z" + d="m 32,240 c 0,8.83656 -7.163444,16 -16,16 -8.836556,0 -16,-7.16344 -16,-16 0,-8.83656 7.163444,-16 16,-16 8.836556,0 16,7.16344 16,16 z" sodipodi:ry="16" sodipodi:rx="16" sodipodi:cy="240" @@ -251,7 +242,7 @@ sodipodi:type="arc" /> <path transform="matrix(0.91334205,0,0,0.48070635,0.34633991,917.17801)" - d="m 14.107143,238.5 a 1.9642857,3.9285715 0 1 1 -3.928571,0 1.9642857,3.9285715 0 1 1 3.928571,0 z" + d="m 14.107143,238.5 c 0,2.16969 -0.87944,3.92857 -1.964285,3.92857 -1.084846,0 -1.964286,-1.75888 -1.964286,-3.92857 0,-2.16969 0.87944,-3.92857 1.964286,-3.92857 1.084845,0 1.964285,1.75888 1.964285,3.92857 z" sodipodi:ry="3.9285715" sodipodi:rx="1.9642857" sodipodi:cy="238.5" @@ -261,7 +252,7 @@ sodipodi:type="arc" /> <path transform="matrix(0.91334205,0,0,0.48070635,9.8832106,917.17801)" - d="m 14.107143,238.5 a 1.9642857,3.9285715 0 1 1 -3.928571,0 1.9642857,3.9285715 0 1 1 3.928571,0 z" + d="m 14.107143,238.5 c 0,2.16969 -0.87944,3.92857 -1.964285,3.92857 -1.084846,0 -1.964286,-1.75888 -1.964286,-3.92857 0,-2.16969 0.87944,-3.92857 1.964286,-3.92857 1.084845,0 1.964285,1.75888 1.964285,3.92857 z" sodipodi:ry="3.9285715" sodipodi:rx="1.9642857" sodipodi:cy="238.5" @@ -282,7 +273,7 @@ inkscape:label=""> <path transform="matrix(0.88628187,0,0,0.88628187,33.801736,823.74463)" - d="m 32,240 a 16,16 0 1 1 -32,0 16,16 0 1 1 32,0 z" + d="m 32,240 c 0,8.83656 -7.163444,16 -16,16 -8.836556,0 -16,-7.16344 -16,-16 0,-8.83656 7.163444,-16 16,-16 8.836556,0 16,7.16344 16,16 z" sodipodi:ry="16" sodipodi:rx="16" sodipodi:cy="240" @@ -300,7 +291,7 @@ style="fill:#000000;fill-opacity:1;stroke:none" /> <path transform="matrix(2.2007051,0,0,1.1582659,15.153743,755.67017)" - d="m 14.107143,238.5 a 1.9642857,3.9285715 0 1 1 -3.928571,0 1.9642857,3.9285715 0 1 1 3.928571,0 z" + d="m 14.107143,238.5 c 0,2.16969 -0.87944,3.92857 -1.964285,3.92857 -1.084846,0 -1.964286,-1.75888 -1.964286,-3.92857 0,-2.16969 0.87944,-3.92857 1.964286,-3.92857 1.084845,0 1.964285,1.75888 1.964285,3.92857 z" sodipodi:ry="3.9285715" sodipodi:rx="1.9642857" sodipodi:cy="238.5" @@ -316,7 +307,7 @@ style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> <path transform="matrix(2.2007051,0,0,1.1582659,27.023036,755.66017)" - d="m 14.107143,238.5 a 1.9642857,3.9285715 0 1 1 -3.928571,0 1.9642857,3.9285715 0 1 1 3.928571,0 z" + d="m 14.107143,238.5 c 0,2.16969 -0.87944,3.92857 -1.964285,3.92857 -1.084846,0 -1.964286,-1.75888 -1.964286,-3.92857 0,-2.16969 0.87944,-3.92857 1.964286,-3.92857 1.084845,0 1.964285,1.75888 1.964285,3.92857 z" sodipodi:ry="3.9285715" sodipodi:rx="1.9642857" sodipodi:cy="238.5" @@ -330,7 +321,7 @@ inkscape:label=""> <path transform="matrix(0.88628187,0,0,0.88628187,65.76398,823.59407)" - d="m 32,240 a 16,16 0 1 1 -32,0 16,16 0 1 1 32,0 z" + d="m 32,240 c 0,8.83656 -7.163444,16 -16,16 -8.836556,0 -16,-7.16344 -16,-16 0,-8.83656 7.163444,-16 16,-16 8.836556,0 16,7.16344 16,16 z" sodipodi:ry="16" sodipodi:rx="16" sodipodi:cy="240" @@ -340,7 +331,7 @@ sodipodi:type="arc" /> <path transform="matrix(0.91334205,0,0,0.48070635,64.29083,917.11755)" - d="m 14.107143,238.5 a 1.9642857,3.9285715 0 1 1 -3.928571,0 1.9642857,3.9285715 0 1 1 3.928571,0 z" + d="m 14.107143,238.5 c 0,2.16969 -0.87944,3.92857 -1.964285,3.92857 -1.084846,0 -1.964286,-1.75888 -1.964286,-3.92857 0,-2.16969 0.87944,-3.92857 1.964286,-3.92857 1.084845,0 1.964285,1.75888 1.964285,3.92857 z" sodipodi:ry="3.9285715" sodipodi:rx="1.9642857" sodipodi:cy="238.5" @@ -350,7 +341,7 @@ sodipodi:type="arc" /> <path transform="matrix(0.91334205,0,0,0.48070635,73.8277,917.11755)" - d="m 14.107143,238.5 a 1.9642857,3.9285715 0 1 1 -3.928571,0 1.9642857,3.9285715 0 1 1 3.928571,0 z" + d="m 14.107143,238.5 c 0,2.16969 -0.87944,3.92857 -1.964285,3.92857 -1.084846,0 -1.964286,-1.75888 -1.964286,-3.92857 0,-2.16969 0.87944,-3.92857 1.964286,-3.92857 1.084845,0 1.964285,1.75888 1.964285,3.92857 z" sodipodi:ry="3.9285715" sodipodi:rx="1.9642857" sodipodi:cy="238.5" @@ -360,7 +351,7 @@ sodipodi:type="arc" /> <path transform="matrix(1.5951602,0,0,1.0261609,60.548479,798.24781)" - d="m 14.107143,238.5 a 1.9642857,3.9285715 0 1 1 -3.928571,0 1.9642857,3.9285715 0 1 1 3.928571,0 z" + d="m 14.107143,238.5 c 0,2.16969 -0.87944,3.92857 -1.964285,3.92857 -1.084846,0 -1.964286,-1.75888 -1.964286,-3.92857 0,-2.16969 0.87944,-3.92857 1.964286,-3.92857 1.084845,0 1.964285,1.75888 1.964285,3.92857 z" sodipodi:ry="3.9285715" sodipodi:rx="1.9642857" sodipodi:cy="238.5" @@ -374,7 +365,7 @@ inkscape:label=""> <path transform="matrix(0.88628187,0,0,0.88628187,97.820154,823.8709)" - d="m 32,240 a 16,16 0 1 1 -32,0 16,16 0 1 1 32,0 z" + d="m 32,240 c 0,8.83656 -7.163444,16 -16,16 -8.836556,0 -16,-7.16344 -16,-16 0,-8.83656 7.163444,-16 16,-16 8.836556,0 16,7.16344 16,16 z" sodipodi:ry="16" sodipodi:rx="16" sodipodi:cy="240" @@ -384,7 +375,7 @@ sodipodi:type="arc" /> <path transform="matrix(0.91334205,0,0,0.48070635,96.347004,917.39438)" - d="m 14.107143,238.5 a 1.9642857,3.9285715 0 1 1 -3.928571,0 1.9642857,3.9285715 0 1 1 3.928571,0 z" + d="m 14.107143,238.5 c 0,2.16969 -0.87944,3.92857 -1.964285,3.92857 -1.084846,0 -1.964286,-1.75888 -1.964286,-3.92857 0,-2.16969 0.87944,-3.92857 1.964286,-3.92857 1.084845,0 1.964285,1.75888 1.964285,3.92857 z" sodipodi:ry="3.9285715" sodipodi:rx="1.9642857" sodipodi:cy="238.5" @@ -394,7 +385,7 @@ sodipodi:type="arc" /> <path transform="matrix(0.91334205,0,0,0.48070635,105.88387,917.39438)" - d="m 14.107143,238.5 a 1.9642857,3.9285715 0 1 1 -3.928571,0 1.9642857,3.9285715 0 1 1 3.928571,0 z" + d="m 14.107143,238.5 c 0,2.16969 -0.87944,3.92857 -1.964285,3.92857 -1.084846,0 -1.964286,-1.75888 -1.964286,-3.92857 0,-2.16969 0.87944,-3.92857 1.964286,-3.92857 1.084845,0 1.964285,1.75888 1.964285,3.92857 z" sodipodi:ry="3.9285715" sodipodi:rx="1.9642857" sodipodi:cy="238.5" @@ -421,7 +412,7 @@ inkscape:label=""> <path transform="matrix(0.88628187,0,0,0.88628187,129.83735,823.77759)" - d="m 32,240 a 16,16 0 1 1 -32,0 16,16 0 1 1 32,0 z" + d="m 32,240 c 0,8.83656 -7.163444,16 -16,16 -8.836556,0 -16,-7.16344 -16,-16 0,-8.83656 7.163444,-16 16,-16 8.836556,0 16,7.16344 16,16 z" sodipodi:ry="16" sodipodi:rx="16" sodipodi:cy="240" @@ -431,7 +422,7 @@ sodipodi:type="arc" /> <path transform="matrix(0.91334205,0,0,0.48070635,128.3642,917.30107)" - d="m 14.107143,238.5 a 1.9642857,3.9285715 0 1 1 -3.928571,0 1.9642857,3.9285715 0 1 1 3.928571,0 z" + d="m 14.107143,238.5 c 0,2.16969 -0.87944,3.92857 -1.964285,3.92857 -1.084846,0 -1.964286,-1.75888 -1.964286,-3.92857 0,-2.16969 0.87944,-3.92857 1.964286,-3.92857 1.084845,0 1.964285,1.75888 1.964285,3.92857 z" sodipodi:ry="3.9285715" sodipodi:rx="1.9642857" sodipodi:cy="238.5" @@ -441,7 +432,7 @@ sodipodi:type="arc" /> <path transform="matrix(0.91334205,0,0,0.48070635,137.90106,917.30107)" - d="m 14.107143,238.5 a 1.9642857,3.9285715 0 1 1 -3.928571,0 1.9642857,3.9285715 0 1 1 3.928571,0 z" + d="m 14.107143,238.5 c 0,2.16969 -0.87944,3.92857 -1.964285,3.92857 -1.084846,0 -1.964286,-1.75888 -1.964286,-3.92857 0,-2.16969 0.87944,-3.92857 1.964286,-3.92857 1.084845,0 1.964285,1.75888 1.964285,3.92857 z" sodipodi:ry="3.9285715" sodipodi:rx="1.9642857" sodipodi:cy="238.5" @@ -461,7 +452,7 @@ inkscape:label=""> <path transform="matrix(0.88628187,0,0,0.88628187,161.68181,823.65707)" - d="m 32,240 a 16,16 0 1 1 -32,0 16,16 0 1 1 32,0 z" + d="m 32,240 c 0,8.83656 -7.163444,16 -16,16 -8.836556,0 -16,-7.16344 -16,-16 0,-8.83656 7.163444,-16 16,-16 8.836556,0 16,7.16344 16,16 z" sodipodi:ry="16" sodipodi:rx="16" sodipodi:cy="240" @@ -471,7 +462,7 @@ sodipodi:type="arc" /> <path transform="matrix(0.91334205,0,0,0.1914354,160.20866,986.17167)" - d="m 14.107143,238.5 a 1.9642857,3.9285715 0 1 1 -3.928571,0 1.9642857,3.9285715 0 1 1 3.928571,0 z" + d="m 14.107143,238.5 c 0,2.16969 -0.87944,3.92857 -1.964285,3.92857 -1.084846,0 -1.964286,-1.75888 -1.964286,-3.92857 0,-2.16969 0.87944,-3.92857 1.964286,-3.92857 1.084845,0 1.964285,1.75888 1.964285,3.92857 z" sodipodi:ry="3.9285715" sodipodi:rx="1.9642857" sodipodi:cy="238.5" @@ -481,7 +472,7 @@ sodipodi:type="arc" /> <path transform="matrix(1.2347542,0,0,0.64987065,165.84267,876.83486)" - d="m 14.107143,238.5 a 1.9642857,3.9285715 0 1 1 -3.928571,0 1.9642857,3.9285715 0 1 1 3.928571,0 z" + d="m 14.107143,238.5 c 0,2.16969 -0.87944,3.92857 -1.964285,3.92857 -1.084846,0 -1.964286,-1.75888 -1.964286,-3.92857 0,-2.16969 0.87944,-3.92857 1.964286,-3.92857 1.084845,0 1.964285,1.75888 1.964285,3.92857 z" sodipodi:ry="3.9285715" sodipodi:rx="1.9642857" sodipodi:cy="238.5" @@ -548,7 +539,7 @@ sodipodi:cy="240" sodipodi:rx="16" sodipodi:ry="16" - d="m 32,240 a 16,16 0 1 1 -32,0 16,16 0 1 1 32,0 z" + d="m 32,240 c 0,8.83656 -7.163444,16 -16,16 -8.836556,0 -16,-7.16344 -16,-16 0,-8.83656 7.163444,-16 16,-16 8.836556,0 16,7.16344 16,16 z" transform="matrix(0.88628187,0,0,0.88628187,225.85699,823.74463)" /> <path sodipodi:nodetypes="czaac" @@ -564,7 +555,7 @@ sodipodi:cy="238.5" sodipodi:rx="1.9642857" sodipodi:ry="3.9285715" - d="m 14.107143,238.5 a 1.9642857,3.9285715 0 1 1 -3.928571,0 1.9642857,3.9285715 0 1 1 3.928571,0 z" + d="m 14.107143,238.5 c 0,2.16969 -0.87944,3.92857 -1.964285,3.92857 -1.084846,0 -1.964286,-1.75888 -1.964286,-3.92857 0,-2.16969 0.87944,-3.92857 1.964286,-3.92857 1.084845,0 1.964285,1.75888 1.964285,3.92857 z" transform="matrix(1.2115763,0,0,0.63767169,220.9911,879.83187)" /> <path sodipodi:type="arc" @@ -574,7 +565,7 @@ sodipodi:cy="238.5" sodipodi:rx="1.9642857" sodipodi:ry="3.9285715" - d="m 14.107143,238.5 a 1.9642857,3.9285715 0 1 1 -3.928571,0 1.9642857,3.9285715 0 1 1 3.928571,0 z" + d="m 14.107143,238.5 c 0,2.16969 -0.87944,3.92857 -1.964285,3.92857 -1.084846,0 -1.964286,-1.75888 -1.964286,-3.92857 0,-2.16969 0.87944,-3.92857 1.964286,-3.92857 1.084845,0 1.964285,1.75888 1.964285,3.92857 z" transform="matrix(1.2115763,0,0,0.63767169,230.2492,879.83187)" /> <path style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" From 726862994d0e04d885ad09eaa37e1aeaff497447 Mon Sep 17 00:00:00 2001 From: krepa098 <krepa098@gmail.com> Date: Mon, 4 Aug 2014 08:59:18 +0200 Subject: [PATCH 030/149] angry, tweaks --- smileys/default/angry.png | Bin 0 -> 1515 bytes smileys/default/cool.png | Bin 1382 -> 1597 bytes smileys/default/crying.png | Bin 1368 -> 1618 bytes smileys/default/emoticons.xml | 5 + smileys/default/happy.png | Bin 1220 -> 1435 bytes smileys/default/laugh.png | Bin 1240 -> 1455 bytes smileys/default/plain.png | Bin 1015 -> 1230 bytes smileys/default/raw.svg | 1030 ++++++++++++++++++--------------- smileys/default/sad.png | Bin 1156 -> 1371 bytes smileys/default/smile.png | Bin 1296 -> 1511 bytes smileys/default/stunned.png | Bin 1088 -> 1303 bytes smileys/default/tongue.png | Bin 1131 -> 1346 bytes smileys/default/uncertain.png | Bin 1139 -> 1350 bytes smileys/default/wink.png | Bin 1128 -> 1343 bytes 14 files changed, 555 insertions(+), 480 deletions(-) create mode 100644 smileys/default/angry.png diff --git a/smileys/default/angry.png b/smileys/default/angry.png new file mode 100644 index 0000000000000000000000000000000000000000..89a26246063dadf4d094fb77bc79cbc5e7f6e2db GIT binary patch literal 1515 zcmV<H1r+*;P)<h;3K|Lk000e1NJLTq0018V0018d1^@s6AFdWT00004b3#c}2nYxW zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H1019+PSaeirbZlh+aa3=3j?t5j0000~bVXQnL}hbha%pgMX>V=- zLvm$dbY)~9W^ZyJbZBKDaa3=3AaHVTYGq?|E+9#6b8u;LWn>^?c_4IXWgsF>Wp-t9 zAZ=-GWFaCTb8TsCWqBZQVPk7946eMW00010bVXQnLvL_-a%pF1bO1v`AVG9=a%p09 zbZKvHElzK4LvL+uWpZO_VQe61baZe!FE3+qWnpw_c4cF4ZEbIEb1rXkXD@7NV`Xl0 zWpgiLc`a^ZFEcJMFX6H#Gynhukx4{BR7i=vm(OohRTRfR=f2k|Ev4-^Z7l>^z#q|? z7%<QlkOd^_0+EDfni%A7aMP6uzg&osx+5{s#F!w4Od|_x6JP-gu?~fW(V${T>9i55 z(=w$$=}hlEE~ZoGN1;=xev`L&=bn2$@7{Orz2}OmQmlUIlEAoSCmtIG>QO=nqYA@V z1}Z&zo5GqbHl7p%@9UC%svJVuk5G}Zn-tEKU=|#eNrY|@&Nhd&=ZWCai0l%j6QR|g z!3J;Q1%HLIVF)|`lLA))$tswshs2AJcnLdKhKCYWp`*23zh5R?BpTtEfur6OZo@^q z+Up>0sj+|>h;N6XH?Vd!1~}2&&ihaZDuDmcC1u8O2BEF?1~h&H-t5xQeA!Zny#?`Y zfbz979NrPunQR|F?_0z;&WLcZp&RP2E+3kaHw&A)p!^;T?&qL!020og0h8UKFTzoT zwuWxxNx<2vzX}cA2tr#l!m;eOg=vpQWS4>OYHlE#yH*CAt^P2KY(pLF&LrW&w2RW| z&EOg@;1O7Pc;f{~G~u+2PGCoxshU~G-)_1DbwA~HN-6|oc_6EhuuzkiQGdM*cU}h( z-fRwQj}M^AA%7NIJBUYBZif&1;iDKlR}Rn5Kkqg`O-ZibXMezrarkipex8KgLAbaz z*Qa(6hGwyIr5pl!<Yt7xgfdz?K*i?1!ckm_L(e_<Z6f^)OvBxMP*<Ak_rfI@nT4&@ zu%#Ma4Z(qRh4K2EA-<8xHA2WAx9k){MQ{xAM-8y23idqv&-<)}Qm@c2dH|}6$d%w2 z#Gzu`veU<7BMN0K4$oKVBka{ncLnA-fH5@s0`&lavd2VTK?UY_78Ta|C?TUbvnF@L z`LAREqc{g4A7RviaaH^;bO$)WAdLD7!vZ8LVbvqn^Y3?IdKrhy)77vxxOiJq0Slts z^RWzIV5S^aEt0LD_88v#VioJx)fEjN9{!UHAIz}jnZmZ2BrpNa5%ViOdM98q0TsbT zvi<YRYxwf3bL`!_w`lm0BS$#b`!QQyu?203I3P?`di45DVNG6(NOxkIb``w*nOB9e zu`zDlx>Ynhl}Zs1fxKV}B&M+_-A(P9^Z`UTJ7;-2J`Q!2g~3jqJjug{4~vFRO-=F6 zYlZgsILui*5zfN=sn#6Uo@)__4&7&ar~=Q+OZ(HOPt(%UQZ)S3sZ&hcKAvN<4u<Yy zf$N##asi{zVI3wmk{if~BNmGl4F<T=e;bom@Wn>JI*dX`#+FmV^+n{E!tur$sGm>1 z%h%yRM+vD^@%8<t^#QJYGEIFb{XYC44OckP+OEeJg@eeo2wfr^YzQHl4@k|Wr>$6( z_>lQ^!w+C^6jkMXOFKC=T;6f7>O>A3h1dvf)3eZ6lMa@5d@m{M(xZ(}0C3(3hx5zl z$Jgz`QP1EuJcU<VS+H^zm6Fctq5D|tFz7Ps_H0EXvP+;7X!Sj8upBSA8p;9?@WBW; zh2&g%=Soba*YTXi1ER{my0PSH;jSj^N3-r~f^(X69to4^3f<N6wbHlLzX7Dq?)vC7 Rp5_1m002ovPDHLkV1i)=uD$>O literal 0 HcmV?d00001 diff --git a/smileys/default/cool.png b/smileys/default/cool.png index 32f918af750677d0f56eb15309fca69c4906aded..d30f4fc0d4a9c81a0972b46e4314630e5c2b322f 100644 GIT binary patch delta 225 zcmW-bF-`+95Jg>3MLEQff-Y+$sOXSMktWrGXm_0<J7n!K;~`=zZV(}H2`VJ0;Sd~w zhD*?}rv2~h{r@xhoIZs|GttGh)}%d}yP6;NU(b7EOkL6o%w8xdaWqb_QC!0f3uuQ> zx{!o#(Q5_Em=no}+u@(iR=7ifKyiIIgB+;G0aD|))%5k_W%OSbzvFZ@2yHqw&cV5= zP<vn2<|~elLqPG=^w6oMGi!ahKs)p!;g~CyjqS-}%$RLE%%is_)v^74KRSKe{vP}R D)qPRl delta 11 ScmdnX^Nedk?q(OppDX|#4g{<K diff --git a/smileys/default/crying.png b/smileys/default/crying.png index 05387b8fa3c30f0ca2a862b281f9b61b3d33a2a8..c7d313791389ea744152e7c812938a372c55fdfc 100644 GIT binary patch delta 1527 zcmV<T1qk}s3epUaZGQj?bVXQnRB3c<WdLzhZ+MQ;la2rY0915ESad{Xb7OL8aCB*J zZU94aWnpw>WFTg5av*eQWgu}>Z+IYZa&Ky7V{|ScNp5p+X>w&`AYyqSbZBKDB2Hy? zWpW^GX>Md8A|P{ZX>4VAAaG%0Yc33~yr=*G09ABFSad^gaDRDnX=iA307F9{L3DI- zX<~JBX>V>VPH%2QZ*6U5a${*>Y#?ZKbZ|N^FJp3LVRUJBWn*t`ZEtRKE^l&YFKlUJ zWo~n2b1!0fEpB5kGcGVM;j$()000E|Nkl<ZNQupteN0tl9LGP;bFLS;z!kWFm=n;N znXXN93L-UXxqrEonldnD_K(f^kE<MWYc@@n{iCaySuW?w`7*kQwW+QC(3Oe2s9Bn< zG7+$nyr6hNke73Q{c*V5SA3al_TA3*ynLVE_dMr0zn4de2=|MIO6ByM<YSPdAQQoZ zqFtaBlP0&psi`H>cfa=3{fO6Bss$pHp(sK~42)}qWq%1eXpJs}!%DG#c8MH)DDhga znyX+dkmoQkQ(PD+2@vlDrvtPCOQ3H6divnzZMfNuIbdP{wF2dNrBeNX;!4$e*`O8c z4UIJ+6(ijZ>Rwv`1n~Lc>J3cOLL+RPUCJhi7K#$DsZ{Y=*b5Y=CqZ@^7&>y<y<u9= z+y=f*0Dr11#qv2N(i6&YM7)dA!d|6VoaKScF%K>pfT3Yh2Dsv&rJcoE08~ln7YN%^ zy_fYsah3=5Fv6k890OS%6i{62WkcxP&}Xmps<~S6V_G6=QpU&#hobR1v~?kt@ND2G z9NM{pt%k<RPK#b>T2OTywtor!+rtZ-zXb2?hJW9hqUQ$x9c$2gY)ugf`0<g6>5$=$ zUik7FIDEoxXQV>&5g6?Z=N$MJ%HA0?s^IX4u%IBEbKMVDe4rEyXP3xP4Io09!@x|B zA$;{;IC?U~zzwK67R~$gV6ZI$JFB8O>27csm?D$`=!Qz=L{XID!ieR^@p0fV!pGbR z(SN+iu~-}hq_{9p6g5;Tr}mrVBP6E8AOoZ&!^%a${`AT4Qb9ED&1K*kZMTzLuzE>s zdnpNkkmxtbcVLi%*dcQ`Y+noUW3zbvi5BMP+h-bydAab{H*oAUjLnEA@9Cas5<wlU z$<_)o!H(6#q3&`jJB_cYXjwEo2}p6nw13GimY&?su9H(^asoP{7^e|DT4CwC1n!T{ zE~L{vgMD#(*zv=(yS~7d`Xc@wzk;_LcW|~bI#Ow6XF~*!M$v8w+8QRgnHHSx%m=`7 zB(d}I>%$6*z^RVs0BBDxWK+$nQ5;La5;Tf-Ezk;fT8xF`7gG3hOz`iyVieHY9)Fwr z{l#Q1xr5v@z4PdeC@lgyO1P#mX#zVR$HLqvJDAzOZ>V25Y7d#7*xZD8NFKN{)PLM@ z4(F(FPC&=9Xg1a?;h#RmTUz0a<!+-KFw0$w<61QZ@;M*OKZq;NqJIGXXofha{Q!(l zy@Tt<8GNlBOzW*;bN&}h@N|dSyMNXJ-TidAHLI0~Q0G+#90sM&<irj%0bFW<Eqmci z16*u`zJA;7a>l`oDX^;8cDdmoz)ww>118?wQd#BzP>THnCQE((*s;C)4y^kGc6jY* zS2z>q=fl*A(9#O$euwH`;Lve<d|Nq8&Wg6<^TU9Np%nWeB&F7QRgJ@7)_?RYjL^#E zRu?RI18Oe7idW#>mGD@4wBg=9*j53XciTtx-N!KVso=b6!Otz2116_)OJxp(q*Q@& z(?U15g&Qnf3H2AD;(hpRU2I{n&wcG{aJ~YPli-C_Q1@$azPSxd3oTF{7#kALE0t=5 zjlNE3y=9Me_1H$g+6pBv#&8ymMD{p1u?wc;*vA33JzpnS!luw_Hll!3s?JO0U=24S zrBv%JXlX}8IFwsTSPd5u(M2q!mTQ6LHj2A@N3421WGR+Mme2pMx;+$+=*AL`M{-w- d#7N&#{{x@XA%)7l6YBr~002ovPDHLkV1k^5-An)g delta 1275 zcmV<X1O)ri4A=^gZGQySNkl<ZNQuptTWnNS6o$XG&vZ&l8CrU=RBa0n1bILzfzpBr z8jVIS25PI)fQcpqAB+YYc))<*<;5n1;4K<_kd)xmq6w791H^zpTZkx1qXD5UO)Rvf z>9nOVopY8Cr$eWmGh9Lw{9k6z+W%hv-shZk*`li4Et+e^AAhnb#iCFk7bO#+TcHD+ zmVm{HS>+nOTYqvl;!U-(M3qW}WhiM;yAd2mF(cmSN7*kz&HQq$zc2BIpez)q1{U}% z?2J^bjERuq2fq)DfTIwOz+f192B7CUcErX48WgG)ROs=06c=d-vc(9SEravu6s+t3 z$eoS?D9{;#%YWCfZ3lz0b$$igAYLd={A8`97-ct5mOTjyvcNK9m)#k*1Fc=q*#|(K zBdjhd*TGnhZ_HlAD7!^inV$){lkZ(L3d_Ls97s)uwr*A$1(5RCCot+vO+hvTW%-%N z{Rqb*cQWK>B0yO~kS(!uw;p>#P!<~DSXLS`J!gD`V}Eh+Ds=Uuj`C#mBfNETfojX( z6lBFOv>m8B0z1Eh&_H5=v*+Q%UGP^+{M_)j;|xcStEsBdI6g2f8*&2i3zx5l{YTw# z&J<`p02BP9IeUJB%J+ty3hdtwOBRjhTn)jcP7q<~{Bo@~0IF2_EbMF#;mcQ`{+AdB z*P!ljJb&+t??=X}@MT>*Cp!Q>3tN>+0MlG6euQNisaRfdoRSPaYqTveF`hTp=EV^p zBNYo_S#z!UO~|GcB`w2)43L!$Ygdf?pECnqSQO8DXBDJQaL1EU;jNdw{bfu9l(djd zsSk@n)J>U*uyX@6CB07DKpr)(ZO1b4U){6C(0_gq4xfVOO56>2A*y2x1x6qj++3Xq zr!J&%CT}Ypvp-<t&#MyhG6Im5n;!R?ViDC*VX8sNG=gJpleiCFC}Jq(5da#)OBuZB z%^Qlq#-{bG3BH2kcyo-n)et4qAapy5ac)ytXFt?V@{M)?9=8sYlI+d<t}&mc^o`V| zeSgFDBSoGZN5N4HLbp$$LvYLDgd}gLD~c}hZMcMgdh>YmrPB#FdF<*uu>2_SW5){K z<xCtW9C3d|`PYX{3&yR-iNpaairazq#00<&hatrs=Okb8<O~k?IgUfCFJN(^5Bhrs z5{H`?h9Yp`GCZ6!64TX7>Pb4Z99xpv^na9hBhxbg2>k(z6QZg#24#=WqT-1{??e;D z`8N1uH=J&Ua~B~z<fhWXsZcZ%)|I&-mk0{{+JYUi2^LrADj$FdH4&RvJ44>N{rU~q z^f`PMbhF*!x$t}`%$f#m9dPDvIQ~2AJL1}RRKbk=ct4#Xh}c*n)Idy0Z4AmupMS-? zIr&(zol9>&EO{GF{sC{i2=A|jyzF?#H^Z=FFMPBMl6-LJQ<(eM$h_^qZ*ABSn^VOV zS^_a8RiVmuFs)sq9WGuAP3K_m$MDrAZ()FBKWtb7XZJ$-BzSrqH2yg<-`WMXgHfo8 z+HQ$2sL<mmTRZ!pqt~_d54ui&sC0(%XS_wnqF^c<{TgN#x~~IVf1Q2cDBEJY*)a{I zNMn%N;T~>WTB(j+XzNB**;ib_s2*-iMpt!2RvU%ZF3PUo9JlUupChau+dlul`u12n lpc~6*JdnHESd8~A^*=mg6G%ADgx~-G002ovPDHLkV1f<;TG;>q diff --git a/smileys/default/emoticons.xml b/smileys/default/emoticons.xml index 7116aea49..bc79d17b7 100644 --- a/smileys/default/emoticons.xml +++ b/smileys/default/emoticons.xml @@ -65,5 +65,10 @@ <string>;D</string> <string>;-D</string> </emoticon> + + <emoticon file="angry.png"> + <string>😠</string> + <string>:@</string> + </emoticon> </messaging-emoticon-map> diff --git a/smileys/default/happy.png b/smileys/default/happy.png index e53bb0541f65b0826f942033286693c66a1e8911..2707faa3e265530cf8f056fa5daaa952c0c85272 100644 GIT binary patch delta 225 zcmW-bJx&8L5QSaP@N<YE1zpxiP|-z(f+p31pxkwa>?CWC84nR#af1knk_%8FK~2d8 zI083eP5Zv5@4fHc*Zt@4WcKvpMr+a@&3(;}+n<-MF{Uo*Ic6`ElsFnE*eEXGjs>(s zC|yXxEA(2yWz30W#O?4;Cv)7OK%lrdoInoL;{d7g>+0bB>uvO36~E(jJqRs3HO|3I zRj7R^YtuPL$04A2YI^8Y)0wrtT%Zm5k#Niv%hLAbF=ouR9j4LSlj_+1ejc5EtZ#Sz E0G9hu_W%F@ delta 11 ScmbQueS~vD?q(Opa25a>5Cg;j diff --git a/smileys/default/laugh.png b/smileys/default/laugh.png index 449269dda23883231c9a26eae2b853df5683bb5d..9f84eb6aac172100bb3719ade53d4125cd7e4a35 100644 GIT binary patch delta 225 zcmW-bJx&8L5QSaP@N<Ys3c9S3prS*Df+p31Xm_0<JIUH(#zVwb+#o{Y5>z0lxda_8 zH_4jzeNW$ezxyADFX7o7=+&Lpq&=F4nxD2muUlhGUD8X;UMMMXG)}NlT);gGXopa` zkc3z0wSw!I6Um6%;h#?DxIuwHaWR=f4%FiSsqyRT=>7X`^xqV}<8(U+Eju;N!G)?& z`&iaybB>NfK=IV{(5a?#Ykj#u8}uXLm@Ag0?a5=zm~A`EqPM5jiT(RJKKopUy&bwE BQ8NGl delta 11 ScmZ3_eS>pC?q(OpY!(0;$OHfY diff --git a/smileys/default/plain.png b/smileys/default/plain.png index bf46059024e7e09261550a40e4d24f5b62364f4d..a54c67ec1803b61358569b792f03ab895c0d774c 100644 GIT binary patch delta 225 zcmW-bF-`+95JfFfAP|QbQqX0M1QlImC}>hGh<4W*vXiVmW;{e}#RX7=#3iVZpymun z9D!5NvZnp->;3<``?dER9?ia9+-ObOqq(d3Vf+2EHOAB>J;&^Yk`hPb1RKQ#+_Hdn z2&D^2c!gdoxQscGjJO^C>12)@6bKX-hZD$wdK@4%eq9~BeZG$VtKxT@t_PuIr^Y#$ zsS36CWo<g==r{xvPfZV<YC5ylmkYE(KN60)Vp-arJjRUKw!<`fdr}?SpO2%{_x01x EAMGSjivR!s delta 11 ScmX@d`JH`2?q(OpE@l88O$1l~ diff --git a/smileys/default/raw.svg b/smileys/default/raw.svg index d2e921d77..6850d04a6 100644 --- a/smileys/default/raw.svg +++ b/smileys/default/raw.svg @@ -23,6 +23,17 @@ id="title4628">qTox + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + id="g3980"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/smileys/default/sad.png b/smileys/default/sad.png index 2460dceb0ae4965d96ff35a2daab66c4994ec32e..8de1451514ad6bf2568ba1fb8ca1556e322adb73 100644 GIT binary patch delta 225 zcmW-bF-`+95Jg?k5OD#zAq8F5NKny5hJq&5f@pW0Av?+1W5z?oRy5QR5|^Mtf|^TE zQ*jg4wEum*|DX4NCNJU1O!V?rYtkOgea(-%@7J9%rY`9PW-pYKI2tF|C@$fS1++sb zT}Z-f^jg7H%!y>g?eI^h3*4eWptwAmLJrj90IBht>frtBZS-FkzvFZ>2(3Cb&cR$& zsC_7Fvjs=TA)t6_dgxTsxwXDrpe_25aLg6U%J$?jX3Vx7X3^Wz>cswj9-n<|4)^{5 Dl^syF delta 11 Scmcc3)xtR;ce4wlI12z81_Oft diff --git a/smileys/default/smile.png b/smileys/default/smile.png index 3f209d6e7d4b9ca9b282cd3cef97975d15b1627c..6901909be18abbe4aecbf1ae91d2fa57de09f003 100644 GIT binary patch delta 225 zcmW-bF-`+95Jg>31r9N!pvxKwDmr8+Xi_bRcGnrQL)IQM9wN5l22mu=fRri{)Leoi zP;m{`wEum*|F@Ih!)ZW#iVJvP0qqb< z7n1NJdad9l=0q~$cKD~$Ij&J4P+S~OAqVPlfYkU^b+rH5jsDx>cbx79p=GDWIk;36 zYM;y6Y|hbf2q>PK9y--@VXZG0XpMd(9CO98v^{x@8MAGNS@ia-I<-HaC+8ol_k%yI C^HE#? delta 11 ScmaFPJ%MXN?q(Op#Vi0EAOtA@ diff --git a/smileys/default/stunned.png b/smileys/default/stunned.png index e9df6697a0d2756e0ed271d18781e64e9d1eb57d..e7b3b8b0024649da294d2ab37dcacc73a0df4183 100644 GIT binary patch delta 225 zcmW-bF-`+95JfG~pol{ZDd@6Bf{G3~6f~(8M7!$@*-6$OGae$g;sy~C1y`U#f|`OW zP;dZl!kYHKulN7g{>$VkJerAK+-ObOqq(d3VfX#KGse^zo`!1K3_-wRq;Dc*MrciQ{x<* zs|vOEWo@?L=r{xvPfZV3pol{ZDbi()1Qi`}C}>hGh<4YRWQVLhW;{e}#SJ1PPC!RRK~2RC zI07}7U`_kq*ZcqX@N4oMp3FoqZ?z`v(cIVkxc`3H8)NE{E--tcq{PuU!A5ZfYZlNB zp>!b$-=WtEu3}CkBW{O(I$h!p1p>v@@f32P9tTK`-&RNOpKqi8y7(QZn?Y#Psc{Z2 zRE64yvNm6GbQ}VTr>2KaHJw}Q%LUq@9|^}?v21Kl9%IIA+hHEPJ*`gc&&TZSb$jp! DhqX}J delta 11 ScmX@a^_pWs?q(Opf6M?LR|K{I diff --git a/smileys/default/uncertain.png b/smileys/default/uncertain.png index 155f90204c6e36ac689008834a0b6cf15dd358cb..64f7694361d25fd6b680c1ef2e2db16813753ad0 100644 GIT binary patch delta 1257 zcmVWFTg5av*eQWgu}>Z+IYZa&Ky7V{|ScNp5p+X>w&`AYyqSbZBKDB2Hy? zWpW^GX>Md8A|P{ZX>4VAAaG%0Yc33~yr=*G09ABFSad^gaDRDnX=iA307F9{L3DI- zX<~JBX>V>VPH%2QZ*6U5a${*>Y#?ZKbZ|N^FJp3LVRUJBWn*t`ZEtRKE^l&YFKlUJ zWo~n2b1!0fEpB5kGcGVM;j$()000B*NklwjZIVREPfCFgM`fQXT?lO`zVx~g9DheKSE4bCG9W_V&QASuMetZe zb_pB?LLLj-Uy0?ff(kEqJzxYJh13Gfr(pVTn4ZI4u(5!cLU$;vC(DG3#3CFtLXTx| z8tbrvH6Y7v1yCTKgwyA-Z3lzWyEDuo$Oq-YhoVwploLQluo^bigJqV!w!CZy#-|`Y z13zSM1pps0MeQL1#vgJqJ^>sH5yoAHvMe1rA#V zXH)&^gCTQvoW;L~4172$`+!hm9af>kb?Qgh@qZZXeG10T76-g?47NT1&mYORSq2*G zuz=7a&xNbf<*~4XHHCxrybIrqz*j?XBvROCV$$^+Jp->Dho64W_X*a3$HG>n3&4y- z#f#A9uf!_$A6Hive$H0Kdhl58vk3Sq@_hvGS7ITwjYP%kN!qlC!RN0kLIz%c8ocYE z{(o9H@L*w|pdXIE2**ByhgxCt^@aWXRS=)Smvm^6p$Pj$`QYXzxMp4P1XfEIFT)QL zAh6#EG=N*H{|lu#Dr__;0V6o3l)}9VGU9ealz>46I!EKBG zR+krGcCIwvG)I&_4K`!o_TzFDpN5x?LVx3ZP`w9g?}A&q;EfMmTOp-6j>EY89KkyS ziJ%W(IW>LoJ7_%s^OxY>9dPG%_$vY5{^}Mae+|6z96a2b``+j|h|e-x4FOMcr>4G+ z$iVa*VWoJX$q8@<+Mk6Ru7i)?gd4Z!+Q0t|o_G}=c>y-o!`-*J>xw(+pbRvJHGgFQ zMCe{uZ>{bY(rBgasQ*gg#iT?Tf=+Y;p9t zs^0qqe)$7FdKtDg75DR4(6+~|jNm4F`aCueOAnWs9;VQ3JDBmQ;sGzF+@^8Q?Xb7y z>Paru_!QU|5G>{hu+7_15aLXXE{eXls(PnbZ>Xc zq<T>V-&hLKD^Z!IuDO96T@z1(6@R6t-R;2@>6(x{sk!T>3@Um^uk)u8u(CDN{rG6v{mhfeU;#t+-950wJ<&nu>=4gTA{Nktc#g3 zzMOv%qx6Yzq_zU8_Y@CJ%Q0|ZFO=?ti8x1$0!TP>1hV=x5}^lZtF1t`0?t(R9;mHA zfVSZXr!v2-4Eu0IT8!{bWdJ#_cYDB@x;6#VbEs7wN`EiHm7WWnaSV1}<@SSNW$oDI z-NOoeBr1o2#+q`Re2Z)FN2q@q9(xhSZmth_?IPUw6r4P}_M2m%rW^-oT;_RjRXThQ zZdEXU(w=wVyHWUT2+l_G$4pFmao2u>*Dt|OzpRa^3WCqURiy*Kj7G(e&>AYmS#KZj zF3ta(seh84;B&lZ5eSs5jS(PJii6NP8Wq29)}>htfl%2xWZ;eC;NJn2cfkus^T$+$ z;L@vb@gq2P2=?ETKQ2@Tu>^rxOS23`=o01K2Wny0j`e?FyY%-G{4fCmT}Gf9ytDdt zD9usfZi7-`1ZxU8xVJ$@ylRM2VG!b0F}CoszJDcI1*;f@xKWq{uPojUr8%Pf?!#pa zD~sWd2e-GY<%JL5D$87uF=oz{~<}q0^pRf@7~h1m=i$awc00v$Iw%8mVNDtU5&BauPHc8_aAE--Kkg0f7w6!KmerFD;E{Ux`T`tk zg5C?+ZDX^La&biHhm4YXH6lYkhx!L=^A{KJ=CtKmXt*EV>fU&6bLCq2egZe;@@+%A zHbF*7Rp@ptW_)`61aH0vfl_$;rQ*QgS$`_mVida5?^aSYw(Av?)3F3h{NRg`%qRSpG%SyffIb6R9FLxCWo`|EWTyAJ5%fscI=&Dwv z(s(U^9XmQXS_j=h1ow@e;|K-~=b%$;&*}5ZlwOnoYE%jgAlfyx^3l14* P00000NkvXXu0mjf3f=k5 diff --git a/smileys/default/wink.png b/smileys/default/wink.png index 810090c0d2454cb6422cac3f6c26a3001bc416e7..dd112dd6a6bea8be98bb07714e9cd15f67e3fe0d 100644 GIT binary patch delta 225 zcmW-bF-`+95JfG~pol{ZDd@6Bf{G3~6f~(8M7!$@*-6$OGae$g;sy~Cm!Lv|8i_M- z1UfE(#G3ZMulN7Y{^#T=JerAK+-ObOqq(d3VfXdCGse^zo`yhKVC-vRq;Dc*MrciQ{x<* zs|vOEWo@?L=r{xvPfZV6W6$GsS From 3b8352959669c7d88300acc8ada0cc5d18b40a1f Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 4 Aug 2014 09:13:21 +0200 Subject: [PATCH 031/149] tweaks --- smileys/default/angry.png | Bin 1515 -> 1566 bytes smileys/default/laugh.png | Bin 1455 -> 1474 bytes smileys/default/raw.svg | 1035 ++++++++++++++++++------------------- smileys/default/smile.png | Bin 1511 -> 1444 bytes 4 files changed, 515 insertions(+), 520 deletions(-) diff --git a/smileys/default/angry.png b/smileys/default/angry.png index 89a26246063dadf4d094fb77bc79cbc5e7f6e2db..567b6887bf82d5b8b549ae34fb6ecabee6c50299 100644 GIT binary patch delta 1258 zcmV`UCWGlsQaCybU`2;WnS`)F$Ee2;`HU_2sRc8Aq z=gau)^D`Vgc(7pj(W6H>Gx$DD&p3H?u_z$SmRk(kjRBLm7?l3l9Gyn6awBgHOioU6 z#0eG_77B*P<8j`2 zKHnalhLnRP!f9AK)tUol;9^k1BX`+XRf=WhO#723PtwxTQZT%?x0jh)Jy|wK!^mA6 z;BqFpT*esaax^M3p6y79CK8Dh3}_1 z@}0j7uXTAyCJWE+w{P|G?T2&JR;9~hQ)#$?hXH__eTnrKt;ZR)_k{LiUl@42> z^4O61>&B*FcmiV#XInbS%HeX-17ozv5oI7UPRHCL)K{mSc?xF(>A^DAZ++gH&!6vsd3zSk)&rR_LvEd*M?AJLi^Fwho| z1tjVMk%VTN802qo)0GLoT!@jnBQep$m>`BsBMWO2U;zuU4uyr$pkherv=OS)GNnK1 zOz%A|rc>ufp;M`Tlec*1o_jv;-goZ3=ZdOQtbXZ|z_?{69vgoJ>QO=nqYA@V1}Z&z zo5GqbHl7p%@9UC%svJVuk5G}Zn-tEKU=|#eNrY|@&Nhd&=ZWCai0l%j6QR|g!3J;Q z1%HLIVF)|`lLA))$tswshs2AJcnLdKhKCYWp`*23zh5R?BpTtEfur6OZo@^q+Up>0 zsj+|>h;N6XH?V(pH3m4*+|K(@2r7X8&?RNYaR#BS_69V51K#Y?(0tiah`j~zZGiH% zGaTL#)|qS{Kkr+_IL?T0u%R33uPz^&kv9vQyP*6Y4DRQkaR3s|o&l5Hp)bNwgtmrm zi-3UTkG{Uj$wuNbrMr4Wz>RVEaRPpxgxx{7xHZ?O zb`XYUv2%Z=90GdeW`w|mGFm%8#pb@kQCx{b&pr5UBK-_Z!`*#QSDNeh!X+4)g{{@F zr5auh!GU#!@%oz~zLCi_LdYMt>=Z*qa18QC4X~#Q_B{K~`>cghuh1`g0IG|~mEah} zp<>*!)5l{Y3S}$~&sXUq?A1$m1?D+`F*N!D^#Ff?vd2VTK?UY_78Ta|C?TUbvnF@L z`LAREqc{g4A7RviaaH^;bO$)WAdLD7!vZ8LVbvqn^Y3?IdKrhy)77vxxOiJq0Slts z^RWzIV5S^aEt0LD_88v#VioJx)fEjN9{!UHAIz}jnZmZ2BrpNa5%ViOdM98q0TsbT zvi*Pa%WL@Zt8?t#ySHfgkt0Vq*ZVPBUaq{HfL))}Ct-i4NUod#HZ`&&x~u)2C0<($Z2i{M4yaOx!-6W3vv1 z?qh-Lnc{K*qtIa;CN`2A$cQ5rixmw9xYK_dlUMM?M!-6ZLPy4yQ^WN|`D$~XJsQ7QVti*p|u|PRW5Fw$^i%Vy~ z;dH28N2lvgrbB)vDzB*0fUp6jC~Y@_wThYWMiQk}gs+y>>(RR+k40paz&@bX=irtU z;FJ`?TtE1IU<9nfXbNtQ!oUy=4CAI;93ZC9R2$Y)Gb9&@MQAp{F2`UWeh8;50CK0R z01EWqfSzl(uEl?#>{%A(J;*1@BX5t&T%#NS>dK0tsuUcPyY0?!Ep)}9e-MDfR%l#N zuQxN-_;Su7MmZqDrph3c&zm`E8jgYL1yC>>x)W?N3Ly2FFOYSoGZA(Hb(KNnZiq8c zJ`XB`2v8S`(409p{_L@ctTMvM(jugK!M!2Q#P59&PojTTc_tl%<2M)B=NN2NY5vB) z2jRnm@b&j_J2koU?q1llAKE%5pC5}IJC;2jr>ds&_`65SU_l^z(_j7YSREvXy>X}- ze*G3CBlM4-g>^e1<$B}IFG9=v`3LB`0hjwhg!Rkn^{4?*rNQUmmId-Re9;PJ^WmM> zVcSONy9R&9V%cjxJq*Q#9_f-tA^HRS*_ZFDEC4X+;_#=zBMFl#J#_8oxV{(wa}u_Hi90ZxCC4dtJU`dX&x0S3`)=l)=Z~x-vb!&x*El>hmQYC)XV_uSEo3**N%^Gj%9+ibol}frw1W9Fho&0)!uG^ z=y89;PbXt6T)6N*ky>kc{<)QeU+BuR4-5f9GT?C97pm9Mj)=4l3=>woLKCWnH^VMF z-q^~PhOLOqJQ_PYFH`J~vwro2P4SctN^2;rqf^#)*TUNEg~W#zapB^n84(v37c8tzO)niY0emF7#RPYxM&?f3KK6H9n?QzL&h zH8oUJRM6AY!^MjiXgT;9{e3-r**wgerP+IXuY2SQduqeFds1=`>4*>=({OoG>eeV6 zIRQWZJe#iG*<8Kmz0TtDTWnl&i*>bLhs!1IPN1qBSso@!!#z;-`v21HnRq}ymTWwb gzgjNt^)K}wC;JfSsV?gH00000Nks-uM6N<$f-lTGiU0rr delta 1146 zcmV-=1cm#;3$F{XMFD?RNkloL=-w2TJ_W-;UbYRokrO080?DWIOPG5 z+YJR!V0av&qqu*r#h~n6*UEd44a$O_?v?_h90Xd*i=n0r95eT^+sm~uI0D1h0O+wo z`;#HPo*v_y^Iya$2SwOg9fZndi-)G<7+6^Wg-hUKoUKLyB$WOJGR8CzW;f7M9YpR1 zoUY1cP#r{omPnY+^tPGT9tlgM5l)sBAuB6#15VfZ%P@bEK&|q0Y7)+jTwuRrur+15 z2gA(VvB}lL41Azlwg3$)mgCGfxla88kG~4f?}Q7NZVl-C3|2M6?oYGZ90Mzs;{Xjw zo(ET@&FA2j2j=he!!FqP7*tonCx_>c`TG(a?DOKfzJcHV%8n@yfX~5Ir42xS597ZE z@$w>yZuNhye?15F4`<(}Yj6mB4m?-^BUij@b!~Rs`O7ezAW;lKIemzYV))^aN+?}A zKRlNjn}9!Kpq6J14z=K=%zL2}#~5miKqYv&`d%o-QK8D91dU+LLK1flWW?JIQGx~` zZWUt}zOCPttb$bxLfoei6TEFPKMxXqawvxss03i`@==ZG&>C~C9^o~u^s^AE)^F=sx%+S}@OMQJkB_$<`h95oJ zM?rtS;qBM#Or7F69hBZRtvclc5TR?@<>ldVs0e^R55D@q^5`p*960bXLqoAU8vXk_ zp!R{;^6)rJyEr0rK{B@|&0ZvFeE?YX5PZ4UWi);nzkl%=sBx{~t@hcnYdvcPL{jE* zCbcMZxR#THBc1~RXnqDxeQs%f)8*e$hi!k`LTuQufr5g9ELb9upr@yY6DLlvWj!3; zXYuFFwhxYgYcUEPsk#ggHxQOig*`Q8nHFkv9NOL$zU@~E3-j5uX)|?obyQVV5sgMU zd-g2HkAKIF8#n1_hkb8=q$RD`RS&MPx1m+{%nJvRGhw=u9xlsD{rEF{@ilz^lS6Ve zX1O`7`16G7O5ue@%Z?D#)nq;sy9yWMs47REXeGnL&B^GhR;1l1435w;c_Y)ku3zh2 z;9@OYNkD0_B9fgR=eXA+R%oAVpZ{OJJze+d#FDA|a#owGT%S_^1M4gCx9Yz!jsO4v M07*qoM6N<$g42&LJpcdz diff --git a/smileys/default/raw.svg b/smileys/default/raw.svg index 6850d04a6..33feebea7 100644 --- a/smileys/default/raw.svg +++ b/smileys/default/raw.svg @@ -200,10 +200,10 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="5.6" - inkscape:cx="132.20639" - inkscape:cy="56.459967" + inkscape:cx="123.74561" + inkscape:cy="60.133234" inkscape:document-units="px" - inkscape:current-layer="layer1" + inkscape:current-layer="angry" showgrid="true" gridtolerance="10" inkscape:window-width="1920" @@ -257,523 +257,518 @@ id="layer1" transform="translate(0,-796.36218)"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + id="happy" + inkscape:label=""> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/smileys/default/smile.png b/smileys/default/smile.png index 6901909be18abbe4aecbf1ae91d2fa57de09f003..898fd0140b7025263abc32bd3516f7b27223472c 100644 GIT binary patch delta 1135 zcmV-#1d#jZ3#1FMMFD?GNklLfOq2rhybu_D4w2KbvNSf%KP{&|H-fc_nd*%Zl+z+KtgO**?+M=ON|nHVpu*?i z1p_$2EXeeO-v>s(Dn!R&EDFP;Fnj}V+`|D{6?RpG^yj;Ti?q7b8==lI*u@KQ3UWd2 zG!#IAfe7?n#q)nG24&C65FbD)C<7$%=FjpEYCvEAPigw;A<;v zU0tJNi7~!u-y%jiCc>tYJSduf_t3Z;17!;#kO93zY%&TUHHkBjG^Tc!I$(229&#_> zL>0}4k~{?1-0D)F_-u08TV1I#LQ{S=Qnqkzz=^ta1qOddP^&y0Pr}KO3+#6cc1ix+ zgJCjv?8NF}65bw`^+3hq1vu%FtNAxr@hZHq6T1JJ8Sv2&c&r-UKal#&F|c?64p1?{ zi@{Z?^*MM2x#>HtI|v<}@O=v$aMQ>1_Q&Eb{R#Vy!tY(FF$KBcbMRED1u&gq@gr;u z25@Ft$2ot2^w){X%mAMgyB2}$%+weGf&mA8BkALUSuk*&?1-gOT3oh^^2PEJcxc|tA23(?=NA0h3j*7X zKoP|D>ieNMM}=a8l4k^KX0vh6fsDkeAxfS>7_xtgv9mAh_av)e6@xHj6#5}n7Vn4R z98oU&@aV?G>Tx{bcI<_dXZ>>m+puPw<9qGo{n&)hv6dcRu0!*67#SX&T5j*wLinuV zr>0g43k&}f)LP4P&sGw8z9*@DcoYyuavhp|h5t`~oA+~b#3AzdAt3RP5K z#+uP>FJ@}_vQj;N{=D8!jg5_3SdgO)A4*am+JSbRLEBtx%L%ID%p?!j?n=GF?j`xD z7V5K;hPu!FEPvv0syA(A>C&YX7Z=ml*T;nmfAH1u!wg*M6+_P>c6a*DT7u~YLWl|002ovPDHLkV1i=q BH^Be^ delta 1203 zcmV;k1Wfy+3+D^4MFD?}Nkl3ZLt`*Bj+=0CfG&l7HI4ei9l}Mr!W=TfLC0WMt;8uQ z1i9U(01CuMAbNiT*R>dwBkLP^6EZ;=@XmJ0HOeWVzN7#uL*SVCkKJCbh3f+lzXiZ2 zR%qVXpcAPvzIpE=MmZ(Iwu)jXE4p)NQjUQ&r4Y!5{z0}G1(1f+8A$u4o-hZ2`if%Y zUcjj;D}st*1gP%{b13!R?6h}}-ioc(fvqmIE= zhL#@;vunrB>>g&}J?*j;s9CiVXQ9Q_@iSDv0?)k$*Zy1_@b(FK@CA7Nc;-FFz^auv zK+O!#gR9cyb8t%v7asIrD@1zXVkaCAFC5b!^WyscfOk*AFIO{TN(#Z};HuIDV0zod zk5Cs3;4FW(j|&0|w^Nmy4L-+fi$H#EW{d#A01iT3Z@c(?BQBf7kRQxjgbcj57yMZe zS^=-VxNuBK5KbP36X#*av#|Psh2w&G5WhwKh-H&>hS?>`M~_uNPS)Ztuw43Q8h+{r zfn7$R47^Pp8^M~TB<^L95w9Ae6dQkpL8}uvj+xlE)RG`0mLrOT~EyT9BaAm zD|G0%1*1b_-ge6mz=2(`?|s<0b0>9mb$11gMx*TCzn>jjAlpCJKQsmiqlFF~s487; zoQZ#&C1E3|M$pMl^ofU!78Mm}Utgczjka&E*W4VVzkTYBsS(sh(8yU5U2U9ERj;0l za5~}gQhWqT3%!KW_KxN8m&d8Dev&{S4`Y_@D8|Od7#JAftv%_&UfmxgR&- z^5cd^-3WlHqN;SZQQIBHUcE3kO&UQXr_joBN3*lD^w_auIy^kQ;55hMaoxRpw*uO* z8J*}zALr@?v^$LLY@;^GO!II(VL7C5xH6P(p>B*o(;LE<9ZDdO!{*IfsH&=>yu5#$ zXf(=|D_6L5=_@8Dr`gvGEqlGxe@%W|>YX{w$%QOnAQ5vZn#6D$}2d4MYDRs>-jTt}Po}%q zr`CBtaIqF{jzX|N5y?!C^W5t>D>N(5x6l7C-=3=bbYe-@eL1Vm*K(gy{{?q;bWA+X R?S23N002ovPDHLkV1kd%O$Gn} From 72c72a4cebb6276803a8c36a02a5a85883757d61 Mon Sep 17 00:00:00 2001 From: Bill Winslow Date: Mon, 4 Aug 2014 20:00:17 -0500 Subject: [PATCH 032/149] Updating to latest file transfer specs --- core.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/core.cpp b/core.cpp index f4933c3ae..920c28218 100644 --- a/core.cpp +++ b/core.cpp @@ -249,7 +249,7 @@ void Core::onFileSendRequestCallback(Tox*, int32_t friendnumber, uint8_t filenum fileRecvQueue.append(file); emit static_cast(core)->fileReceiveRequested(fileRecvQueue.last()); } -void Core::onFileControlCallback(Tox*, int32_t friendnumber, uint8_t receive_send, uint8_t filenumber, +void Core::onFileControlCallback(Tox* tox, int32_t friendnumber, uint8_t receive_send, uint8_t filenumber, uint8_t control_type, const uint8_t*, uint16_t, void *core) { ToxFile* file{nullptr}; @@ -280,7 +280,7 @@ void Core::onFileControlCallback(Tox*, int32_t friendnumber, uint8_t receive_sen qWarning("Core::onFileControlCallback: No such file in queue"); return; } - if (control_type == TOX_FILECONTROL_ACCEPT && receive_send == 1) + if (receive_send == 1 && control_type == TOX_FILECONTROL_ACCEPT) { file->status = ToxFile::TRANSMITTING; emit static_cast(core)->fileTransferAccepted(*file); @@ -294,7 +294,15 @@ void Core::onFileControlCallback(Tox*, int32_t friendnumber, uint8_t receive_sen file->status = ToxFile::STOPPED; emit static_cast(core)->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); file->sendFuture.waitForFinished(); // Wait for sendAllFileData to return before deleting the ToxFile - removeFileFromQueue(true, file->friendId, file->fileNum); + removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum); + } + else if (receive_send == 1 && control_type == TOX_FILECONTROL_FINISHED) + { + qDebug() << QString("Core::onFileControlCallback: Transfer of file %1 to friend %2 is complete") + .arg(file->fileNum).arg(file->friendId); + file->status = ToxFile::STOPPED; + emit static_cast(core)->fileTransferFinished(*file); + removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum); } else if (receive_send == 0 && control_type == TOX_FILECONTROL_KILL) { @@ -302,7 +310,7 @@ void Core::onFileControlCallback(Tox*, int32_t friendnumber, uint8_t receive_sen .arg(file->fileNum).arg(file->friendId); file->status = ToxFile::STOPPED; emit static_cast(core)->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::RECEIVING); - removeFileFromQueue(false, file->friendId, file->fileNum); + removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum); } else if (receive_send == 0 && control_type == TOX_FILECONTROL_FINISHED) { @@ -310,7 +318,9 @@ void Core::onFileControlCallback(Tox*, int32_t friendnumber, uint8_t receive_sen .arg(file->fileNum).arg(file->friendId); file->status = ToxFile::STOPPED; emit static_cast(core)->fileTransferFinished(*file); - removeFileFromQueue(false, file->friendId, file->fileNum); + removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum); + // confirm receive is complete + tox_file_send_control(tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_FINISHED, nullptr, 0); } else { @@ -989,9 +999,6 @@ void Core::sendAllFileData(Core *core, ToxFile* file) } qDebug("Core::fileHeartbeat: Transfer finished"); tox_file_send_control(core->tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_FINISHED, nullptr, 0); - file->status = ToxFile::STOPPED; - emit core->fileTransferFinished(*file); - removeFileFromQueue(true, file->friendId, file->fileNum); } void Core::onAvInvite(void* _toxav, int32_t call_index, void* core) From 25ff5c5e1fc21814d440bc0ae247d5f5997c4ecf Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 5 Aug 2014 16:40:41 +0200 Subject: [PATCH 033/149] scared, tweaks --- smileys/default/crying.png | Bin 1618 -> 1612 bytes smileys/default/emoticons.xml | 5 ++ smileys/default/raw.svg | 85 +++++++++++++++++++++++++++++++--- smileys/default/scared.png | Bin 0 -> 1721 bytes 4 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 smileys/default/scared.png diff --git a/smileys/default/crying.png b/smileys/default/crying.png index c7d313791389ea744152e7c812938a372c55fdfc..06702cac93ae90345d655367b2e63d7abda87937 100644 GIT binary patch delta 1305 zcmV+!1?KwF49pC$MFD^ENkl1o64g=Gb zis4Fwltf5$fL34$34)|kn5KV)M%Ys1W-G)B#faC}s1z;i0m^eGz~pQ&bo8=2!?d8a3p#rMsI?Sp zODd!<+{Y31E=mh~lwxIm7UWI5d(jXK4O4R=H3{0fS*Zm;RfKN@YDx^*Wh*0S;FmvJvxBmlmKZOz8 zfZAiRemj4@9vO?k&e~X?949yoOc5#pbaRbLL{a8S#fTTjDM{ckB5lsJSifjnJRb$P zQZZ1JHP@&_?Kde!NO#3?2FT8U_0Nwy7fy$#7smR%z8X@K?eTjP$kGZ+N0C+^pTpv#2ie=cW^}dx zz>ecHS#@9om;OqRuxn*kLxe1iqT3R*6_(; zOOJo+#C1A*0?^7dvbpVgK+WM=;=1e@`X9~GA->YU^g5n0#1Wd zNzF$E?Ee5h z-xyyQASn^vd=bv>hl~mE_y%Y^KQe#c+6AVC7N`o@hQ;T*pM34AKm+MFD^KNklae5wMcHpm;%$ zmvesoak$)9e3@+a-Ol#Be4pRR_lt%~<@B56V~~HNAQQoZqFtaBlP0&p zsi`H>cfa=3{fO6Bss$pHp(sK~42)}qWeGZHjV^@4O0j=-i5z_>@mjB%t6(dT=P)o+ zTo@?{5bp%11GEB5pl<+r`rzhmxY><4U}6BZ0_Az7QvHD9O4WMVpcU&4jWr<^Bi#+^ zURwbK@cH5D4NQO2LL+RPUCJhi7K#$DsZ{Y=*b5Y=CqZ@^7&>yfbVqVaz^v~?kt@ND2G9NM{pt%kT2OTywtor!+rtZ-zXb2?hToc^=LY{BYtVaaO%VzB@sWw?kl~JA`0^S!e8O&L zq(bu%80`$_9QYQ>-WfEi;P8jApdg%c-49oMpcD&dm&j2KAVQhLz)X)JeDz;AdNRbo z4X8R6&HI1!V6ZI$JFB8O>27csm?D$`=!Qz=L{XID!ieR^@p0fV!pGbR(Y(m9SR4hU zxG+!@HB>66_M7A*B&Nh51EeLx%0^yxiv0s7OMU*>vAz2atosCZcBhX-7mj zlv_$z4Hps7MJ%P3Yk}rAio1J9ta?3UDV9f;&;PHwJrs}V#uAQ4a#xGQNZ%Jy{{x@X VA%)7l6YBr~002ovPDHLkV1g!mkS72D diff --git a/smileys/default/emoticons.xml b/smileys/default/emoticons.xml index bc79d17b7..e78080516 100644 --- a/smileys/default/emoticons.xml +++ b/smileys/default/emoticons.xml @@ -71,4 +71,9 @@ :@ + + 😨 + D: + + diff --git a/smileys/default/raw.svg b/smileys/default/raw.svg index 33feebea7..0ffa03c04 100644 --- a/smileys/default/raw.svg +++ b/smileys/default/raw.svg @@ -23,6 +23,17 @@ id="title4628">qTox + + + + + + + + + inkscape:window-maximized="1" + showguides="true" + inkscape:guide-bbox="true"> + + + + + + diff --git a/smileys/default/scared.png b/smileys/default/scared.png new file mode 100644 index 0000000000000000000000000000000000000000..595df46082079f7327bf0bc7db6684cdfd3532b3 GIT binary patch literal 1721 zcmV;q21fabP)V=- zLvm$dbY)~9W^ZyJbZBKDaa3=3AaHVTYGq?|E+9#6b8u;LWn>^?c_4IXWgsF>Wp-t9 zAZ=-GWFaCTb8TsCWqBZQVPk7946eMW00010bVXQnLvL_-a%pF1bO1v`AVG9=a%p09 zbZKvHElzK4LvL+uWpZO_VQe61baZe!FE3+qWnpw_c4cF4ZEbIEb1rXkXD@7NV`Xl0 zWpgiLc`a^ZFEcJMFX6H#GynhvUr9tkR7i=vms@NUWfaGMXJ&TW?rxW|rC7jHLF1(; zs41mvgQB4l1(Xz9V-O)RKH!syL=zLCMMGkOiHUC-qY0AeHj*e1jmk~ZQd+!Jr3TOd zVr;dvlQ|T&>#b#UJ;GVsn!~Axb_%mqG^~ zr@}UkCDrO)tv|UMcyqlhQ)RVctq@FT=zYrgjbpji(6eGC1hZ3w?Pb-v`(MGEVp4(1 zRuL`l_j0|X@u+hnuXPx9Bt!V9`QvmRR_DDq%~fN z&sKbP|24w_4s@@jCpDc#kq@g-0i=3#2F66*9Ft87waq@St(c=d#Vhg24>XI9{ds=2&ux9d!C89DXdh zgc;dw#z%51un;aqerX@?IyUeSf4FngCZ7KF4|aXHmq0L^m1`=QoIfceVBhX0jx_wp z+|t`wTD2%`e7gS!Zp;1x5tf%#>uv`?mDMS-yttX2G3vdae$DTvIsiDbznPU!MAK}} zbtU-nlLl0k{hu9XVZ}{Mn-Ljf6F0L-k>xo$xEk2)wAG6rWJSUh*#TcN%_%@IXJmip z285t5ef67wi){<3lp+Fo!Bj@OgekJ~tY25O)r;SWdql<3kShgT>0dwn)E#8|4Y|2l zEPr@rM!R4H)~}z>{{1J3MvEw(CP2EKO9AjpDDDxJLowEg@?MvHKOVu1@QIX7ANk$^ z1lBnMg#g(;lkrO@UIsi+VVZ-I50(i!1OI$*Pnax&ntTVL3pG~INr3zhd^Pl8EQBsc zp+kUdD~@gZ{&TkHU7!yTrQN~f6c#un2>7!8b9lcu2!Ju1cEUD|y^wGR`$7ew)VLFk zfgO95Z;$8l^C_FY0UziEX3y}LcXNW}_bEj;$hbaw1_wb%gl!s~l4^Ai$7E;kK&mFk z=h;`9`pwVq!dp{#VCh;OfA&%4&6`I!9L5;K@#Dv7X>MZO<~r7|Z0G4mGM8}*^bV+p zva_T{-7#nTtOA%CPM@@=#p1Q?CA|N^E{cnbuNYM_ndF7%pCLE(8LvOrlQ#ZW98PvJ ze6|l?sfS~7$g!D!_e^Yi)S~a`f=6GvkCnQAzpvuU0!{0G21u&Iqc{3S?~;&!iJ%D!|?JNZD@{3U1u+~fh;JzbZZ{? zE{iSiEak+B6Ks6>Ioi+s#ND^1D803twNXR&c{tN<@y++SY^e<}_nt*OShN)A1Ry!&%YU=@uwULCb`r;)5-jj@l)Q=3j4kbQ(2l| z!JUSV^YB|2s>+T9HC(xdgNxOxrECLM734zk6tJ)3;PcGIRCo3Q@Uaons@HMrc1zf3 zTbQBvG-9KfC&gd9Kk9k2w9f}4V* z3+MXaTt8mQ!v>lZuBT%etD#;EVFk)?uVx9x=%_YENT5tiuXed6x=Z~V$4GVTd4;uO P00000NkvXXu0mjfBWM_m literal 0 HcmV?d00001 From b640c095e76ed1f3d02a48ef52dca072c4fb9a23 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Tue, 5 Aug 2014 16:53:52 +0200 Subject: [PATCH 034/149] black, thin outline --- smileys/default/angry.png | Bin 1566 -> 1476 bytes smileys/default/cool.png | Bin 1597 -> 1578 bytes smileys/default/crying.png | Bin 1612 -> 1499 bytes smileys/default/happy.png | Bin 1435 -> 1384 bytes smileys/default/laugh.png | Bin 1474 -> 1385 bytes smileys/default/plain.png | Bin 1230 -> 1219 bytes smileys/default/raw.svg | 28 ++++++++++++++-------------- smileys/default/sad.png | Bin 1371 -> 1317 bytes smileys/default/scared.png | Bin 1721 -> 1742 bytes smileys/default/smile.png | Bin 1444 -> 1386 bytes smileys/default/stunned.png | Bin 1303 -> 1293 bytes smileys/default/tongue.png | Bin 1346 -> 1321 bytes smileys/default/uncertain.png | Bin 1350 -> 1320 bytes smileys/default/wink.png | Bin 1343 -> 1270 bytes 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/smileys/default/angry.png b/smileys/default/angry.png index 567b6887bf82d5b8b549ae34fb6ecabee6c50299..e096ce5ffdf4f5cbca495e868cbb582f2829e957 100644 GIT binary patch delta 1203 zcmV;k1Wfy$48#i|iBL{Q4GJ0x0000DNk~Le0000U0000U2nGNE06Q?QqOl<)0e@;q zL_t(YiM5wqNE}xb$A5R68FiiP8Wh>YG>R+egSEAJ&EB4>2i}(wDq67NroViG+OE2<w0Hw9aA%`pts$J_j!>59Lqzr`|uiqULnMjpgkeh6k2MtDSOuK&4iA8^xAC7 zG=-1W#)Om-A%r(i;nAG{zJH4B=S>?&a2fWDvJj53TS^&H0d$47#zM4;qGaWF{sdb> zMQ*YbXV{a8Ww;xLyC&RQ{eD#jhYRBK6+q(x+7C0d0cTYJBa5aJ0X*a<8~ZH;iw<0W zoIL*HYj9-8`hWcZ+)U8{7+QhD2{umz@LYRL6L3})Lii1plKN6eJ%3UI2O+o!!BB!M zLZArnt?QL~AsB{Nx35dhcBu3v+pPD3eVY;?gkJ^r*6qN~$|pB<#Z^A2N_Qj;-yH;x zy18B!P`3lSZ-Tulu(P}nJ<)@$!m|b4@h zOqEhj7x={ZK#EHuO|IwSWC+sIB>uQXE&7{&GDRE;)jSe!_gxRY}=N$o{V_-aD>sNr)-&G5v(q?#QvK>n5 zs<6vnLJ#a(ZDIZ)GBSaEYZzTu88eynMXWb%>T1*GJYCcFA5UTIV|9~1 RrT_o{00>D%PDHLkV1oa{HaP$Q delta 1293 zcmV+o1@ijD3!V%iiBL{Q4GJ0x0000DNk~Le0000V0000V2nGNE03WUvIk6!m0e{3v zL_t(YiM^NGZ&XDb$3MS0XSdzb3)>480&PJ>tcDZ=Z7DG^Bx<5o6Pj&eki>t$w?3Ib ziw|Pb>Jy2HCdLFYWH<6)ZGt}FgIJeKB=G`5kg{#G)ot0{wwK*KGd^s$J-b_EE5&be zvS)rX^ZU&C?Oc8%#uy6KwUBtH9e>)eXb`ByP=zpIU<`*l6hr*Kj}EDT{IbhUPx@7D+y2?yy`aLkIMw|$LOa~VY6?_0nqh=1;bkr#2C z4JhDvb0_aWJ}3|VLr8o|a|)rO<_gq*3D)BMp}BI3Ao40i_X375wBpGAfSGr{u~zG^@rD=gIFWl z_~--nrjN!1oh*L9+Ma4?vP!!&~vr?}1z|InA+X%gnuh@T!!+!_EaCHWLo`pr% zl6>nisPv@YYldND5hqo|VPL?%77{Pe?jOaH^6am8q8eUWfSa>06o>I7j88$47u8_wMVK zZ|PSl>TQ8q0I!eb@H|X;mv$B-Y_>5}DT7vJ*&EKok^+=LYpAjjCNwBr!T&XQpokp;7BX0~$PEK;;#*KpE$z&3*NP1Us`vPKf zI2igHJ59m{5P#ux%Hj3sG;Au*cXr~$2^JO>3Wmqyao%`7-yWTYl!GP0X;?bdngeFw zVo<^(ciC4}ie=?Y`;#Y6($dmWFub?7mzi5VSvE(*$Xy)ZawfT4#u(^wG%7Nl?MR6x z5{VQH1{k`13zd`bMaIF=C<9#?TUHKtDJb0rdg`m8c7JK|oxcpPb$Li83(xPjZ}sx+ zhjY|crORVeX}E#ot(~T4RXB)T3=$IIP+b+089*|X4qKt}*pT__#-?C+0%HtkTRO?g z;d0UgW3+SErqM3TFf9!A8a*Is?F2EgZ>BpZ`5?7mis9y{!_fraW)u ztSUo#R$`Cb#c?zWvxdCgt#D8d2=oE1wuR#_!SZhapBKC~C;@FCkxK7ev3PnNryMLG zZ1_(%mTWEG)r5A8>#infZCvM(FpF8IyIQW+`U?er+hXrFKCQ3|*ijnvOMa8686PnQCLbp(Ap|;zlot^IW$3EKaY@yc5 zNlr3z&$;Kj_sp3)XM~iJ$%+ud4}X*aIjTx7fNc{3x_}?0l-DL5>rP-Hgilx5;WeqY zYzj&PSc?{*7vU5QcstUB4jhN-d z;8HRN8i~P~7C3T($njG|Et@^jD2Jt#(Mf}a5Pq-8*Chc8KiGwLX~Aui;(w5~AZ%|W ze72R2aD?@l9)SZagji|1`EJ*9`1aPK|2t&5)Hh)@eoTL4h;>rR^Am!F5Ps9m?@haz z{p{n2slcQJF=pnmlgQe4>5UArB5mhVN)m9*Ytr(@Ggx_Zk$@CJNJUYk%jJ?TmrDvE zB#=>6Rh6b`N}tasv$C?J$A9CILI}CM5c$^g40}yl04>Q&m5QcOR}!Fb!$WAH9)Ygw z7>0qa>#1vx$Ah9ctIIG9d_Er@j|W}Xal74QWo40_olRR%Q2iu&Nq|C4%~CghPvRZMIg9z9|C{g^#|PgFO;oP;y~O|9>Y+2ROW|kG3GJ z-p1d9x5$@L_NxH8%8sfEw50{m-l=fC&yB7-p+X2ky#_CD8eoPeUK^jE_8=4k-IdwD zvsVH7SXuy86=isRmFJ?`%PNaev%clskg1>ls%sgg{XQd2{Sku%f&X48zFi3vge~P|CNw7%ZCt zA%tH6%1Q%R$rEYee49X#oNxz^tg1BZjJ}3pQ2F3s%GaepX#fi-Q-GXB z3q}tLAz=S2J8luq6C5bCczDJXO}i z+gmT7tFbiS3xA@1e~$C2BT7Q@=MHh8u6-i2Lsl=o$?C;7C+)A;Hlg-ThVJY-J<{IE zkZluEfUb*IaDV3Sf06{NO8|baNk`vlJQICur%Og+Fl#Nh!VwA;Ddja?C3vP~`T$Wo z^Z1z-&{cv`%4-ThI70K06GWy1y7PTlu_d$Z$O$6h2+ctJ>txv+I(~|1TkyX@fA|d! z9)opjoVK`D2LCs(ox@(Ug4D`(Ax(OzXYFs3$fVvknr;#@W3{>egm2tz-y-4>zlC7 zw$c%e@?mN)*%2hV5WnfB=V${l`71K17r#IjFNt>=g}KPhmB`&S$k(?bmo1Es=lhZ8 zKOLQu)NZ2<#7s9mfIp2j_9g*eX}amzSIh9&0I^??UmiqmdMpmpRHVm1ZYW0{d=uII zjT5@Bmf-|+<#^7N+gp1io_1Yx+NRXrj)C9(hJM@v?(Q$l1dEuqpSFJhUnXG704J&O P00000NkvXXu0mjftQv6g delta 1325 zcmV+|1=9Me4805?iBL{Q4GJ0x0000DNk~Le0000V0000V2nGNE03WUvIk6!m0e|C3 zL_t(YiOrW?XjDfShM$=^IlI|S)@*(>T4Q1x)7G~BR!x+)pq5gi7b*#qR4BB!QYk5g zUie2T6uc1cdQm8drR>s{BGRk2*wz>oB#KzIph=_}-NcQ%`Q7B4uNNo#mrXR%qJ3d5 z&dhh_o$oz!=6gqp2y?}isIn6d8-Fp>DX2!MKrtZDheLPB(6PKlQgfY8&4v72R5gpx zhGIKHNxEMvTvyQ9*%(4Np%lm0x5&wVMcx@vn-m-d8ZCnp4q(DTD7L}2Kr3(sQj;*6 zg7`4RM{p(`4A3di-q|rIJmx* zLr_RmKz=5winVYI*i}^uwUuD>^w%B@$AzALh$R8|&Qta;yi!|#V~Vm;VNvA-MSqsCV++*PfxyAWRyj~W-WgGwwBq;55>&%B5H!XZlv0@n zkV>U+UAKVP@Au>P`}5*Ogk&(16&yAix3&_qyV(%=*_Ss_ zx&;F^iz^Be>#l7-#~#fAm~bHGcz*HRTwi;qIUx z+qP$H#`5#gyMDU9A=4U`hBD(mpD(W!*#Q<*m0~p1lw*L#DLyZA5!x(+Qx(F9!1Y@J zd_Fy6CQ2!;_7(%)#ub4ZcY@fqo>3{K6xVJAfdo|{?-!hOXai1KSE9;Bu{|8Xs44w} zfg)0lnRT*a|9D1nrGFq;Y~hGCYkaU+r#~&>046rX_A60k>x9EbgpzPDyLr~W;La+$ zZQHC`mVbP&e%{TLm7 zk?+}cm#!NXh!kesuy}+wU%j7+P4j3?tyWMC-dUZ-i?w4M`G2sFs&XqYqm|1hIkKl4 z%jBPmFVzk6+50yMhfG1npMP)_qqFg89#Jf`5Gu67)r!1BbjzAS);0`t;jdEe4f?2G zG{UO-L;-OcTi5inwjsf#8)ft-{5-dCh*y@z^N7JKMpMmH>WE zDQsPzPk-F^!1Hpha46T!PBV~7osAHk@^C8G!*yJOPmaPLUEXsj2sI1fS`SP*P#%Kl z7vATYPTV_yi17V}R%Z8b@M!n?M;DyAMfHTipDF7EaJ<=b=dlx{5f jcq(_b>G-d2ss8{c(>fZtI_=s30000 zL_t(YiOrXPOjTtV$3O4ooHIBauT4z|ggZe+jU;jdBegclaw^tV%gsT~HD;OpV++%1 z^G7xNr?#S+TiHxptNDj6GaUYyYk;If6qlkn(TkbZM*O&5FX!^~$KhV?VZJAUnrSuqKU1wEc zE?M`wyz#K99HTIoEM4b~D1YJpUuJ7%1=iq?MBw9HFu4RuH$kg6KKb{DVAe8tVGY!s ziS4hfz%n$pD5c!}#Dbx*e#H`c?VQqpv?&?!PjaviY#ZJ! zb8I*)Tj1D8n391}(|H+}G;GZ`-uHfa{m85q}7E{CuU5n`7pO1BD^( z!C}xF)Sy4>UU9#~mWI-BU%%FM7f@Ht%I_kVQGO$vV6O2hb#B>P%;)w3UP3I#)>O+;>tm@?%g5^O+rzK^6&bW)`qRiQd&VW+JA&q-tdCu=el9T8F+<#$V5kc2kQ(Qn-WbmyTm5 zGqaGa^ntd`<=nAMngBhdH*D#1`wn#WK+3q$o$4+hc>jbMlZP&S{vX9&g!qFmZzIGX od_g~G03Q$b2{XhX?%Sj7U;nY=lTwu{ng9R*07*qoM6N<$g5|qgQUCw| delta 1340 zcmV-C1;hH=3(O25iBL{Q4GJ0x0000DNk~Le0000V0000V2nGNE03WUvIk6!m0e|vI zL_t(YiOrX7Xq9Cc$A9tUz-b7P*oP=$L}X}6 z^(CQXl~PEcXnNKR(m{fjSh~$c<=eDO-3zso+dO!7+}w7a=jy|=vz@o)#DV=k-OqJj z_y7Og&vRcdw-OP?isl-X=r<|FpnpI?9zqt1ZUHYQElz_|vnpg@tbA%L;-_oW3K1$% zlp&;t>{?-2f*xTbfN)4D_7+u0-93pnc+>&~+kp8F1Jjj?;Yx#)L`ZaiR$vJX1fg#L ze7C^Yiy1UAfCho8`EEIRm*Pq_c-X8Jn+%QhP$ou>6V#oy0tnFQhxQworhkP-*iz(X zE5r)Lh}YMs6fNul%5x^b^s+m{w4k*MI(q=9wG?YhDx@#m#}V}|N(+0GVr707 z!9=~U@;v>t}!#7Lig-$CU&L!=50 zeFQ5OM*3X$!?jLOif4){q)r2fQ0Xu*bK(fM{{wYDg%R9<+GDYPJAb|&8H>Qq+E||) zCpZjD5h?+6bB#(wQRYg;h!@8xN#HOdZO*h*QiA8Hz`F(cg1lA z$j*TE&yPG8PKT!##`?X!8d8((@q|=(^@aF+t~5YM_nVZedJpTA@a3F*NKS~q0O0%; z=;(rFMfN|92cI8~HGjcVCH4!%!|g#h(*_FGX$5&;=jv$u(UC^=u^9l&o(4}8k1h=0 za>A;mwyXp9umA4F&-BctHf0A(kALpN(^N2Qw*)Lfqv+NG zUa-p|z=`Gz-tPE{-qh&;_!4H&=^INui$rI?ohJWwmGR2O-JEN;<2aBEoeni&pJ4IE5nM8%mq=rUh6&unEK@ z`PLQIxIT`1a(@SdaPivc={Cvog*o>!E$u2`HykJePJ>fQL}>J=eGUWn+yXn%^z|#g zZOSGuGsxmuBP5sG;KM!eb2D7H3Il`o=`WZBkIsY*<#t2>czp@He0UwL<|CA()Unfj z1Qh(zf*CaN6uV{hm~wmXZP@r3eCn~Y-I94wI0I%)fqynH{Q5hbJY(m9<)yH_3a01B z@ z&DYrjmasLvn~iE9m1^`*Gt|S4ODpBQ32oho2nUPZMD%b`8C}FuYONM%?V`N5f84s) ygO*}#bo>1O>f6I{pKdIXxG#6LXpHwQ^3B`l*l0 zQ$BV^DnS@nDYeateLBBNBAM4-f5ug8h(H8XbDH6}CMO8PCC2=fnM5QlPj1!_=vQ z;8MFRO3I3`A|>qk0|ti!_ZKd~r7MxaC%;{sXzO>8W6FxKToxq&ntxKtZ9AmoWkwF( z@gSrn1@0ftfQ-$NodS=nK;D_!$OrT2>kug)p+u0j%x-6(Ehtp@_ z#F-m|j*i2T6R_(^xaZDAduK10I$jYO(*UM?G&i;33k4i}0e^Pp2A1m2C@0lwdi@B@ zJMiJb<@TmFd{aJ}A$Vlk4h^R|nD6%n0+fQ|wSl*PtQ>ymSsQS{5BuMP&%c2~<#1oZ zqOacz!Ir2201-h%FbrPF&*G~5iiE~rZOHZqkQfd5;5Eem%c5`Pm^_CR<{^O8l!yEC zv$$#)yc*(N1AhaC%c8fog1My+%yc3z?FuAJO+;#6Mt*EWyk8=h+mP=+Mcyn!?!Fz- zV~}Hq!lAVl%(*Oj0V50?guAU+##`#}uY9=medMV}5Tyc>SUNNfdG>MS+_7+IOC5eI zmT|znly%+B-q-{T3$dQkuesS<0xRG6_I3$;;~V-F6WG{am?)FD cX+LfM0^zws#;v~6Y5)KL07*qoM6N<$f*Di{*#H0l delta 1161 zcmV;41a|xA3Y!ZdiBL{Q4GJ0x0000DNk~Le0000V0000V2nGNE03WUvIk6!m0e?YB zL_t(YiOrWyY*bYg$A9O(VW6cHryrykX&ZJnK3pJ*R3$Y(jtDVv^lmbKFJuY5fJJU{KY8&yF zO!9Kxx%dC>o%7E9KT%b(r7J4Ignvsl4&?$RD1``v3jMfr=R34lgf*G%e3FfLXH+(- z(tuEllIO>bV69>%XJZ7VO@!9UuzoQo@mNG^1P%gK0S7mfixXN5IY9^pzzA4{Picdxd^9HvJ^@S5uh#>p*i*5#J0yG zQe%W~it><^%jQQomGgf?e18PB%Kd&3POMzupkuIQMe{EV6SZT<-ySB!JEO7@s9I5g zlc~7ce}a3Th7CKR`;VCg-Z%oQHo?n>r{8l7tSG<%s>by^aa9@u4sLON=1KRy58rpe zR~>LTk~ych-^)AyJG^}qe*SfOPH{d299&fz08Cd@f(W&tT%4KS<9{W&nXgmHSqK5g zyB2}Goas3NgmQ5ZYP+Hm3?y8t#gG?TJcBZDU>5`zK+$cmV@u|o;t(8dfg_*6laE08 z?V0mJi(%jrc?nCkbVS%D%7<%8VbOw_A7H+?dL4f31%Yiwpai^L{a@hgsIc6i6dJ*r zY#R4GV8lBOQ3?&hpnp}2&Hh-Q6IQ`024T=B^n-US`dm%I^|6_TXOC;)(r9|j*AeAU zgG)Df=dsV@FTi8F=Pv&2>#$)*dd%0cmL8Mu(2g)Nba^u2;dOAT9ZsD2_riUD!N;fI z?mN@tLze+zB;TRkRD?B&(l#`T>;LULx4_!FVEb$E+YQ?3jeppE$ZIxxwob+r&*`AF zRfIKZ07PgVb8!X|UQ%!YeDW4p3*kKwAD*4?@h{=i)9}hO>CI*!0b?$X2(2*Q+sDmb zY~1<)u<8!@XusE^*FNR-_G~zC47N5y%^G;IaWd{&&sqU7-&{_dVG2#I#q`7{2W)x( z&VJx+-}>!vsDBj_DYcPGd>Ed46JB~3o_G+xe$U%MpPo3l7NgMQ$I?7pXGEG6TFQ#j zE!2esG`#8+VeTS$s1jC}!}22N>xW-@;Pg4TmV~B8cxRXQz&`yKJ#mG7RrT7EQ5;0R zix3_6aMP^Rw?DwK&*98DubQuqd8;cefk$iL`7o?5OI{z-e-U~IQB_W^t0&FFP3h>W zR;1A=^u(zfy_W7?*Wcs)z$?b#5eO|wU!~6!_j=L_jZ^LO|I4?ha*MuL(zzwyYEzl- buhf444cOfV469v400000NkvXXu0mjf-K`+& diff --git a/smileys/default/laugh.png b/smileys/default/laugh.png index 0ca308c356218d3d76b77a7de7823b4357ff854e..163b0c4c7aab649d3624bf194a13bf9a7943de60 100644 GIT binary patch delta 1111 zcmV-d1gQJM3+W0WiBL{Q4GJ0x0000DNk~Le0000U0000U2nGNE06Q?QqOl<)0e=rk zL_t(YiM^L^OqEp}$3N%#+-LCccxR}=0B53&F>Zxh3G@P8Vx?1FxM?lJ95ph?)vNBN z!%bXmEOpC)BW=8ZxwV{2SZZuoj*3bdWl6#kHsw#vtRY<<;BxQ%_2L4T`wsz)?{;3C z``r8c{C?-$^F6;ui3qcmQYsn91AkI9jZ^@ymwsRX_+CW*oOP`Gft6AYUE^)jpvdE8 zWv&y?nic4)(})A;?ql?3FPF$pb9i zwHfsw&`F)Xh?Km~-_|HkOs{-u$COfb)1b+<8^^=9tQoxM3u z(jRnrqv>D?dXAHHyPdZ}z<(1*=5VzOGyF$=cc82i(zd|6N8yjVk%7Ou3Y$tHYbTsI z6CGad!qhb?lu`}=Lf%BS)1U}I0m-I8&){X^qnX2{E3k20=(0ZdOmKds10H<@9!m+#{eC#p3@<$&8O!H~ zB^wxVTcq27yj&-qSdKIu3ZYPdby-0ufXx;i3IW&4b>ac?Y(UDI6%YTP97_|d6q}}z zI%)U|q19=`X&R|97JvBvm(A;?zq^mog#vc>G3xcwuK@!$d+`AA0K+3t^%=~eKbTRa zJHU|;oKLU@q8_Ig-$~$}FN^j0`SS*Lc6IT4$7MP`{delK>Bk8XA<@B&mQz88X+Mo5 zEnh6RZ{L>rYD50h@=3WZ#JO5dA&CxdOgWd^qQ15fYcjL78GrEJs}}3?^H567d1Pm2 zV-0pvT<8y3h1y0ew?#b=@M^%35YJ%e*lEgv+W2;NXWKa|(#)Lk_B@Msm8nVB>0>$!8EQ&W9}h9ed^ z&d_HCrMO#u;(vh0BgdyIo`Bm;gKLLM7z@8u8jc}J%M969_J*{#w~No`o7zjS*DI~9 zt@6stg_5x2*ejF|@40Q)3w)~(N-f1vKdBI>_1>FFIIY55ZTBK&pt9vQ3R zd41~;MOy?j?2e1o`pm1@^ZNr0fz1ZVOF_kGlxE%RO)Rf`!Q0zu@P%*a!xC87SC|+{ dJhYd#{{T;&p&xg6Rl)!O002ovPDHLkV1jx58p;3w delta 1201 zcmV;i1WxbB5^*kWU<*#tEtLb({ws2GJvXu2WP`T`Fmq6wza zHwuy%AMnA%M1wKWfL3>bmr7!&LLz}~!3RtX0b-;VmD27~q1#f*esg^Iy6s+CX@!9Q zw>dL&{xg$v`H!e7)5ZCy_;0wZ#D8J2KsibfA)(NVOJ~60bf{iOr|VCqLw+VIuc*?1 zumPngZ8w6oika|65~Wpyua?#8(Yqp#MP!x0KA_g;;Fc8NloY~TKlpuM1gyen3T}?V zzz_@!`_ zn>lG3j)Ce0P%s<16KpaHAoZCqkaeds5q1G}l|kfgh%-?>4=RHQP#25PoH;lC?6HWf zGQ!EyBBXl3y&=xT?|l$YqJLI-CLM(1Hy7CF7;IH({>Hxt;lqRQ_4jZ)HM#TdUf8oA z+BznmAB!D3mOUP)s;2Y!yGP1kK_Gk6U;Xe{9VCanai|)8{T3u6^pBr~bvq#CdgIM6 zLd*O42k5&2m-|74^~>t@r~y!=!RO$X1@bq1(F$er;hooE+eYZS27kw5*=s&M48?^W z>5@kw`UCvgm+z}A06qs-l?DLc`Kb62Hk1_LOqR!k!*H$z0)^iAt<7-im+Uphz|~_g zYbKP;Y3Y2loaNZ-%d?9oyvAS3G<33#v^0Z zeU3lh-@p)D>IJnt>wm*xG3u4f$&gDtnJtreD$+F4JjPIE1j@my)%OEw9u+DKO3(<_ zOs8<)0~qnTAxh97B&=fW^xOJf!75nAAS8@JFL-V7ejv>w$`v0jofxkl&za>-Y}*Tm zj{i&4%mC|Gr#QIRj*oASWrDSI`2r572O&8yL{U1`-fn>Caeu>4Cu1yJxbQ!bT5Ea! zxs`-p=*qGW3;{wi;BeX(s@Ktuh_nt26IQ%J6RL(c!!A4C*vgiMt%%G#8aq2LQ|ynk ze)WV+@stiqYbdOvQ`UCZ!rJYH#D^Af;o_wk5f>L1Gt05GeLTd{$0zK$wSBy$c0{Dz z=kWAXl{jhTa(^WbFYhcOF&JQeNf2Z1ENMnYMo7f3@NVNUO|MNvv1{R6H*U)1?DDX# zfD9$0(BxW9cEvpf0#H#3?Vl&v{(;NcOMbpNe3VcqG$nCcTN{lHb$qll$(EP0bGIuF zuEi)crEOUn?o33Q6?RvZ=1Ztg4jFds_w(cvOL%otBY!nDHB?ko(9_ey#fukcIrtg< zeLZ~HJj|M<*?W7hd*ljxYQwsFQgRUKh!7pqaCuVd)+ih~0YCmco37s3T)pPK&f@Z0 zY+Q4Tb+ulH%O&nkpsE~M9wtk}Jy7-f|I+Q5ctAgvY&?*^S}yMOFZCZM`w-})Gd;WP=cY5>cNB9#GXA! zbFie~wY9D6!GqRA6LJxXNNp)4q_q&5G?rpeVG|WEfp*!9+nLeVgS$qvv;Ju|OTRG8 zmaa*giM`&+oH?$i8RM> zYfoU-R8tPHv_fX_5$-SZn5IrL?J(i`j3}j2{|PK2hGEcW>U`1}$LQ(6YHffrEx4o2 zEx3IT#-?y?%;LE|AA267N-6KqU=a!17BfvTqF)SP*GKkUlsqjY;mR=Sxqo?<(+=%H zTaX79k<(T=-w$*Xy4s6*G~`|lC2)twNjVwXlv2MJ1dB-6D(8M;kmHxmBhLfPX>uCX zdyU6VhEuy|zO!Q@V%Qcl1Kos*1qHZt9vSE+WLwOLh>-_24Ema4M4xwggLJhQvnfW@ zF!(T6CrT+qBy_BThj+f_<$s`q^p6X-?!vh@z|ac=?k~cz3W!$aw=E>$%m@7aWP_7R zsgwp_>hyQUF@m6*TkzUNh+l@Y-G!l}H{taAQ1>2udn>=aJ_4O_3{$5cvP*4SboF## z1$B7mPgq*nF5i6s4;}`CuYdP+pf`UAj_K*ZvMss*G!Y5AK9Saj;D6vVuR=}rcKP)> zs5==Pck$ircbNtk-U*IrZ2;FNA|hcOXlah&mT6Q31(#{?$MvUsTu6Nv;LV1@dz|a5 zIfgs?D=ivOS$kstll+niZD;pCSOBML3qy0tvMM!Qrz)55OQD)-%5|Np0xAE+OY?nJ zmsZG>3b?dF#`js(fPb~cN4TW|XIX0kgl&uEzkZ~m(7(1=+T4Oy-ex215Y?1Y>!wcf z_PrMig>9o?>Lis?>pDQ%VPb5G!M7UsX0In3@cB1K2Q=10drN-(*c49MVFI!#)Abp- zF^jj5+#9GAWZa`ao}Uk0NJ7>UjleD=V4CvLxkf&n{Sy1=bALQo@yn!t`i()?RiEw5 z7{K!wottNQC{g?qK9sDzIf zdp;ng)VhC`0CsgudXSV&spE*ssnO;cPelpr)rR6?|WfOeIQo5U6b zg>Hl{T-8F!W(Erq6kJMal132~$9!;MI3w z<+r^7AKZc$UW4~;Hb1il`n$2f@Gj4Xt1=O>c&T{nL8m`~ZwjpD5g^ftMHpSq zN;FdT7!gA((X|H|_~4k! z5#`et2jH1wdrzQUdi*#1unGcKj6fgwx%wy+a8!8Spd^jp%zhGg8)U?yWQJ_-dK=g673WgcO(v~@J_(iR|W#x3(^ zD6JKgxzaY?fBoAP-|3*t4W+db0T5xf>hWfw48090_U#$?`n!XJzWf-52J8C@WvF^s z5oRG&QXgbwA!0fE(m;K2`Qs7nJU%%5RLakafjkG_ui{lbzJEDCt`{KWWE7@6$GzN| z??3`Q*L`qsE9KU}a~OrGps%*Z;c>l>a;>ld`Stby1LfC!FXxo&VK>`gAVnTz$nJW$ zwpgkBI;<8^Rqmc2r_RGQWOP+0GHDcYYm9CG)i(Ef*9nu2_WA$i+rxTFHs?2c=Dx6cBfUx`qG%002ovPDHLkV1fki$20%{ diff --git a/smileys/default/raw.svg b/smileys/default/raw.svg index 0ffa03c04..8c19ee384 100644 --- a/smileys/default/raw.svg +++ b/smileys/default/raw.svg @@ -229,7 +229,7 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="3.959798" - inkscape:cx="128.26741" + inkscape:cx="85.967272" inkscape:cy="46.934585" inkscape:document-units="px" inkscape:current-layer="layer1" @@ -298,7 +298,7 @@ sodipodi:cy="240" sodipodi:cx="16" id="path2987" - style="fill:#ffcc00;fill-opacity:1;stroke:#c8a900;stroke-width:1.69246382;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;filter:url(#filter3777)" + style="fill:#ffcc00;fill-opacity:1;stroke:#000000;stroke-width:1.12830921000000006;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:1.0;stroke-dasharray:none;stroke-dashoffset:0;filter:url(#filter3777)" sodipodi:type="arc" /> gG7O{=Z zs}D&7=@;ZZAt4VIVv`4pFG47`T0#k?m4;}O&=@peqSm$)tgh>NT|IqRH-7Bhjcx4G zKOF8bbLRZ!&di-TSBVIll~T$JRDS|lx{ePZ5@7SfW6@X_KT7e!=o(_p2P*KN^L9>9OT4R=vq(n*Qa@P8N_KTGh( zyF3hrc++VK;=oF&eO5YsZH;(NH)H-YBT)MRlr<)XUhIN>N1^a-xOOAHy(karYcWin zR#=&8w?#u!9hOtTTfe~Qc(gqD03JMY26ukDI?%4~oPC<=u-q060DqcN%4Of^h06R^?<>Z{E!M)DaHBO|K z!|+OR;x&%Nst92B4p6B9Sp_-Cck**4)RZOPSO9wq5<_EJVP$E$jxToLr$YJJr0Y7q z1V{dVFD(*bVsxBvs(*l^gt1$f;S52vr=N_5w5m6n!a+d<}o zA^f_COzp^2WBo(yt}aR5F%*Wr0k}OJwYhmHDT;pUukMGe7n1ky9|BWnOhl%1fMAG@ z_HIsAmpGqZ%gb>28l1WS6TgF|!LA(0bi=vM=zvTEP8@|(?|(+?oz&hWvxfR+2$ zli_0eeitG?t+(mxNOcJU$iY&i?*cOW{c8Kt0CKMrdG9Sm(~zCpk=s|}eJgb@YE;t8wQZtUzh}g*s`CtzX6y;J$l-DrjpP5iuqaHMof(n@!Sg_TJ;e%_f`O4Nb_B z`hOZ`&Ya)O+_~qR5mjZo8V`v#Vt>_FbDTB`Ag#$KuxU?YK{|n!YCp0YaIz})LA4(NT1J9gN*-H3_K~0* zH^R52g~-A3?0}Os@ej;KQGZ8yE^!IhcP`Ln8JwEZ?1N$b?l^0I59{!;kTd}eRV7%N zF4xc~uz-d&o(or{&0}Gg6=!zZ`4N0S4!4G( zJDAyKdd9Vz_!Hi}33q=>w<#+IkASmyfm8e_WKGxqqFkyj<{DZd(Kj z^U`eu@a1D6G>?bG>xtMjilNX~umu@-?+x(gKI1DEnq3&@v ztp4x|4Bm$RuigIZ9q?pzx}R_a;x?8Dy^xerM}so#u{iQf_2%TV5QU~UVfZI_^%Pt_ z4+qN99Y2V{^**@vDdc$IRyQ1eYGd4X;Kym~xXpL<0X+suDOI7vb}&=3n;o7w4`cVB z?;ZH~VrDQvu74NaItzFDV1E%je*s4CZj4XOg6&`wIud>B@P>d6qFf0t!pwr(7hQ3k ze$fT3FJy+Ms-_aY`2-Htx}O7Ff8j-Nl&i_rY)SzsG8!bbR>Nhbl$u$9={Z!D{`vr$ zYPgh$uIh-i8-=M^T9zMVt$OWug!a_(`Tte7C+iWtSRXd)k-XJXmF-vRf2={s*YBpA Q{{R3007*qoM6N<$f-qhE!2kdN diff --git a/smileys/default/scared.png b/smileys/default/scared.png index 595df46082079f7327bf0bc7db6684cdfd3532b3..c8a9049778d5c100c3a3ef015157bca88a9b317b 100644 GIT binary patch delta 1471 zcmV;w1wi__4bBZAiBL{Q4GJ0x0000DNk~Le0000U0000U2nGNE06Q?QqOl<)0e^H! zL_t(YiM^M9Y*W`2$3OS^zGugFlcr&fV`JPU4FxZdl+iXp2ntl95@k{~b$_sCYSG5B zHQS{9gVd^>Mz%@((Mp|K4e>{%4gRYTQng7#Ds-(Ffel&+NpPD2OF~S7aYhoyG4I*$ z?2nQt#5N5S?JHgB>D_bB=iGDNyMI5Fh_F~Gr9wa(5XR6E0NnftkOaC#WOUKKz7DLE zsx%DUX;>BQuA7eq!%eoYI$~K5hJ66`jbtwO-w`{L?6nL-54!fu0oTpHBO;Uc1XfC! zhGBN#F}fa(Z!|+K&-yE)ag;Jj+KaeM4)-&9_V3wi{U19N+}B;#*(V~-qJP0ksgSlR zj#MpetZ&-3D;QW3xnouqYWn&Jy?@)EnYc1=DR0kgEmeXduu^KZ$MhauvGKXe_~z%W zyCN=7|FOe%;^V(g7Mz<~M5L!ISSc0qnCAJm@3+@9tZ7x>1UjpWpPrQNLkH3Y$5}Oh z=5t`Blxcdsr&~5{TJglzt$*KWrVI7&BS-ABAAOW?Zr)rwTXQ|zX&6RF_>raco3^dD zVETS?*|crFb?x#%{qVr$p8wmh!-rxS2bZUZd z^jrM;H#>XLkEvx7>buWx3hBfw{PnYM0~WYZ8SgoSE3X6g8|_6n(Z5&Ztw@p zEDKwDWQcTX0)XUjicI=ykxjtNa{f$WF3|qZ5+!XmJl){;dd+qKt&|G+d^)x&9>g$; zYrC?sf`@B^TpP=#4l2XxMA@^bpos6N%MnUr^uQUw^2aVs+Z5H4zP9d29k^ z>D1hBSsohzozF8eI+o1^^mN%8-%pK>WpnvFBN|91ug=&3^Zx@*UY)Ulqz1ar^x2lr z$a058X->JDLgGIz7cN11LKCldXnxE?P1V=$DFqkK^w}2Btwm(?p(-`lb0M>0eM|Yl zW8<*?)rR4eT8)Wy+s**nBH1g7RrY+5@A_BLz#mYbh zHxh@6jr-q6wrq$?E|)6{ov)w&^hG)NJFCb~;t&$3;C}{CIR_RIOp{-1d6KDx12(tS z%FxizZO&cSm4Sf)>Fev0bUJ-o-_+EUJl+%*`{eC@wmiv{Y4Xci-rRodIP5#s%a8Z$ zXT=-4umCPzfhBb-iAJN0kB{^ATV0$u{vk8d<1{QS@PJ=PUiXlm0FPP44|a60c!Y5q=Be)Y`J^Qiu{)NeGjyoUr=D|ZjKYvG_YNGz#-2@+t-5v1rL3m{^nNz)7 z%4AvG@pc~EG)+1zP1g(0VD9`L{&mfiU1SO_oHz&XeL(j84{_`~uR9KRcc5PoK&7SW z4Ekxe^Tb-4upf;3WV6 delta 1449 zcmV;a1y=gb4Y>^=iBL{Q4GJ0x0000DNk~Le0000V0000V2nGNE03WUvIk6!m0e@df zL_t(YiM^LwY!qb_$A4#LcH8c5m$Ic;z*0fur6{N=rEG(up%Mj@6kB5uAu&GSlZiwV z6QM;zVuFc@ZyKWslIS*)C=iXxP0~_Yyi}zI&;Vj=wX~G&w%ZOn-|+!@W0wk8{lCq8 z=R3bSXTHlhqN-f2+Umt0_lRP1lYc-VN%|LUcoUjW%2(T%;++CJ{FFr^4o|zkk-)-}Y2u zurk<=m4)Hnyf0ZYb(hnuXPx9Bt!V9`QvmRR_DDq%~fN&sKbP|24w_4s@@jCpDc#kq@g- z0i=3#2F66*9Ft87waq6s5>dI@hHVxhslL`?Ip6oA`=6Lml zfrnHUu4h)@h^n$^Xc3O2U1h7QIp$b$i5+zMCLDe&xr7aW{ z5P!IH(I+8iIhzr`Q8Bp);R)&0NFm1@k=LO20Tz< znuC%LmI*oo|9o&ym@I>ud7!8b9lcu2!Ju1cEUD|y^wGR`$7ew)VLFkfgO95Z;$8l^C_FY0UziE zX3y}LcXNW}_bEj;$hbaw1_wb%gl!s~l4^Ai$7E;kK&mFk=h;`9`pwVq!dp{#VCh;O zfA&%4&6`I!9Dl|b!|~(CX=!d^-R3&huWaY(M>3aj3iJ-BhqAMzM%^)I`>X<(8cv_I zr^Vv6?Ipbb!7hr6i?0|}GMVIs=bs@r^%<`}*ONB>R~$}uGJLiVU#W*%infA>sm zd(@)u=z>RIx{=TKv=WI#(i~>eW6LUd<;g>o-Z4@ucz*`I{|ztY(XyaM7s9A3Rbhi? zIC%Oj%$_>p=*^GvsN3@PFxYinT3cH=($dJWwiY7!g%r-Xh3V68Wbxv~ghC-+f8$+V zeQ`0{H~l&6=k!_d43@%%p?AaZ@)~Vuj!9i-FSUUzD7P&G3jDVzk)zZs$NryL3$^4S>Q{K=D`@RcPS(;$MoraF{@LLzE%8ms! zT)BpWi`A>8Yy(ymvG-9KfC&gd9Kk9k2w9f}4V*3+MXaTt8mQ!v>lZ zuBT%etD#;EVFk)?uVx9x=%_YENT5tiuXed6x=Z~V$4GVTd4;uO00000NkvXXu0mjf DK-s^Q diff --git a/smileys/default/smile.png b/smileys/default/smile.png index 898fd0140b7025263abc32bd3516f7b27223472c..b13fa01d23b5002af34b80b842706e1206dab745 100644 GIT binary patch delta 1112 zcmV-e1gHC?3+f6XiBL{Q4GJ0x0000DNk~Le0000U0000U2nGNE06Q?QqOl<)0e=ul zL_t(YiM^LwOdMqt$A8~4v$DgwHpR*YXi0%Uw6s{;a5G{fm|jvhDxqm?;QvK!2>J5eHyd^aBIHuOjm2l6^f2tdw%uHOid^MW#hU zRvKpVdhAK@L;`g5G1lITdF?iKyGHkjj~dhBw1^C?2&|OSb)7Q1#wUgO=p`PEoOFn= zg?8i*Kw}G3*Wvr-G83l7@rem4MPy>hV5OAXX;7b;M&jocI8zfA4ax#}yMN*EDMo&~ zP3MS@ouQUs0az)u#faqRieg+RO0h2wIaeQ_!8~=2A>SBzBJz7!uu{rxL~`rQF`^Ib zMm-KRsPjJ{rJwSTZ;Z{epL}}7lv29WpuVCQ*OP(*9N3MjD8}V9s8>qq3&6TgS!NoE zj~m`lI#G%}GmS)D=l$TA5`PhtQm!ZmJvYAMnNW!|Zo<`@koywoT6n;%c8GF7V%)-e z-fq}-kimzeY!Hzl8-QJ-yf7a<6x1JpP5U7K5M&gGhgM#IE&CzmEx2@b;r-MED9lH< zYm~!OsGSByB_51W4sWzUN8jZ2&AV{7Cp5VBrlafXWkYDYeXmcRBWzIcT46|yo|*Y3t)3{cxX^ltXP|-5f|L>S3^nh zL~0swVYdALUpC94zkj2TvDE^0^f6{x^lQLCdoLzTCfCDJI9&_N=nodvp+ay)&HSEX z4Jg3vH0XTLfFoFIcO8vl(7%aSb8}Y=yyNxqM{5JEUk^`@`2(S@*Q`^z_I|wIg@Cd~w`1?NgeND^_;?j5D(oku#{e@YRnO7tb5kv%C=SW@#!?QzUT}M7DvCGDU=cK8r>5<_*d$vkq zW1{5Rm&^&VG=Cv^84T+>9|U>RU_f^ow45wueEy#c%MPxVR8{vXpVBK?|So+`A7p8@Qt(T<$Ho*)5y>WvYU(;_sitkG}p3Et{TmB4azXAi6hMK22=raW^M5P`WzWhG zA3!Q71>O>tOrsnFHW%c;l6-K?^w;hz&qB{23|t4`Yb$JBU87@(F}`WvB1SnT!lsfu zD4Kuw(6}4}WeXvY0lh>QbNhY;xLL zU8yocQ+_s5ws3C1iMn(J27gCTt2`Y~!pV^f>~{=yN&eh}VKR5@#Oh%Z-X50qK*iz( zIO&qB`8QbcD!i~0y8oIP@X--?tQy`wkowFquy_FuP%*)a!BwgCId}!R={v1E2pyg9 zeG43L)5rAo$Ko#i3Hy%1?_H@e1-amJ@KmVEnV~FmRphh^10mT(*ny#qtt(Xx_{pFjxBL7W~=^0^5y15ybZD`=K~Tg<^w}X9R0z zvvJRXjKr!TN}fR&vVV%PvoGuSB&%Q*gD_+i`XN>p?}y?XQ7-%N=*GnAaXjI6?1htO z{c{4_ux6a&d+p@?*o4oqmL6ZOL-TbQ86KTlZtvDY_^jclrdA3I3;z?;TFZ0KRuX!? zC#ijS6c9#o9h!aRH5zSm<@E3kLP~6-DKCSaA&>WVy~THpO@D~oeKsCCbdVhXARE?9 zwJ9;DgL1k&q){J$2o2*NuM9+B;lviZ=Z#xD^X54gEqWBsvuV1&{isJruF-Tjib<#y z0}&Yaa71W;gp%6kN{i27#gipd#pUuKtlODI*|If!yzf&2ff@GJ1YNv%k=M3u;q~eW zbvvfA*t2l17k_WuU%%fp(oi+gxnR3991EBoEi_O1;AFCHbiq>a&xEy3hSAf8uefH*IC< z(xns^7t`0*$At@j@YV6d3|#5s%laFveJc6g{%bKmr)RLIBBZXO6DIZ4DShO}VB&MM;sbInb!NQAA zB%1O-(}#U9zF;K8@Bs4CrZ1REh-gf#D4NF7qJ{=YwtR$Wth%nlc4pxEuwUrTENff$ z|1xvWoO6F??mfA4Mo1|sR6>X#(0>Ayt11-$j>87934AT3+$wmk{lG$qfUeT-H|Vq+ zLd{{U+C%6ym6QOitdm$?!}?|sT~~?5O(radVJT(op1?u~P1ESrRnB*`p>?-ov^IcG zai3^s7v>gVYzp(zEVkuv&bAqmQrZQBg%Cl%!Aw(_>h}lm9}eYRlpHNZp?@zze14JD zxXB5(Eyw{2A?l41J{#yFFxZ3s-;n>*&?r`9oS2#5xRmmSCs+s(G)lNR`VNnsIf=L* zXj+rg$es)QY9=_c_sugqCWO%Z1~UU)1RfL=;LJ(HKo%K>W|y-i`N?{|6K zG}wdQ6sB6!cr$GiQc8pnfqw&~+`je^Wp0IZ*Mh6p;rVAkQ@sH-_Q8HdRu}m;#`y^mnwOxj}b!;mOm`b{39yc|%7oL;Y(|_bObun*0242s+x(bd`Qc zEw$gEv%4L`ZNh6m!OD8_{`xJrb=w_$@zZRgmp^y+>2AmH8*~CFLVt*$wV>{H-}i`hN)Qtv5v zw!wRk({nY4v1Y%eMFGld59P1qhjci8G=E_M9I5q&rj=rqE2>IG`oJ%SYAPvFRVqA= z{QqByCouY%Z^1fqQYe$+F?A1yFs^QlGpQsuXKe071XO>hE7r z>h-PNt2;4xxgWm!F*$zjY54d(DD&?hyR!?A9Ai6fQmsfSw{(^0+(Ka)zdf9V0(|*B zod2+}*trGJRiaYLEd?NMGBGxVxnH1^Fn%T1KJiIm;IS#pxPQq6q>fC>VffN4_EI!| z;4i%WNR(%oTmcwAW z3Cxs}Z8I{z$m-B2mRGRqgJX@k_LrLTLx)DO<`-GDZ9YibGGHmC9XB}<87DS5jc3pM z?pts$kR3mM5Kk_g^@dJPBO~L)QcYi`ALda#82ogLfDnd!JL`ABSla?f+1~;3~%~u=q&g0?T-EQ_PTM}CTr*~(b zncp+-&O6V4L{+I(^9c!NJbJNo3xBkuL=e&n%Xln=EHgbZ-KljxsRcflkn^exBJ`m& z<=TzloMIl%#s4c#dW4c`!6DZ0>j5035h0X}HAA59YPS(K5 z6VOlxOKC0`1&~Y-TenvHc+R$l-q>)m46Fdw+7eMdiY?-?;V%@ddS1)5^^4hcC=v2ZLXQ0;e|Kg z)wf~cugZY;Z^E;$!@D<1`>cVE7Az3W@_e`|g8_@z7AimK$S3f_JbXC|H{#`EmX`gv zyMMw5x8T>`OJmwX5U_Zv3<8+>gai@#!VTC;-*Iz8`R78_*FnJg&wnD&R9_k+K)3;m z&^MouU?AhsD~6_UV+Ats;X4pK0PPVMTmFHv{h;=-IgWEI z211sZb=X+jtp2&>qzdP*!1Nve_jf*`76f z$*lFMs?`b!uHLIY&U3!C0+Km%nXh3A!=A$|u2i4o`K}7>-POk}u7Kw-3d6a!JUlv} z(Ng-~4xkX~L3z$Dlq3bH)NR&a-qE||}_MgB)2u;&y)m7eY2%$CCW7JiF zOR;yfxdo#WFfc^)#t3oK;%YojpOiA5HCPDY^B4?Q2MK)Gfv3E9-=Jh@I)4mpJw(Q) zn2$tx(JloUU?IeD!_C(nO?bOn(ElAWUETedJs+_ajd4y&Iq3)%Lih|fcl$dza`^({ zAkdUP`2yMU9)Cn*RPJ8+cE*Gdn#W+cqY3ZBf&yH=faqw#>oFJ>LTDLaO{29sNZ_F1 zwNqCMdUcS1rtxNKOh_paLVtJ<<#GSc$K=};(uN7Q$KlyipsCJ)yR&d84*~_5@210W z`gI=swN8_D7ehk`O;>4$ zWT-s`jm`BKb`I~{gSo}T^Y{$R+_wi`|7vHVH@~sBX|Bic7&HPXLVpOKX;EBPWp8}? zDJUsSJfA3ovLbuCOXm}JmjV}`x3{UQ0@I>c2;ozK+L|DyOCitB*rmYF*LQO4q}Ge@ zbd__CQ@(0~m?J+@s{sDeqx)C#BRZTrvwvX$RF*nJQ%bV@imFnO+VFFsl0w|7N`b?c z|Nl#|ESBaLiRB77w|_{?vRG1p<=F+yT!E9UWdZm+2J@@mlDGG)9iM^KKkXeX{0i1) zqEZzBE?4qWAm0OS9iBOn{>|nV9Da`VNR)sorCd3ZFT$e}RGdATZuse!F!_r;cx)2P z4G;pP1WDp1OU zxn^2iZR;VDE%;ake7-0D>sxSd4T^l3_H8{xOpC5m6S!SY@i={BQ_OewXIJ5Gyb2=^ zV0wLLZ16XzscVEM{pq&d{g`7@%*W$gON||<^%?jKIzNDy9)*~IkyW^L4Ng_;*f_O5 z2X6MJ=HR=Z5{JY2YVbdizS69kz1=I%d3(DHp8JM=&jfP&3*#_}hxXI$ipgv@8M=#93ZYR+#S&y4+s~DM>%VR5yxQL8*!QgAlpp^P#}?lKknkX7Jq|s?ns35 zPzox6PsXIyC|800=Dl#R2^_Pz+4gcR%q~G<6@V|T@aj_ox=|S8+cXw2%2g3ghC|T0 z@4=xtIR*~5K;0ggOLEdEfD9D=fucE0MHvD5!y#lR;6kzXP5a@^m&(U92jR*)aOpa{{5%|btbAOs z9uliGq%1u$8D&V6%TI*ik(#XsP%Yj62Y#FbfgvN%3SO?>4dpm0JZexvMzE%m#9aj$ z@lHdOkU>aV#n{S^^?x17Dp8hAVmz0bg@zT$Sv>wvHpaG3CQ4QTpiRK}O@ z5mAa0O=mj{^_GX<`V~H!hQ9rfvETx(!b%1v((vvZ(9u@hMt|{~4$62}MAJS15ymnu zuOw2?QjlW9t=>~k9c}RW7w}1Eas4kF@Zubtc&@ZfA_W;2M}#rR=Ju@Fi)XD*MLN(3 zckX+$Db$+lrP|GMt!J%(c+Onr&oG5y*J5UuDucH)LT4LXPZrl-y9>`AEsdXD0@q>` zhI4g!cy~l^pnsf8tir-dWdk_#I*iLKL>@q5(xwlRC=zKSNu{L?O|k2x4NI~V$i8@6*D1~p93PgYP-f_2 z>;7M6GUq$r@60*hobw+cr6gMkA%A>84N$166am;av%nm1UP>9yI@g`RLWlxgrPXWD zVA=SqgIHxH=%vMY0HQO@Pu{?~5JA^fVo8%e%jP2~W#T`9g%Fyi(W0xoTVIFP6vC*j zfIP)H(ZV8(PC(B9=BZ&)md%M&iY_T-Dr>M1!sj&@stOYLxE=2f|GJa1Mt|30a4bx6 zEW%XMWS`R#tN{xlb{QVdv^P@F(Tu(^K$ z7K7a{@aNw**)F9_C;+-jYkeJ>6Let_9z6_oufd*1cWBpX*mVTTpM$T?t!>}ohx$4+ zU8NP4rrK-J&=kUON;v*AL}$|XSFXeLX=m`sZ*L9s^jYVarVxhLpnm~C5kmMZ8-Hzu zbMWp*ptLxB|5!PcZ+DJ6{7m|qr@*17onvY%z_RfRA$%%OQys+0Q^&Pq-S%W9y#EGNKD@fm!Xj*aiknH3fFh-g z>ngF)iR_`5eu9H-=|nvp@Y`9iF2LM3@L?Oo;!yn(^nJa$-+$-?=qfQOWn2MBn)LMy zU}giIjzj2mD0vXR{|sIZr9U?z;Gz5B`13IF1-x>4ya^+h z;ZiS@m1H?ZxEvBv%7kTe;#ipEdYv!-0$+|mTf@enkhVgWO-IHAE|*g(Mb}t_sm^XJ zx6bc;3fs28@oFO*gLZafjYXJBrT8TCY#A)2OeIbBg?mZ#58`M&N5-N3McC|kjybD; z5EWhh(Obd9j2rMLObQ&8aCB~WtP6Syle-?ryxE9K))kAdPk?uXZv`TPOh|80>ut#?BT8ymAb-J^;@j$+uYs8tbrt&?3);tJ3AMu!A*)gZ8`&-;BUlLvSQg z*k@wW^&33{uN{Y2@U zeFX4VVj;ARM8)e#+O&wl=dUV423~&}yz8L;S~&1vVV|HMj=u=UK7)r^Ve|Ec{rpuB zpTU=OXpx}^`$hTS<|epiUGW4~OBXN04-+7;-v~5-TdV&Ir8z2WG$;WhIHr`sy$Uko zc0-haK}a}?aY}FND}R!s;3x(mVH768ZHxa_mlt4mt~B2?N0dJeHe=xS<8l?BhL?^) z<9$%Q2WszvTf5+m4_#X!r8$nnxcnT!I|GTJ4_`SoeegSIJpl8U;NBf@=XUrj0pI@W z79@WSyz?A9+?xB|=sAebGFuG+PjjcHzK+Pi^c-QOc%jJ&aDN8cpM@K)gOA^Y8@J}# zzyA%McoiOb0XEjd-M6{xiaY6`3^a!|WdKCzTd=X>$>qV9QgHt>?y&I1+xcLC?b~4R zD181FwA^%MJ)VRG8%u;fSgh@f!(ME0^tr0u`viXZ13r2gwlx*^^H|Wf$E}RuCVTok zHV{h>mzf@>(0^?^nDMFN0WYT9rg6{hu(##vNiNm+6xa?%p*y{nfrr9+5~Vjj1CtjD z2YCNeI2(uF$IAmxUT|kQM>&)|&E|A(cgm!HB7qi4z+VGThGF+D<$)&>D9|4Y)0=Hu u)9Lm9HMeJLjczQtT9dolQmyta^&jnb!A&7+oALkv00{s|MNUMnLSTZs+536` diff --git a/smileys/default/wink.png b/smileys/default/wink.png index dd112dd6a6bea8be98bb07714e9cd15f67e3fe0d..ab5858c2d0d2e6a4ea7925b618b9a5af4d36736d 100644 GIT binary patch delta 995 zcmV<9104Ln3ib&hiBL{Q4GJ0x0000DNk~Le0000U0000U2nGNE06Q?QqOl<)0e_rH zL_t(YiOrWyOk7nI$A5Qx?}a{J#@4DKe25)rYwFZ$qGiz3m_XEa!44NT5JerUq6-(! z!bm8nNfT2ykQh=MBkHCxjVx-3G$CmMtzqG`O(R;clfp7CiBVla3BdRyi7VHz&t1YWG(xdBeYQilh(y-}R!Zr*&LKmitEmCKwGs1)J#dFB zzoUg4FdT&A{lrfUlC&M(PbT?PM3SopE2T;;lYv?siDScXQYQp&vqHZf z-kAuDUWVBMk@@?d@L~sCo`7=~p}8IGtRUK11x*d;hDO^G*fMEuZN$vy^tTzPJOGck zz_vz+%;nmg9)YB@{C#~kHGyokHey;P%>W80wM-@=Lu@LP9A+YLHGd4%6|lvff5jCC zmf`nqfyq-~=$Up4H(>MA{1c1gaRGHcFLog)z&)Gcv0eG00QcPupLf765BPRNUuP~9 zQd!UE#Rlp$psc2H{WtlA=Thxfs;R^n{DCr;rcu6_@Qb193Q9DM@|$e%e=C>cFf~3& zqFBK3NfM63lnV%7xqpUTEO43?UR5}4lrq9eM5Yam&~Px~5#p#1| z%CsH2PYjYA3uPMaxF7nDrgHF;FT?le3j;;q%Tw^wtFW*DLw~)n^{(adu@Iz7qVDt$ zf{38&yj8!KIT=N=+u37?ryK#~86VR9E;7`M{Bjcc_9)WfM;_Uc8sGP5sz2LD{a)sD zowpZxOJG2^OoE5~%;$s8k077CgKR5H0aiAbD+NCJaqfRIiX8ScZh9WwS|0EBUZ$DIuWv(56X)V1-g*K$31+2tm>M1u9aC z_|&xGn~^HMsZYir?%G(5dGNu4m8RP$sHhP|Y7-v}ZsO8ylA2{_jt{e&?rt`lZ4+Am zFb^~5%>B)sxpU6{imFnoCL`iYIDfQZ(IilZ5=59&n8D$)-(tKuq{&jplTzRl5$RN= z51|XCGIQMsuB({qqcM*%D#GxtkdCbj9t}&oz#!0STR4GotUv{9@`29=Bj73|Q*bQ_ z@db!4;-nlbAgXYzwO7yIAY3FGX21x?ErVNMg;nDRS!*hQ0vOwr)x4IK0D#iCWgvD#VTarkq+-DrWX#w*>7Pf33u4=;^D%1feMISr842t zW@FKWdL?r`I?x8wpTlS8pmQ&5U1i~BIL6Ru3)F#EtJkaADme0J@th1tg{=l9Xav`k zQn)ujM!ar_5;O>Nu76_O(%bsFoR5h z7UKx>@r8|rsCsQRU-1P%nD<+Zo92)vQAXp7IE6m@gHOX#uR+Qw9h_Kzjw7)D`Md|h zb2=!a%^^)101<{$4puC&a-aik@ZK3X__9|()>14E`<{b~KYzh9-FdMDq#P^}h9OqaN8iTXncz?iO{s7y8mV4m-9dK};2hZ2c70=HpoNVpY6PfFI22$i=m`K{gt!br} zl3?4#4d%=hn4Uvb8QI-Sj)%*u=&G(rzfqW)rDt)exO*)t(v0%l>xe7#=iBH1mv7J3 nZQ8Nq>bC6F^0m>s)c*ipo5z=40KumK0000 Date: Tue, 5 Aug 2014 19:58:36 +0200 Subject: [PATCH 035/149] changed happy emoticon --- smileys/default/emoticons.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smileys/default/emoticons.xml b/smileys/default/emoticons.xml index e78080516..f978d55d5 100644 --- a/smileys/default/emoticons.xml +++ b/smileys/default/emoticons.xml @@ -1,7 +1,7 @@ - + 😊 :) :-) From 45f178a47dd088a2ffe03d806f608be56c6912f9 Mon Sep 17 00:00:00 2001 From: Bill Winslow Date: Tue, 5 Aug 2014 18:57:16 -0500 Subject: [PATCH 036/149] update libsodium version in bootstrap.sh --- bootstrap.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bootstrap.sh b/bootstrap.sh index 4114f26db..d14549aa0 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -103,15 +103,15 @@ rm -rf ${BASE_DIR}/${TOX_CORE_DIR} if [[ $TOX_ONLY = "false" ]]; then git clone git://github.com/jedisct1/libsodium.git ${BASE_DIR}/${SODIUM_DIR} pushd ${BASE_DIR}/${SODIUM_DIR} - git checkout tags/0.5.0 + git checkout tags/0.6.1 ./autogen.sh - + if [[ $GLOBAL = "false" ]]; then ./configure --prefix=${BASE_DIR}/ else ./configure fi - + make -j2 check if [[ $GLOBAL = "false" ]]; then From ee184a558ca7dca44dd23abadf3e69b0a08230f2 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sat, 9 Aug 2014 22:07:32 +0200 Subject: [PATCH 037/149] Fallback to IPv4 if IPv6 fails Fixes #181 --- core.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/core.cpp b/core.cpp index 920c28218..b54b18783 100644 --- a/core.cpp +++ b/core.cpp @@ -97,9 +97,22 @@ void Core::start() tox = tox_new(enableIPv6); if (tox == nullptr) { - qCritical() << "Tox core failed to start"; - emit failedToStart(); - return; + if (enableIPv6) // Fallback to IPv4 + { + tox = tox_new(false); + if (tox == nullptr) + { + qCritical() << "Tox core failed to start"; + emit failedToStart(); + return; + } + } + else + { + qCritical() << "Tox core failed to start"; + emit failedToStart(); + return; + } } toxav = toxav_new(tox, TOXAV_MAX_CALLS); From 7557d92a9233c01fc405a691c2f825e27fedfdbe Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sat, 9 Aug 2014 22:12:34 +0200 Subject: [PATCH 038/149] Add log message when falling back to IPv4 --- core.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core.cpp b/core.cpp index b54b18783..509a5fdfc 100644 --- a/core.cpp +++ b/core.cpp @@ -106,6 +106,8 @@ void Core::start() emit failedToStart(); return; } + else + qWarning() << "Core failed to start with IPv6, falling back to IPv4. LAN discovery may not work properly."; } else { From ea3b2c95ee23382ac137f2d4691645987d3dabd3 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 10 Aug 2014 13:56:03 +0200 Subject: [PATCH 039/149] settings: default smiley pack --- res/settings.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/res/settings.ini b/res/settings.ini index e1420de5b..52a4f1d5f 100644 --- a/res/settings.ini +++ b/res/settings.ini @@ -64,3 +64,6 @@ dhtServerList\16\name=zlacki US dhtServerList\16\userId=9430A83211A7AD1C294711D069D587028CA0B4782FA43CB9B30008247A43C944 dhtServerList\16\address=69.42.220.58 dhtServerList\16\port=33445 + +[GUI] +smileyPack=smileys/default/emoticons.xml From 58b1f043e276c9db1ba10420b8143eb4eb6ee655 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 10 Aug 2014 14:38:41 +0200 Subject: [PATCH 040/149] show smiley widget only if there are smileys to show --- widget/form/chatform.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index 0e9e72f9f..e95748fe8 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -659,14 +659,18 @@ void ChatForm::onSaveLogClicked() void ChatForm::onEmoteButtonClicked() { + // don't show the smiley selection widget if there are no smileys available + if (SmileyPack::getInstance().getEmoticons().empty()) + return; + EmoticonsWidget widget; connect(&widget, &EmoticonsWidget::insertEmoticon, this, &ChatForm::onEmoteInsertRequested); QWidget* sender = qobject_cast(QObject::sender()); if (sender) { - QPoint pos(widget.sizeHint().width() / 2, widget.sizeHint().height()); - widget.exec(sender->mapToGlobal(-pos - QPoint(0, 10))); + QPoint pos = -QPoint(widget.sizeHint().width() / 2, widget.sizeHint().height()) - QPoint(0, 10); + widget.exec(sender->mapToGlobal(pos)); } } From d0b11074eb10b6bee32618ad6ebc9997a76119eb Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 10 Aug 2014 14:47:46 +0200 Subject: [PATCH 041/149] use the new signal slot syntax as they are checked at compile time --- widget/form/chatform.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index e95748fe8..903a50d19 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -184,14 +184,14 @@ ChatForm::ChatForm(Friend* chatFriend) connect(Widget::getInstance()->getCore(), &Core::fileSendStarted, this, &ChatForm::startFileSend); connect(Widget::getInstance()->getCore(), &Core::videoFrameReceived, netcam, &NetCamView::updateDisplay); - connect(sendButton, SIGNAL(clicked()), this, SLOT(onSendTriggered())); - connect(fileButton, SIGNAL(clicked()), this, SLOT(onAttachClicked())); - connect(callButton, SIGNAL(clicked()), this, SLOT(onCallTriggered())); - connect(videoButton, SIGNAL(clicked()), this, SLOT(onVideoCallTriggered())); - connect(msgEdit, SIGNAL(enterPressed()), this, SLOT(onSendTriggered())); - connect(chatArea->verticalScrollBar(), SIGNAL(rangeChanged(int,int)), this, SLOT(onSliderRangeChanged())); - connect(chatArea, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onChatContextMenuRequested(QPoint))); - connect(emoteButton, SIGNAL(clicked()), this, SLOT(onEmoteButtonClicked())); + connect(sendButton, &QPushButton::clicked, this, &ChatForm::onSendTriggered); + connect(fileButton, &QPushButton::clicked, this, &ChatForm::onAttachClicked); + connect(callButton, &QPushButton::clicked, this, &ChatForm::onCallTriggered); + connect(videoButton, &QPushButton::clicked, this, &ChatForm::onVideoCallTriggered); + connect(msgEdit, &ChatTextEdit::enterPressed, this, &ChatForm::onSendTriggered); + connect(chatArea->verticalScrollBar(), &QScrollBar::rangeChanged, this, &ChatForm::onSliderRangeChanged); + connect(chatArea, &QScrollArea::customContextMenuRequested, this, &ChatForm::onChatContextMenuRequested); + connect(emoteButton, &QPushButton::clicked, this, &ChatForm::onEmoteButtonClicked); } ChatForm::~ChatForm() From a3a0ee3923afbfa0d8e9294daf7d9f1e03deaaf7 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 10 Aug 2014 15:07:02 +0200 Subject: [PATCH 042/149] style update --- res.qrc | 1 + ui/emoticonWidget/dot_page_hover.png | Bin 0 -> 237 bytes ui/emoticonWidget/emoticonWidget.css | 11 ++++++----- 3 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 ui/emoticonWidget/dot_page_hover.png diff --git a/res.qrc b/res.qrc index 67c2ecf50..3afbcf5a4 100644 --- a/res.qrc +++ b/res.qrc @@ -114,5 +114,6 @@ ui/emoticonWidget/dot_page.png ui/emoticonWidget/dot_page_current.png ui/emoticonWidget/emoticonWidget.css + ui/emoticonWidget/dot_page_hover.png diff --git a/ui/emoticonWidget/dot_page_hover.png b/ui/emoticonWidget/dot_page_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..1c23931b921ef2be1841c3404062acc16234ebcc GIT binary patch literal 237 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4u_bxCyDx`7I;J! z19e;nVMZs7*%d%R_7YEDSN3}xT)a#cD-W8A0)?tPT^vIsF859_n|?OkWM;w5+g!63Nk^&N{kNTwEn(tCmYBn(>;Ycs z3Ene Date: Sun, 10 Aug 2014 15:11:59 +0200 Subject: [PATCH 043/149] tweaked page button --- widget/emoticonswidget.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/widget/emoticonswidget.cpp b/widget/emoticonswidget.cpp index 1b7866b85..b2796c999 100644 --- a/widget/emoticonswidget.cpp +++ b/widget/emoticonswidget.cpp @@ -64,12 +64,16 @@ EmoticonsWidget::EmoticonsWidget(QWidget *parent) : page->setLayout(pageLayout); stack.addWidget(page); - QRadioButton* pageButton = new QRadioButton; - pageButton->setProperty("pageIndex", i); - pageButton->setChecked(i == 0); - buttonLayout->addWidget(pageButton); + // page buttons are only needed if there is more than 1 page + if (pageCount > 1) + { + QRadioButton* pageButton = new QRadioButton; + pageButton->setProperty("pageIndex", i); + pageButton->setChecked(i == 0); + buttonLayout->addWidget(pageButton); - connect(pageButton, &QRadioButton::clicked, this, &EmoticonsWidget::onPageButtonClicked); + connect(pageButton, &QRadioButton::clicked, this, &EmoticonsWidget::onPageButtonClicked); + } } buttonLayout->addStretch(); From 8c32699608e4b94e923303af4c4d7ec8ddcf3914 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 10 Aug 2014 15:20:10 +0200 Subject: [PATCH 044/149] style update --- ui/emoticonWidget/emoticonWidget.css | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/ui/emoticonWidget/emoticonWidget.css b/ui/emoticonWidget/emoticonWidget.css index a21f4a769..a1aab7de3 100644 --- a/ui/emoticonWidget/emoticonWidget.css +++ b/ui/emoticonWidget/emoticonWidget.css @@ -33,16 +33,6 @@ QRadioButton::indicator::checked image: url(:/ui/emoticonWidget/dot_page_current.png); } -QRadioButton::indicator:checked:hover -{ - image: url(:/ui/emoticonWidget/dot_page_current.png); -} - -QRadioButton::indicator:checked:pressed -{ - image: url(:/ui/emoticonWidget/dot_page.png); -} - QMenu { background-color: rgb(240,240,240); /* sets background of the menu */ From af4623695c0b2f8c930435c9d0da871d1cce70da Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 10 Aug 2014 18:14:50 +0200 Subject: [PATCH 045/149] styling cleanup --- qtox.pro | 6 +- settings.cpp | 24 +++++ settings.h | 8 ++ style.cpp | 19 ++++ style.h | 14 +++ widget/form/chatform.cpp | 82 ++-------------- widget/widget.cpp | 207 ++++++++++++++++----------------------- 7 files changed, 160 insertions(+), 200 deletions(-) create mode 100644 style.cpp create mode 100644 style.h diff --git a/qtox.pro b/qtox.pro index 707599b6c..9f13b9176 100644 --- a/qtox.pro +++ b/qtox.pro @@ -85,7 +85,8 @@ HEADERS += widget/form/addfriendform.h \ widget/netcamview.h \ widget/tool/clickablelabel.h \ smileypack.h \ - widget/emoticonswidget.h + widget/emoticonswidget.h \ + style.h SOURCES += \ widget/form/addfriendform.cpp \ @@ -119,4 +120,5 @@ SOURCES += \ widget/netcamview.cpp \ widget/tool/clickablelabel.cpp \ smileypack.cpp \ - widget/emoticonswidget.cpp + widget/emoticonswidget.cpp \ + style.cpp diff --git a/settings.cpp b/settings.cpp index 2639731c5..83c85e63d 100644 --- a/settings.cpp +++ b/settings.cpp @@ -102,6 +102,8 @@ void Settings::load() secondColumnHandlePosFromRight = s.value("secondColumnHandlePosFromRight", 50).toInt(); timestampFormat = s.value("timestampFormat", "hh:mm").toString(); minimizeOnClose = s.value("minimizeOnClose", false).toBool(); + useNativeStyle = s.value("nativeStyle", false).toBool(); + useNativeDecoration = s.value("nativeDecoration", true).toBool(); s.endGroup(); s.beginGroup("Privacy"); @@ -158,6 +160,8 @@ void Settings::save(QString path) s.setValue("secondColumnHandlePosFromRight", secondColumnHandlePosFromRight); s.setValue("timestampFormat", timestampFormat); s.setValue("minimizeOnClose", minimizeOnClose); + s.setValue("nativeStyle", useNativeStyle); + s.setValue("nativeDecoration", useNativeDecoration); s.endGroup(); s.beginGroup("Privacy"); @@ -335,6 +339,26 @@ void Settings::setEmojiFontFamily(const QString &value) emit emojiFontChanged(); } +bool Settings::getUseNativeStyle() const +{ + return useNativeStyle; +} + +void Settings::setUseNativeStyle(bool value) +{ + useNativeStyle = value; +} + +bool Settings::getUseNativeDecoration() const +{ + return useNativeDecoration; +} + +void Settings::setUseNativeDecoration(bool value) +{ + useNativeDecoration = value; +} + bool Settings::isMinimizeOnCloseEnabled() const { return minimizeOnClose; diff --git a/settings.h b/settings.h index 95e16620f..eafd2aa58 100644 --- a/settings.h +++ b/settings.h @@ -112,6 +112,12 @@ public: bool isTypingNotificationEnabled() const; void setTypingNotification(bool enabled); + bool getUseNativeStyle() const; + void setUseNativeStyle(bool value); + + bool getUseNativeDecoration() const; + void setUseNativeDecoration(bool value); + private: Settings(); Settings(Settings &settings) = delete; @@ -147,6 +153,8 @@ private: QString emojiFontFamily; int emojiFontPointSize; bool minimizeOnClose; + bool useNativeStyle; + bool useNativeDecoration; // ChatView int firstColumnHandlePos; diff --git a/style.cpp b/style.cpp new file mode 100644 index 000000000..3a8cb1142 --- /dev/null +++ b/style.cpp @@ -0,0 +1,19 @@ +#include "style.h" +#include "settings.h" + +#include +#include + +QString Style::get(const QString &filename) +{ + if (!Settings::getInstance().getUseNativeStyle()) + { + QFile file(filename); + if (file.open(QFile::ReadOnly | QFile::Text)) + return file.readAll(); + else + qWarning() << "Style " << filename << " not found"; + } + + return QString(); +} diff --git a/style.h b/style.h new file mode 100644 index 000000000..37ec89828 --- /dev/null +++ b/style.h @@ -0,0 +1,14 @@ +#ifndef STYLE_H +#define STYLE_H + +#include + +class Style +{ +public: + static QString get(const QString& filename); +private: + Style(); +}; + +#endif // STYLE_H diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index 903a50d19..62ad56318 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -21,6 +21,7 @@ #include "widget/widget.h" #include "widget/filetransfertwidget.h" #include "widget/emoticonswidget.h" +#include "style.h" #include #include #include @@ -53,16 +54,8 @@ ChatForm::ChatForm(Friend* chatFriend) avatar->setPixmap(QPixmap(":/img/contact_dark.png")); chatAreaWidget->setLayout(mainChatLayout); - QString chatAreaStylesheet = ""; - try - { - QFile f(":/ui/chatArea/chatArea.css"); - f.open(QFile::ReadOnly | QFile::Text); - QTextStream chatAreaStylesheetStream(&f); - chatAreaStylesheet = chatAreaStylesheetStream.readAll(); - } - catch (int e) {} - chatArea->setStyleSheet(chatAreaStylesheet); + chatAreaWidget->setStyleSheet(Style::get(":/ui/chatArea/chatArea.css")); + chatArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); chatArea->setWidgetResizable(true); chatArea->setContextMenuPolicy(Qt::CustomContextMenu); @@ -73,76 +66,19 @@ ChatForm::ChatForm(Friend* chatFriend) footButtonsSmall->setSpacing(2); - QString msgEditStylesheet = ""; - try - { - QFile f(":/ui/msgEdit/msgEdit.css"); - f.open(QFile::ReadOnly | QFile::Text); - QTextStream msgEditStylesheetStream(&f); - msgEditStylesheet = msgEditStylesheetStream.readAll(); - } - catch (int e) {} - msgEdit->setStyleSheet(msgEditStylesheet); + msgEdit->setStyleSheet(Style::get(":/ui/msgEdit/msgEdit.css")); msgEdit->setFixedHeight(50); msgEdit->setFrameStyle(QFrame::NoFrame); - QString sendButtonStylesheet = ""; - try - { - QFile f(":/ui/sendButton/sendButton.css"); - f.open(QFile::ReadOnly | QFile::Text); - QTextStream sendButtonStylesheetStream(&f); - sendButtonStylesheet = sendButtonStylesheetStream.readAll(); - } - catch (int e) {} - sendButton->setStyleSheet(sendButtonStylesheet); + sendButton->setStyleSheet(Style::get(":/ui/sendButton/sendButton.css")); + fileButton->setStyleSheet(Style::get(":/ui/fileButton/fileButton.css")); + emoteButton->setStyleSheet(Style::get(":/ui/emoteButton/emoteButton.css")); - QString fileButtonStylesheet = ""; - try - { - QFile f(":/ui/fileButton/fileButton.css"); - f.open(QFile::ReadOnly | QFile::Text); - QTextStream fileButtonStylesheetStream(&f); - fileButtonStylesheet = fileButtonStylesheetStream.readAll(); - } - catch (int e) {} - fileButton->setStyleSheet(fileButtonStylesheet); - - - QString emoteButtonStylesheet = ""; - try - { - QFile f(":/ui/emoteButton/emoteButton.css"); - f.open(QFile::ReadOnly | QFile::Text); - QTextStream emoteButtonStylesheetStream(&f); - emoteButtonStylesheet = emoteButtonStylesheetStream.readAll(); - } - catch (int e) {} - emoteButton->setStyleSheet(emoteButtonStylesheet); - - QString callButtonStylesheet = ""; - try - { - QFile f(":/ui/callButton/callButton.css"); - f.open(QFile::ReadOnly | QFile::Text); - QTextStream callButtonStylesheetStream(&f); - callButtonStylesheet = callButtonStylesheetStream.readAll(); - } - catch (int e) {} callButton->setObjectName("green"); - callButton->setStyleSheet(callButtonStylesheet); + callButton->setStyleSheet(Style::get(":/ui/callButton/callButton.css")); - QString videoButtonStylesheet = ""; - try - { - QFile f(":/ui/videoButton/videoButton.css"); - f.open(QFile::ReadOnly | QFile::Text); - QTextStream videoButtonStylesheetStream(&f); - videoButtonStylesheet = videoButtonStylesheetStream.readAll(); - } - catch (int e) {} videoButton->setObjectName("green"); - videoButton->setStyleSheet(videoButtonStylesheet); + videoButton->setStyleSheet(Style::get(":/ui/videoButton/videoButton.css")); main->setLayout(mainLayout); mainLayout->addWidget(chatArea); diff --git a/widget/widget.cpp b/widget/widget.cpp index 890b0447a..519d69d94 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -25,6 +25,7 @@ #include "group.h" #include "widget/groupwidget.h" #include "widget/form/groupchatform.h" +#include "style.h" #include #include #include @@ -45,98 +46,54 @@ Widget::Widget(QWidget *parent) : { ui->setupUi(this); - QSettings settings(Settings::getInstance().getSettingsDirPath() + '/' + "windowSettings.ini", QSettings::IniFormat); - if (!settings.contains("useNativeTheme")) - useNativeTheme = 1; - else - useNativeTheme = settings.value("useNativeTheme").toInt(); + ui->titleBar->hide(); + layout()->setContentsMargins(0, 0, 0, 0); + ui->friendList->setObjectName("friendList"); + ui->friendList->setStyleSheet(Style::get(":ui/friendList/friendList.css")); - if (useNativeTheme) + setStyleSheet(Style::get(":ui/window/window.css")); + //ui->statusPanel->setStyleSheet(QString("")); + //ui->friendList->setStyleSheet(QString("")); + + ui->friendList->setObjectName("friendList"); + ui->friendList->setStyleSheet(Style::get(":ui/friendList/friendList.css")); + + ui->tbMenu->setIcon(QIcon(":ui/window/applicationIcon.png")); + ui->pbMin->setObjectName("minimizeButton"); + ui->pbMax->setObjectName("maximizeButton"); + ui->pbClose->setObjectName("closeButton"); + + if (!Settings::getInstance().getUseNativeDecoration()) { - ui->titleBar->hide(); - this->layout()->setContentsMargins(0, 0, 0, 0); - - QString friendListStylesheet = ""; - try - { - QFile f(":ui/friendList/friendList.css"); - f.open(QFile::ReadOnly | QFile::Text); - QTextStream friendListStylesheetStream(&f); - friendListStylesheet = friendListStylesheetStream.readAll(); - } - catch (int e) {} - ui->friendList->setObjectName("friendList"); - ui->friendList->setStyleSheet(friendListStylesheet); - } - else - { - QString windowStylesheet = ""; - try - { - QFile f(":ui/window/window.css"); - f.open(QFile::ReadOnly | QFile::Text); - QTextStream windowStylesheetStream(&f); - windowStylesheet = windowStylesheetStream.readAll(); - } - catch (int e) {} - this->setObjectName("activeWindow"); - this->setStyleSheet(windowStylesheet); - ui->statusPanel->setStyleSheet(QString("")); - ui->friendList->setStyleSheet(QString("")); - - QString friendListStylesheet = ""; - try - { - QFile f(":ui/friendList/friendList.css"); - f.open(QFile::ReadOnly | QFile::Text); - QTextStream friendListStylesheetStream(&f); - friendListStylesheet = friendListStylesheetStream.readAll(); - } - catch (int e) {} - ui->friendList->setObjectName("friendList"); - ui->friendList->setStyleSheet(friendListStylesheet); - - ui->tbMenu->setIcon(QIcon(":ui/window/applicationIcon.png")); - ui->pbMin->setObjectName("minimizeButton"); - ui->pbMax->setObjectName("maximizeButton"); - ui->pbClose->setObjectName("closeButton"); - setWindowFlags(Qt::CustomizeWindowHint); setWindowFlags(Qt::FramelessWindowHint); + } - addAction(ui->actionClose); + addAction(ui->actionClose); - connect(ui->pbMin, SIGNAL(clicked()), this, SLOT(minimizeBtnClicked())); - connect(ui->pbMax, SIGNAL(clicked()), this, SLOT(maximizeBtnClicked())); - connect(ui->pbClose, SIGNAL(clicked()), this, SLOT(close())); + connect(ui->pbMin, SIGNAL(clicked()), this, SLOT(minimizeBtnClicked())); + connect(ui->pbMax, SIGNAL(clicked()), this, SLOT(maximizeBtnClicked())); + connect(ui->pbClose, SIGNAL(clicked()), this, SLOT(close())); - m_titleMode = FullTitle; - moveWidget = false; - inResizeZone = false; - allowToResize = false; - resizeVerSup = false; - resizeHorEsq = false; - resizeDiagSupEsq = false; - resizeDiagSupDer = false; + m_titleMode = FullTitle; + moveWidget = false; + inResizeZone = false; + allowToResize = false; + resizeVerSup = false; + resizeHorEsq = false; + resizeDiagSupEsq = false; + resizeDiagSupDer = false; QSettings settings(Settings::getInstance().getSettingsDirPath() + '/' + "windowSettings.ini", QSettings::IniFormat); QRect geo = settings.value("geometry").toRect(); - if (geo.height() > 0 and geo.x() < QApplication::desktop()->width() and geo.width() > 0 and geo.y() < QApplication::desktop()->height()) - this->setGeometry(geo); + if (geo.height() > 0 and geo.x() < QApplication::desktop()->width() and geo.width() > 0 and geo.y() < QApplication::desktop()->height()) + this->setGeometry(geo); - if (settings.value("maximized").toBool()) - { - showMaximized(); - ui->pbMax->setObjectName("restoreButton"); - } - - QList widgets = this->findChildren(); - - foreach (QWidget *widget, widgets) - { - widget->setMouseTracking(true); - } + if (settings.value("maximized").toBool()) + { + showMaximized(); + ui->pbMax->setObjectName("restoreButton"); } isWindowMinimized = 0; @@ -174,11 +131,11 @@ Widget::Widget(QWidget *parent) : ui->statusButton->setMenu(statusButtonMenu); - this->setMouseTracking(true); +// this->setMouseTracking(true); - QList widgets = this->findChildren(); - foreach (QWidget *widget, widgets) - widget->setMouseTracking(true); +// QList widgets = this->findChildren(); +// foreach (QWidget *widget, widgets) +// widget->setMouseTracking(true); ui->titleBar->setMouseTracking(true); ui->LTitle->setMouseTracking(true); @@ -1116,47 +1073,47 @@ void Widget::setTitlebarMode(const TitleMode &flag) switch (m_titleMode) { - case CleanTitle: - ui->tbMenu->setHidden(true); - ui->pbMin->setHidden(true); - ui->pbMax->setHidden(true); - ui->pbClose->setHidden(true); - break; - case OnlyCloseButton: - ui->tbMenu->setHidden(true); - ui->pbMin->setHidden(true); - ui->pbMax->setHidden(true); - break; - case MenuOff: - ui->tbMenu->setHidden(true); - break; - case MaxMinOff: - ui->pbMin->setHidden(true); - ui->pbMax->setHidden(true); - break; - case FullScreenMode: - ui->pbMax->setHidden(true); - showMaximized(); - break; - case MaximizeModeOff: - ui->pbMax->setHidden(true); - break; - case MinimizeModeOff: - ui->pbMin->setHidden(true); - break; - case FullTitle: - ui->tbMenu->setVisible(true); - ui->pbMin->setVisible(true); - ui->pbMax->setVisible(true); - ui->pbClose->setVisible(true); - break; - break; - default: - ui->tbMenu->setVisible(true); - ui->pbMin->setVisible(true); - ui->pbMax->setVisible(true); - ui->pbClose->setVisible(true); - break; + case CleanTitle: + ui->tbMenu->setHidden(true); + ui->pbMin->setHidden(true); + ui->pbMax->setHidden(true); + ui->pbClose->setHidden(true); + break; + case OnlyCloseButton: + ui->tbMenu->setHidden(true); + ui->pbMin->setHidden(true); + ui->pbMax->setHidden(true); + break; + case MenuOff: + ui->tbMenu->setHidden(true); + break; + case MaxMinOff: + ui->pbMin->setHidden(true); + ui->pbMax->setHidden(true); + break; + case FullScreenMode: + ui->pbMax->setHidden(true); + showMaximized(); + break; + case MaximizeModeOff: + ui->pbMax->setHidden(true); + break; + case MinimizeModeOff: + ui->pbMin->setHidden(true); + break; + case FullTitle: + ui->tbMenu->setVisible(true); + ui->pbMin->setVisible(true); + ui->pbMax->setVisible(true); + ui->pbClose->setVisible(true); + break; + break; + default: + ui->tbMenu->setVisible(true); + ui->pbMin->setVisible(true); + ui->pbMax->setVisible(true); + ui->pbClose->setVisible(true); + break; } ui->LTitle->setVisible(true); } From 7dc00889ee1492f3f8fe59827acbff69f8a746ef Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 10 Aug 2014 18:50:40 +0200 Subject: [PATCH 046/149] settings: default smiley pack --- res/settings.ini | 3 --- settings.cpp | 6 +++++- smileypack.cpp | 5 +++++ smileypack.h | 1 + 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/res/settings.ini b/res/settings.ini index 52a4f1d5f..e1420de5b 100644 --- a/res/settings.ini +++ b/res/settings.ini @@ -64,6 +64,3 @@ dhtServerList\16\name=zlacki US dhtServerList\16\userId=9430A83211A7AD1C294711D069D587028CA0B4782FA43CB9B30008247A43C944 dhtServerList\16\address=69.42.220.58 dhtServerList\16\port=33445 - -[GUI] -smileyPack=smileys/default/emoticons.xml diff --git a/settings.cpp b/settings.cpp index 2639731c5..0ce006fb0 100644 --- a/settings.cpp +++ b/settings.cpp @@ -94,7 +94,7 @@ void Settings::load() s.beginGroup("GUI"); enableSmoothAnimation = s.value("smoothAnimation", true).toBool(); - smileyPack = s.value("smileyPack", !SmileyPack::listSmileyPacks().empty() ? SmileyPack::listSmileyPacks()[0].second : "").toString(); + smileyPack = s.value("smileyPack", QString()).toString(); customEmojiFont = s.value("customEmojiFont", true).toBool(); emojiFontFamily = s.value("emojiFontFamily", "DejaVu Sans").toString(); emojiFontPointSize = s.value("emojiFontPointSize", QApplication::font().pointSize()).toInt(); @@ -108,6 +108,10 @@ void Settings::load() typingNotification = s.value("typingNotification", false).toBool(); s.endGroup(); + // try to set a smiley pack if none is selected + if (!SmileyPack::isValid(smileyPack) && !SmileyPack::listSmileyPacks().isEmpty()) + smileyPack = SmileyPack::listSmileyPacks()[0].second; + loaded = true; } diff --git a/smileypack.cpp b/smileypack.cpp index e969de06a..dba5ac0c5 100644 --- a/smileypack.cpp +++ b/smileypack.cpp @@ -57,6 +57,11 @@ QList > SmileyPack::listSmileyPacks(const QString &path) return smileyPacks; } +bool SmileyPack::isValid(const QString &filename) +{ + return QFile(filename).exists(); +} + bool SmileyPack::load(const QString& filename) { // discard old data diff --git a/smileypack.h b/smileypack.h index 7800f0c93..b227e6bcb 100644 --- a/smileypack.h +++ b/smileypack.h @@ -29,6 +29,7 @@ class SmileyPack : public QObject public: static SmileyPack& getInstance(); static QList> listSmileyPacks(const QString& path = "./smileys"); + static bool isValid(const QString& filename); bool load(const QString &filename); QString smileyfied(QString msg); From 86e6f5f0d1f7a898abeac45ffc8917bc51491e40 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Sun, 10 Aug 2014 19:01:53 +0200 Subject: [PATCH 047/149] define SMILEYPACK_DEFAULT_PATH --- smileypack.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/smileypack.h b/smileypack.h index b227e6bcb..9f4ea31ba 100644 --- a/smileypack.h +++ b/smileypack.h @@ -22,13 +22,15 @@ #include #include +#define SMILEYPACK_DEFAULT_PATH "./smileys" + //maps emoticons to smileys class SmileyPack : public QObject { Q_OBJECT public: static SmileyPack& getInstance(); - static QList> listSmileyPacks(const QString& path = "./smileys"); + static QList> listSmileyPacks(const QString& path = SMILEYPACK_DEFAULT_PATH); static bool isValid(const QString& filename); bool load(const QString &filename); From 921b8478f64d471fa8c08541c1efe932bdb11fbf Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 11 Aug 2014 10:00:08 +0200 Subject: [PATCH 048/149] removed "the super ugly hack", Widget derives from QMainWindow --- mainwindow.ui | 3336 +++++++++++++++++++++++++++++++ qtox.pro | 9 +- settings.cpp | 24 + settings.h | 8 + style.cpp | 16 + style.h | 16 + widget.ui | 3341 -------------------------------- widget/adjustingscrollarea.cpp | 35 + widget/adjustingscrollarea.h | 35 + widget/form/addfriendform.cpp | 2 +- widget/form/addfriendform.h | 4 +- widget/form/chatform.cpp | 2 +- widget/form/chatform.h | 4 +- widget/form/filesform.cpp | 2 +- widget/form/filesform.h | 4 +- widget/form/groupchatform.cpp | 2 +- widget/form/groupchatform.h | 4 +- widget/form/settingsform.cpp | 2 +- widget/form/settingsform.h | 4 +- widget/friendwidget.cpp | 6 - widget/friendwidget.h | 1 - widget/groupwidget.cpp | 6 - widget/groupwidget.h | 6 +- widget/widget.cpp | 75 +- widget/widget.h | 15 +- 25 files changed, 3522 insertions(+), 3437 deletions(-) create mode 100644 mainwindow.ui delete mode 100644 widget.ui create mode 100644 widget/adjustingscrollarea.cpp create mode 100644 widget/adjustingscrollarea.h diff --git a/mainwindow.ui b/mainwindow.ui new file mode 100644 index 000000000..c4a3e92d7 --- /dev/null +++ b/mainwindow.ui @@ -0,0 +1,3336 @@ + + + MainWindow + + + + 0 + 0 + 882 + 600 + + + + + 640 + 420 + + + + qTox + + + + :/img/icon.png:/img/icon.png + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 0 + 23 + + + + + 16777215 + 23 + + + + + 4 + + + 5 + + + 0 + + + 1 + + + 0 + + + + + + 16 + 16 + + + + + 16 + 16 + + + + + 16 + 16 + + + + QToolButton::InstantPopup + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 15 + 1 + + + + + + + + + 100 + 22 + + + + + 16777215 + 22 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 134 + 20 + + + + + + + + + 22 + 22 + + + + + 22 + 22 + + + + + 22 + 22 + + + + true + + + + + + + + 22 + 22 + + + + + 22 + 22 + + + + + 22 + 22 + + + + true + + + + + + + + 22 + 22 + + + + + 22 + 22 + + + + + 22 + 22 + + + + true + + + + + + + + + + + 0 + 0 + + + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + + true + + + false + + + QSplitter{ + color: rgb(255, 255, 255); + background-color: rgb(255, 255, 255); + alternate-background-color: rgb(255, 255, 255); + border-color: rgb(255, 255, 255); + gridline-color: rgb(255, 255, 255); + selection-color: rgb(255, 255, 255); + selection-background-color: rgb(255, 255, 255); +} +QSplitter:handle{ + color: rgb(255, 255, 255); + background-color: rgb(255, 255, 255); +} + + + Qt::Horizontal + + + false + + + + + 0 + 0 + + + + + 225 + 0 + + + + + 1920 + 16777215 + + + + + + + + + 255 + 255 + 255 + + + + + + + 28 + 28 + 28 + + + + + + + 42 + 42 + 42 + + + + + + + 35 + 35 + 35 + + + + + + + 14 + 14 + 14 + + + + + + + 18 + 18 + 18 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 28 + 28 + 28 + + + + + + + 0 + 0 + 0 + + + + + + + 14 + 14 + 14 + + + + + + + 28 + 28 + 28 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + + 255 + 255 + 255 + + + + + + + 28 + 28 + 28 + + + + + + + 42 + 42 + 42 + + + + + + + 35 + 35 + 35 + + + + + + + 14 + 14 + 14 + + + + + + + 18 + 18 + 18 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 28 + 28 + 28 + + + + + + + 0 + 0 + 0 + + + + + + + 14 + 14 + 14 + + + + + + + 28 + 28 + 28 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + + 14 + 14 + 14 + + + + + + + 28 + 28 + 28 + + + + + + + 42 + 42 + 42 + + + + + + + 35 + 35 + 35 + + + + + + + 14 + 14 + 14 + + + + + + + 18 + 18 + 18 + + + + + + + 14 + 14 + 14 + + + + + + + 255 + 255 + 255 + + + + + + + 14 + 14 + 14 + + + + + + + 28 + 28 + 28 + + + + + + + 28 + 28 + 28 + + + + + + + 0 + 0 + 0 + + + + + + + 28 + 28 + 28 + + + + + + + 28 + 28 + 28 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + true + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + 0 + 0 + + + + + 225 + 60 + + + + + + + + + 255 + 255 + 255 + + + + + + + 28 + 28 + 28 + + + + + + + 42 + 42 + 42 + + + + + + + 35 + 35 + 35 + + + + + + + 14 + 14 + 14 + + + + + + + 18 + 18 + 18 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 28 + 28 + 28 + + + + + + + 0 + 0 + 0 + + + + + + + 14 + 14 + 14 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + + 255 + 255 + 255 + + + + + + + 28 + 28 + 28 + + + + + + + 42 + 42 + 42 + + + + + + + 35 + 35 + 35 + + + + + + + 14 + 14 + 14 + + + + + + + 18 + 18 + 18 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 28 + 28 + 28 + + + + + + + 0 + 0 + 0 + + + + + + + 14 + 14 + 14 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + + 14 + 14 + 14 + + + + + + + 28 + 28 + 28 + + + + + + + 42 + 42 + 42 + + + + + + + 35 + 35 + 35 + + + + + + + 14 + 14 + 14 + + + + + + + 18 + 18 + 18 + + + + + + + 14 + 14 + 14 + + + + + + + 255 + 255 + 255 + + + + + + + 14 + 14 + 14 + + + + + + + 28 + 28 + 28 + + + + + + + 28 + 28 + 28 + + + + + + + 0 + 0 + 0 + + + + + + + 28 + 28 + 28 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + true + + + + + + 0 + + + + + + 40 + 40 + + + + + 40 + 40 + + + + + + + :/img/contact.png + + + true + + + + + + + 0 + + + + + true + + + + 1 + 0 + + + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 240 + 240 + 240 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + + + 11 + 75 + true + + + + Your name + + + + + + + + 1 + 0 + + + + + + + + + 193 + 193 + 193 + + + + + + + 193 + 193 + 193 + + + + + + + + + 193 + 193 + 193 + + + + + + + 193 + 193 + 193 + + + + + + + + + 14 + 14 + 14 + + + + + + + 14 + 14 + 14 + + + + + + + + + 8 + + + + Your status + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + + 0 + 0 + + + + + 20 + 40 + + + + Qt::NoFocus + + + + + + + 10 + 10 + + + + false + + + false + + + false + + + true + + + + + + + + + + + + + 0 + 0 + + + + + 225 + 0 + + + + Qt::LeftToRight + + + true + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 501 + 430 + + + + + + + + + true + + + + 0 + 0 + + + + + 225 + 35 + + + + + + + + + 255 + 255 + 255 + + + + + + + 28 + 28 + 28 + + + + + + + 42 + 42 + 42 + + + + + + + 35 + 35 + 35 + + + + + + + 14 + 14 + 14 + + + + + + + 18 + 18 + 18 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 28 + 28 + 28 + + + + + + + 0 + 0 + 0 + + + + + + + 14 + 14 + 14 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + + 255 + 255 + 255 + + + + + + + 28 + 28 + 28 + + + + + + + 42 + 42 + 42 + + + + + + + 35 + 35 + 35 + + + + + + + 14 + 14 + 14 + + + + + + + 18 + 18 + 18 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 28 + 28 + 28 + + + + + + + 0 + 0 + 0 + + + + + + + 14 + 14 + 14 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + + 14 + 14 + 14 + + + + + + + 28 + 28 + 28 + + + + + + + 42 + 42 + 42 + + + + + + + 35 + 35 + 35 + + + + + + + 14 + 14 + 14 + + + + + + + 18 + 18 + 18 + + + + + + + 14 + 14 + 14 + + + + + + + 255 + 255 + 255 + + + + + + + 14 + 14 + 14 + + + + + + + 28 + 28 + 28 + + + + + + + 28 + 28 + 28 + + + + + + + 0 + 0 + 0 + + + + + + + 28 + 28 + 28 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + true + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 55 + 35 + + + + + 55 + 35 + + + + Qt::NoFocus + + + Add friends + + + + + + + :/img/add.png:/img/add.png + + + true + + + + + + + Qt::Horizontal + + + QSizePolicy::Maximum + + + + 500 + 20 + + + + + + + + + 55 + 35 + + + + Qt::NoFocus + + + Create a group chat + + + + + + + :/img/group.png:/img/group.png + + + true + + + + + + + Qt::Horizontal + + + QSizePolicy::Maximum + + + + 500 + 20 + + + + + + + + + 55 + 35 + + + + + 55 + 35 + + + + Qt::NoFocus + + + View completed file transfers + + + + + + + :/img/transfer.png:/img/transfer.png + + + true + + + + + + + Qt::Horizontal + + + QSizePolicy::Maximum + + + + 500 + 20 + + + + + + + + + 55 + 35 + + + + + 55 + 35 + + + + Qt::NoFocus + + + Change your settings + + + + + + + :/img/settings.png:/img/settings.png + + + true + + + + + + + + + + + + 1 + 0 + + + + + 375 + 0 + + + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 127 + 127 + 127 + + + + + + + 170 + 170 + 170 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 127 + 127 + 127 + + + + + + + 170 + 170 + 170 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + + 127 + 127 + 127 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 127 + 127 + 127 + + + + + + + 170 + 170 + 170 + + + + + + + 127 + 127 + 127 + + + + + + + 255 + 255 + 255 + + + + + + + 127 + 127 + 127 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + true + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + true + + + + + + + + 0 + 1 + + + + + 16777215 + 1 + + + + + + + + + 193 + 193 + 193 + + + + + + + + + 193 + 193 + 193 + + + + + + + + + 127 + 127 + 127 + + + + + + + + QFrame::HLine + + + QFrame::Plain + + + + + + + + 0 + 0 + + + + + 375 + 0 + + + + + + + + + + + + + true + + + + 0 + 0 + 882 + 24 + + + + + + + Close + + + Ctrl+Q + + + + + + EditableLabelWidget + QLabel +
widget/tool/editablelabelwidget.h
+
+ + AdjustingScrollArea + QScrollArea +
widget/adjustingscrollarea.h
+ 1 +
+
+ + + + +
diff --git a/qtox.pro b/qtox.pro index 9f13b9176..1ebaad38f 100644 --- a/qtox.pro +++ b/qtox.pro @@ -25,7 +25,8 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = qtox TEMPLATE = app -FORMS += widget.ui +FORMS += \ + mainwindow.ui CONFIG += c++11 TRANSLATIONS = translations/de.ts \ @@ -86,7 +87,8 @@ HEADERS += widget/form/addfriendform.h \ widget/tool/clickablelabel.h \ smileypack.h \ widget/emoticonswidget.h \ - style.h + style.h \ + widget/adjustingscrollarea.h SOURCES += \ widget/form/addfriendform.cpp \ @@ -121,4 +123,5 @@ SOURCES += \ widget/tool/clickablelabel.cpp \ smileypack.cpp \ widget/emoticonswidget.cpp \ - style.cpp + style.cpp \ + widget/adjustingscrollarea.cpp diff --git a/settings.cpp b/settings.cpp index 83c85e63d..19e9e1f93 100644 --- a/settings.cpp +++ b/settings.cpp @@ -104,6 +104,8 @@ void Settings::load() minimizeOnClose = s.value("minimizeOnClose", false).toBool(); useNativeStyle = s.value("nativeStyle", false).toBool(); useNativeDecoration = s.value("nativeDecoration", true).toBool(); + windowGeometry = s.value("windowGeometry", QByteArray()).toByteArray(); + windowState = s.value("windowState", QByteArray()).toByteArray(); s.endGroup(); s.beginGroup("Privacy"); @@ -162,6 +164,8 @@ void Settings::save(QString path) s.setValue("minimizeOnClose", minimizeOnClose); s.setValue("nativeStyle", useNativeStyle); s.setValue("nativeDecoration", useNativeDecoration); + s.setValue("windowGeometry", windowGeometry); + s.setValue("windowState", windowState); s.endGroup(); s.beginGroup("Privacy"); @@ -359,6 +363,26 @@ void Settings::setUseNativeDecoration(bool value) useNativeDecoration = value; } +QByteArray Settings::getWindowGeometry() const +{ + return windowGeometry; +} + +void Settings::setWindowGeometry(const QByteArray &value) +{ + windowGeometry = value; +} + +QByteArray Settings::getWindowState() const +{ + return windowState; +} + +void Settings::setWindowState(const QByteArray &value) +{ + windowState = value; +} + bool Settings::isMinimizeOnCloseEnabled() const { return minimizeOnClose; diff --git a/settings.h b/settings.h index eafd2aa58..a514350d5 100644 --- a/settings.h +++ b/settings.h @@ -118,6 +118,12 @@ public: bool getUseNativeDecoration() const; void setUseNativeDecoration(bool value); + QByteArray getWindowGeometry() const; + void setWindowGeometry(const QByteArray &value); + + QByteArray getWindowState() const; + void setWindowState(const QByteArray &value); + private: Settings(); Settings(Settings &settings) = delete; @@ -155,6 +161,8 @@ private: bool minimizeOnClose; bool useNativeStyle; bool useNativeDecoration; + QByteArray windowGeometry; + QByteArray windowState; // ChatView int firstColumnHandlePos; diff --git a/style.cpp b/style.cpp index 3a8cb1142..609dcc277 100644 --- a/style.cpp +++ b/style.cpp @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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. +*/ + #include "style.h" #include "settings.h" diff --git a/style.h b/style.h index 37ec89828..77a09ce25 100644 --- a/style.h +++ b/style.h @@ -1,3 +1,19 @@ +/* + Copyright (C) 2014 by Project Tox + + 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. +*/ + #ifndef STYLE_H #define STYLE_H diff --git a/widget.ui b/widget.ui deleted file mode 100644 index 3fd6e03bd..000000000 --- a/widget.ui +++ /dev/null @@ -1,3341 +0,0 @@ - - - Widget - - - - 0 - 0 - 640 - 420 - - - - - 640 - 420 - - - - - 16777215 - 16777215 - - - - Tox - - - - :/img/icon.png:/img/icon.png - - - - 2 - - - 1 - - - 2 - - - 2 - - - 0 - - - - - - 0 - 0 - - - - - 0 - 23 - - - - - 16777215 - 23 - - - - - 4 - - - 5 - - - 0 - - - 1 - - - 0 - - - - - - 16 - 16 - - - - - 16 - 16 - - - - - 16 - 16 - - - - QToolButton::InstantPopup - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 15 - 1 - - - - - - - - - 100 - 22 - - - - - 16777215 - 22 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Minimum - - - - 134 - 20 - - - - - - - - - 22 - 22 - - - - - 22 - 22 - - - - - 22 - 22 - - - - true - - - - - - - - 22 - 22 - - - - - 22 - 22 - - - - - 22 - 22 - - - - true - - - - - - - - 22 - 22 - - - - - 22 - 22 - - - - - 22 - 22 - - - - true - - - - - - - - - - - 0 - 0 - - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - - true - - - false - - - QSplitter{ - color: rgb(255, 255, 255); - background-color: rgb(255, 255, 255); - alternate-background-color: rgb(255, 255, 255); - border-color: rgb(255, 255, 255); - gridline-color: rgb(255, 255, 255); - selection-color: rgb(255, 255, 255); - selection-background-color: rgb(255, 255, 255); -} -QSplitter:handle{ - color: rgb(255, 255, 255); - background-color: rgb(255, 255, 255); -} - - - Qt::Horizontal - - - false - - - - - 0 - 0 - - - - - 225 - 0 - - - - - 1920 - 16777215 - - - - - - - - - 255 - 255 - 255 - - - - - - - 28 - 28 - 28 - - - - - - - 42 - 42 - 42 - - - - - - - 35 - 35 - 35 - - - - - - - 14 - 14 - 14 - - - - - - - 18 - 18 - 18 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 28 - 28 - 28 - - - - - - - 0 - 0 - 0 - - - - - - - 14 - 14 - 14 - - - - - - - 28 - 28 - 28 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - - 255 - 255 - 255 - - - - - - - 28 - 28 - 28 - - - - - - - 42 - 42 - 42 - - - - - - - 35 - 35 - 35 - - - - - - - 14 - 14 - 14 - - - - - - - 18 - 18 - 18 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 28 - 28 - 28 - - - - - - - 0 - 0 - 0 - - - - - - - 14 - 14 - 14 - - - - - - - 28 - 28 - 28 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - - 14 - 14 - 14 - - - - - - - 28 - 28 - 28 - - - - - - - 42 - 42 - 42 - - - - - - - 35 - 35 - 35 - - - - - - - 14 - 14 - 14 - - - - - - - 18 - 18 - 18 - - - - - - - 14 - 14 - 14 - - - - - - - 255 - 255 - 255 - - - - - - - 14 - 14 - 14 - - - - - - - 28 - 28 - 28 - - - - - - - 28 - 28 - 28 - - - - - - - 0 - 0 - 0 - - - - - - - 28 - 28 - 28 - - - - - - - 28 - 28 - 28 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - true - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - true - - - - 0 - 0 - - - - - 225 - 60 - - - - - - - - - 255 - 255 - 255 - - - - - - - 28 - 28 - 28 - - - - - - - 42 - 42 - 42 - - - - - - - 35 - 35 - 35 - - - - - - - 14 - 14 - 14 - - - - - - - 18 - 18 - 18 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 28 - 28 - 28 - - - - - - - 0 - 0 - 0 - - - - - - - 14 - 14 - 14 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - - 255 - 255 - 255 - - - - - - - 28 - 28 - 28 - - - - - - - 42 - 42 - 42 - - - - - - - 35 - 35 - 35 - - - - - - - 14 - 14 - 14 - - - - - - - 18 - 18 - 18 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 28 - 28 - 28 - - - - - - - 0 - 0 - 0 - - - - - - - 14 - 14 - 14 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - - 14 - 14 - 14 - - - - - - - 28 - 28 - 28 - - - - - - - 42 - 42 - 42 - - - - - - - 35 - 35 - 35 - - - - - - - 14 - 14 - 14 - - - - - - - 18 - 18 - 18 - - - - - - - 14 - 14 - 14 - - - - - - - 255 - 255 - 255 - - - - - - - 14 - 14 - 14 - - - - - - - 28 - 28 - 28 - - - - - - - 28 - 28 - 28 - - - - - - - 0 - 0 - 0 - - - - - - - 28 - 28 - 28 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - true - - - - - - 0 - - - - - - 40 - 40 - - - - - 40 - 40 - - - - - - - :/img/contact.png - - - true - - - - - - - 0 - - - - - true - - - - 1 - 0 - - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 240 - 240 - 240 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - - - 11 - 75 - true - - - - Your name - - - - - - - - 1 - 0 - - - - - - - - - 193 - 193 - 193 - - - - - - - 193 - 193 - 193 - - - - - - - - - 193 - 193 - 193 - - - - - - - 193 - 193 - 193 - - - - - - - - - 14 - 14 - 14 - - - - - - - 14 - 14 - 14 - - - - - - - - - 8 - - - - Your status - - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 10 - 20 - - - - - - - - - 0 - 0 - - - - - 20 - 40 - - - - Qt::NoFocus - - - - - - - 10 - 10 - - - - false - - - false - - - false - - - true - - - - - - - - - - - - - 0 - 0 - - - - - 225 - 0 - - - - Qt::RightToLeft - - - true - - - QFrame::NoFrame - - - Qt::ScrollBarAlwaysOff - - - true - - - - - 0 - 0 - 255 - 299 - - - - - - - - - true - - - - 0 - 0 - - - - - 225 - 35 - - - - - - - - - 255 - 255 - 255 - - - - - - - 28 - 28 - 28 - - - - - - - 42 - 42 - 42 - - - - - - - 35 - 35 - 35 - - - - - - - 14 - 14 - 14 - - - - - - - 18 - 18 - 18 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 28 - 28 - 28 - - - - - - - 0 - 0 - 0 - - - - - - - 14 - 14 - 14 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - - 255 - 255 - 255 - - - - - - - 28 - 28 - 28 - - - - - - - 42 - 42 - 42 - - - - - - - 35 - 35 - 35 - - - - - - - 14 - 14 - 14 - - - - - - - 18 - 18 - 18 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 28 - 28 - 28 - - - - - - - 0 - 0 - 0 - - - - - - - 14 - 14 - 14 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - - 14 - 14 - 14 - - - - - - - 28 - 28 - 28 - - - - - - - 42 - 42 - 42 - - - - - - - 35 - 35 - 35 - - - - - - - 14 - 14 - 14 - - - - - - - 18 - 18 - 18 - - - - - - - 14 - 14 - 14 - - - - - - - 255 - 255 - 255 - - - - - - - 14 - 14 - 14 - - - - - - - 28 - 28 - 28 - - - - - - - 28 - 28 - 28 - - - - - - - 0 - 0 - 0 - - - - - - - 28 - 28 - 28 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - true - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 55 - 35 - - - - - 55 - 35 - - - - Qt::NoFocus - - - Add friends - - - - - - - :/img/add.png:/img/add.png - - - true - - - - - - - Qt::Horizontal - - - QSizePolicy::Maximum - - - - 500 - 20 - - - - - - - - - 55 - 35 - - - - Qt::NoFocus - - - Create a group chat - - - - - - - :/img/group.png:/img/group.png - - - true - - - - - - - Qt::Horizontal - - - QSizePolicy::Maximum - - - - 500 - 20 - - - - - - - - - 55 - 35 - - - - - 55 - 35 - - - - Qt::NoFocus - - - View completed file transfers - - - - - - - :/img/transfer.png:/img/transfer.png - - - true - - - - - - - Qt::Horizontal - - - QSizePolicy::Maximum - - - - 500 - 20 - - - - - - - - - 55 - 35 - - - - - 55 - 35 - - - - Qt::NoFocus - - - Change your settings - - - - - - - :/img/settings.png:/img/settings.png - - - true - - - - - - - - - - - - 1 - 0 - - - - - 375 - 0 - - - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 127 - 127 - 127 - - - - - - - 170 - 170 - 170 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 127 - 127 - 127 - - - - - - - 170 - 170 - 170 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - - 127 - 127 - 127 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 127 - 127 - 127 - - - - - - - 170 - 170 - 170 - - - - - - - 127 - 127 - 127 - - - - - - - 255 - 255 - 255 - - - - - - - 127 - 127 - 127 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - true - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - true - - - - - - - - 0 - 1 - - - - - 16777215 - 1 - - - - - - - - - 193 - 193 - 193 - - - - - - - - - 193 - 193 - 193 - - - - - - - - - 127 - 127 - 127 - - - - - - - - QFrame::HLine - - - QFrame::Plain - - - - - - - - 0 - 0 - - - - - 375 - 0 - - - - - - - - - - - - Close - - - Ctrl+Q - - - - - - - EditableLabelWidget - QLabel -
widget/tool/editablelabelwidget.h
-
-
- - - - - - actionClose - triggered() - Widget - close() - - - -1 - -1 - - - 69 - 61 - - - - -
diff --git a/widget/adjustingscrollarea.cpp b/widget/adjustingscrollarea.cpp new file mode 100644 index 000000000..02e5b8746 --- /dev/null +++ b/widget/adjustingscrollarea.cpp @@ -0,0 +1,35 @@ +/* + Copyright (C) 2014 by Project Tox + + 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. +*/ + +#include "adjustingscrollarea.h" + +#include +#include + +AdjustingScrollArea::AdjustingScrollArea(QWidget *parent) : + QScrollArea(parent) +{ +} + +void AdjustingScrollArea::resizeEvent(QResizeEvent *ev) +{ + if (widget()) + { + widget()->setMinimumWidth(width()); + } + + QScrollArea::resizeEvent(ev); +} diff --git a/widget/adjustingscrollarea.h b/widget/adjustingscrollarea.h new file mode 100644 index 000000000..de6a85ac3 --- /dev/null +++ b/widget/adjustingscrollarea.h @@ -0,0 +1,35 @@ +/* + Copyright (C) 2014 by Project Tox + + 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. +*/ + +#ifndef ADJUSTINGSCROLLAREA_H +#define ADJUSTINGSCROLLAREA_H + +#include + +class AdjustingScrollArea : public QScrollArea +{ + Q_OBJECT +public: + explicit AdjustingScrollArea(QWidget *parent = 0); + + virtual void resizeEvent(QResizeEvent *ev); +signals: + +public slots: + +}; + +#endif // ADJUSTINGSCROLLAREA_H diff --git a/widget/form/addfriendform.cpp b/widget/form/addfriendform.cpp index d83e9b5b3..9d09e0682 100644 --- a/widget/form/addfriendform.cpp +++ b/widget/form/addfriendform.cpp @@ -57,7 +57,7 @@ AddFriendForm::~AddFriendForm() main->deleteLater(); } -void AddFriendForm::show(Ui::Widget &ui) +void AddFriendForm::show(Ui::MainWindow &ui) { ui.mainContent->layout()->addWidget(main); ui.mainHead->layout()->addWidget(head); diff --git a/widget/form/addfriendform.h b/widget/form/addfriendform.h index 7f2263827..0edcf2214 100644 --- a/widget/form/addfriendform.h +++ b/widget/form/addfriendform.h @@ -17,7 +17,7 @@ #ifndef ADDFRIENDFORM_H #define ADDFRIENDFORM_H -#include "ui_widget.h" +#include "ui_mainwindow.h" #include #include @@ -33,7 +33,7 @@ public: AddFriendForm(); ~AddFriendForm(); - void show(Ui::Widget& ui); + void show(Ui::MainWindow &ui); bool isToxId(const QString& value) const; void showWarning(const QString& message) const; QString getMessage() const; diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index 62ad56318..f5c1487a8 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -137,7 +137,7 @@ ChatForm::~ChatForm() delete netcam; } -void ChatForm::show(Ui::Widget &ui) +void ChatForm::show(Ui::MainWindow &ui) { ui.mainContent->layout()->addWidget(main); ui.mainHead->layout()->addWidget(head); diff --git a/widget/form/chatform.h b/widget/form/chatform.h index 064e05b29..3354629d6 100644 --- a/widget/form/chatform.h +++ b/widget/form/chatform.h @@ -28,7 +28,7 @@ #include #include "widget/tool/chattextedit.h" -#include "ui_widget.h" +#include "ui_mainwindow.h" #include "core.h" #include "widget/netcamview.h" @@ -43,7 +43,7 @@ class ChatForm : public QObject public: ChatForm(Friend* chatFriend); ~ChatForm(); - void show(Ui::Widget& ui); + void show(Ui::MainWindow &ui); void setName(QString newName); void setStatusMessage(QString newMessage); void addFriendMessage(QString message); diff --git a/widget/form/filesform.cpp b/widget/form/filesform.cpp index 14ffe5fe0..6d69c1f5a 100644 --- a/widget/form/filesform.cpp +++ b/widget/form/filesform.cpp @@ -50,7 +50,7 @@ FilesForm::~FilesForm() // I'm not too bummed about removing it } -void FilesForm::show(Ui::Widget& ui) +void FilesForm::show(Ui::MainWindow& ui) { ui.mainContent->layout()->addWidget(&main); ui.mainHead->layout()->addWidget(head); diff --git a/widget/form/filesform.h b/widget/form/filesform.h index f8fb51105..0f1a2b1d8 100644 --- a/widget/form/filesform.h +++ b/widget/form/filesform.h @@ -17,7 +17,7 @@ #ifndef FILESFORM_H #define FILESFORM_H -#include "ui_widget.h" +#include "ui_mainwindow.h" #include #include @@ -37,7 +37,7 @@ public: FilesForm(); ~FilesForm(); - void show(Ui::Widget& ui); + void show(Ui::MainWindow &ui); public slots: void onFileDownloadComplete(const QString& path); diff --git a/widget/form/groupchatform.cpp b/widget/form/groupchatform.cpp index f3f12afcf..919c457d7 100644 --- a/widget/form/groupchatform.cpp +++ b/widget/form/groupchatform.cpp @@ -142,7 +142,7 @@ GroupChatForm::~GroupChatForm() delete main; } -void GroupChatForm::show(Ui::Widget &ui) +void GroupChatForm::show(Ui::MainWindow &ui) { ui.mainContent->layout()->addWidget(main); ui.mainHead->layout()->addWidget(head); diff --git a/widget/form/groupchatform.h b/widget/form/groupchatform.h index b4ac9a5ce..af008476a 100644 --- a/widget/form/groupchatform.h +++ b/widget/form/groupchatform.h @@ -27,7 +27,7 @@ #include #include "widget/tool/chattextedit.h" -#include "ui_widget.h" +#include "ui_mainwindow.h" // Spacing in px inserted when the author of the last message changes #define AUTHOR_CHANGE_SPACING 5 @@ -40,7 +40,7 @@ class GroupChatForm : public QObject public: GroupChatForm(Group* chatGroup); ~GroupChatForm(); - void show(Ui::Widget& ui); + void show(Ui::MainWindow &ui); void setName(QString newName); void addGroupMessage(QString message, int peerId); void addMessage(QString author, QString message, QString date=QTime::currentTime().toString("hh:mm")); diff --git a/widget/form/settingsform.cpp b/widget/form/settingsform.cpp index 822cae675..193fac4a1 100644 --- a/widget/form/settingsform.cpp +++ b/widget/form/settingsform.cpp @@ -93,7 +93,7 @@ void SettingsForm::setFriendAddress(const QString& friendAddress) id.setText(friendAddress); } -void SettingsForm::show(Ui::Widget &ui) +void SettingsForm::show(Ui::MainWindow &ui) { name.setText(ui.nameLabel->text()); statusText.setText(ui.statusLabel->text()); diff --git a/widget/form/settingsform.h b/widget/form/settingsform.h index db5a395cf..0c8f59ee4 100644 --- a/widget/form/settingsform.h +++ b/widget/form/settingsform.h @@ -28,7 +28,7 @@ #include #include #include "widget/tool/clickablelabel.h" -#include "ui_widget.h" +#include "ui_mainwindow.h" #include "widget/selfcamview.h" class SettingsForm : public QObject @@ -38,7 +38,7 @@ public: SettingsForm(); ~SettingsForm(); - void show(Ui::Widget& ui); + void show(Ui::MainWindow &ui); public slots: void setFriendAddress(const QString& friendAddress); diff --git a/widget/friendwidget.cpp b/widget/friendwidget.cpp index 845bf816c..a430288a0 100644 --- a/widget/friendwidget.cpp +++ b/widget/friendwidget.cpp @@ -27,7 +27,6 @@ FriendWidget::FriendWidget(int FriendId, QString id) { this->setMouseTracking(true); this->setAutoFillBackground(true); - this->setFixedWidth(225); this->setFixedHeight(55); this->setLayout(&layout); layout.setSpacing(0); @@ -70,11 +69,6 @@ FriendWidget::FriendWidget(int FriendId, QString id) isActiveWidget = 0; } -void FriendWidget::setNewFixedWidth(int newWidth) -{ - this->setFixedWidth(newWidth); -} - void FriendWidget::mouseReleaseEvent (QMouseEvent*) { emit friendWidgetClicked(this); diff --git a/widget/friendwidget.h b/widget/friendwidget.h index 091f78c69..6afcdc1aa 100644 --- a/widget/friendwidget.h +++ b/widget/friendwidget.h @@ -34,7 +34,6 @@ public: void leaveEvent(QEvent* event); void setAsActiveChatroom(); void setAsInactiveChatroom(); - void setNewFixedWidth(int newWidth); signals: void friendWidgetClicked(FriendWidget* widget); diff --git a/widget/groupwidget.cpp b/widget/groupwidget.cpp index 6eb995031..7a138e28a 100644 --- a/widget/groupwidget.cpp +++ b/widget/groupwidget.cpp @@ -27,7 +27,6 @@ GroupWidget::GroupWidget(int GroupId, QString Name) this->setMouseTracking(true); this->setAutoFillBackground(true); this->setLayout(&layout); - this->setFixedWidth(225); this->setFixedHeight(55); layout.setSpacing(0); layout.setMargin(0); @@ -72,11 +71,6 @@ GroupWidget::GroupWidget(int GroupId, QString Name) isActiveWidget = 0; } -void GroupWidget::setNewFixedWidth(int newWidth) -{ - this->setFixedWidth(newWidth); -} - void GroupWidget::mouseReleaseEvent (QMouseEvent*) { emit groupWidgetClicked(this); diff --git a/widget/groupwidget.h b/widget/groupwidget.h index fe66a2371..ab2cf8929 100644 --- a/widget/groupwidget.h +++ b/widget/groupwidget.h @@ -33,7 +33,8 @@ public: void contextMenuEvent(QContextMenuEvent * event); void enterEvent(QEvent* event); void leaveEvent(QEvent* event); - + void setAsInactiveChatroom(); + void setAsActiveChatroom(); signals: void groupWidgetClicked(GroupWidget* widget); @@ -44,9 +45,6 @@ public: QLabel avatar, name, nusers, statusPic; QHBoxLayout layout; QVBoxLayout textLayout; - void setAsInactiveChatroom(); - void setAsActiveChatroom(); - void setNewFixedWidth(int newWidth); private: QColor lastColor; diff --git a/widget/widget.cpp b/widget/widget.cpp index 519d69d94..c7d6eda88 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -15,7 +15,7 @@ */ #include "widget.h" -#include "ui_widget.h" +#include "ui_mainwindow.h" #include "settings.h" #include "friend.h" #include "friendlist.h" @@ -41,11 +41,21 @@ Widget *Widget::instance{nullptr}; -Widget::Widget(QWidget *parent) : - QWidget(parent), ui(new Ui::Widget), activeFriendWidget{nullptr}, activeGroupWidget{nullptr} +Widget::Widget(QWidget *parent) + : QMainWindow(parent), + ui(new Ui::MainWindow), + activeFriendWidget{nullptr}, + activeGroupWidget{nullptr} { ui->setupUi(this); + ui->statusbar->hide(); + ui->menubar->hide(); + + //restore window state + restoreGeometry(Settings::getInstance().getWindowGeometry()); + restoreState(Settings::getInstance().getWindowState()); + ui->titleBar->hide(); layout()->setContentsMargins(0, 0, 0, 0); ui->friendList->setObjectName("friendList"); @@ -84,29 +94,17 @@ Widget::Widget(QWidget *parent) : resizeDiagSupEsq = false; resizeDiagSupDer = false; - QSettings settings(Settings::getInstance().getSettingsDirPath() + '/' + "windowSettings.ini", QSettings::IniFormat); - QRect geo = settings.value("geometry").toRect(); - - if (geo.height() > 0 and geo.x() < QApplication::desktop()->width() and geo.width() > 0 and geo.y() < QApplication::desktop()->height()) - this->setGeometry(geo); - - if (settings.value("maximized").toBool()) - { - showMaximized(); - ui->pbMax->setObjectName("restoreButton"); - } - isWindowMinimized = 0; ui->mainContent->setLayout(new QVBoxLayout()); ui->mainHead->setLayout(new QVBoxLayout()); ui->mainHead->layout()->setMargin(0); ui->mainHead->layout()->setSpacing(0); + QWidget* friendListWidget = new QWidget(); friendListWidget->setLayout(new QVBoxLayout()); friendListWidget->layout()->setSpacing(0); friendListWidget->layout()->setMargin(0); - friendListWidget->setLayoutDirection(Qt::LeftToRight); ui->friendList->setWidget(friendListWidget); // delay setting username and message until Core inits @@ -116,10 +114,7 @@ Widget::Widget(QWidget *parent) : ui->statusLabel->label->setStyleSheet("QLabel { color : white; font-size: 8pt;}"); ui->friendList->widget()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - QFile f1(":/ui/statusButton/statusButton.css"); - f1.open(QFile::ReadOnly | QFile::Text); - QTextStream statusButtonStylesheetStream(&f1); - ui->statusButton->setStyleSheet(statusButtonStylesheetStream.readAll()); + ui->statusButton->setStyleSheet(Style::get(":/ui/statusButton/statusButton.css")); QMenu *statusButtonMenu = new QMenu(ui->statusButton); QAction* setStatusOnline = statusButtonMenu->addAction(tr("Online","Button to set your status to 'Online'")); @@ -147,9 +142,9 @@ Widget::Widget(QWidget *parent) : ui->friendList->viewport()->installEventFilter(this); - QList currentSizes = ui->centralWidget->sizes(); - currentSizes[0] = 225; - ui->centralWidget->setSizes(currentSizes); +// QList currentSizes = ui->centralWidget->sizes(); +// currentSizes[0] = 225; +// ui->centralWidget->setSizes(currentSizes); ui->statusButton->setObjectName("offline"); ui->statusButton->style()->polish(ui->statusButton); @@ -198,7 +193,6 @@ Widget::Widget(QWidget *parent) : connect(this, &Widget::friendRequested, core, &Core::requestFriendship); connect(this, &Widget::friendRequestAccepted, core, &Core::acceptFriendRequest); - connect(ui->centralWidget, SIGNAL(splitterMoved(int,int)),this, SLOT(splitterMoved(int,int))); connect(ui->addButton, SIGNAL(clicked()), this, SLOT(onAddClicked())); connect(ui->groupButton, SIGNAL(clicked()), this, SLOT(onGroupClicked())); connect(ui->transferButton, SIGNAL(clicked()), this, SLOT(onTransferClicked())); @@ -236,10 +230,6 @@ Widget::~Widget() for (Group* g : GroupList::groupList) delete g; GroupList::groupList.clear(); - QSettings settings(Settings::getInstance().getSettingsDirPath() + '/' + "windowSettings.ini", QSettings::IniFormat); - settings.setValue("geometry", geometry()); - settings.setValue("maximized", isMaximized()); - settings.setValue("useNativeTheme", useNativeTheme); delete ui; } @@ -250,27 +240,16 @@ Widget* Widget::getInstance() return instance; } -//Super ugly hack to enable resizable friend widgets -//There should be a way to set them to resize automagicly, but I can't seem to find it. -void Widget::splitterMoved(int, int) -{ - updateFriendListWidth(); -} - QThread* Widget::getCoreThread() { return coreThread; } -void Widget::updateFriendListWidth() +void Widget::closeEvent(QCloseEvent *event) { - int newWidth = ui->friendList->width(); - for (Friend* f : FriendList::friendList) - if (f->widget != nullptr) - f->widget->setNewFixedWidth(newWidth); - for (Group* g : GroupList::groupList) - if (g->widget != nullptr) - g->widget->setNewFixedWidth(newWidth); + Settings::getInstance().setWindowGeometry(saveGeometry()); + Settings::getInstance().setWindowState(saveState()); + QWidget::closeEvent(event); } QString Widget::getUsername() @@ -432,7 +411,6 @@ void Widget::addFriend(int friendId, const QString &userId) QWidget* widget = ui->friendList->widget(); QLayout* layout = widget->layout(); layout->addWidget(newfriend->widget); - updateFriendListWidth(); connect(newfriend->widget, SIGNAL(friendWidgetClicked(FriendWidget*)), this, SLOT(onFriendWidgetClicked(FriendWidget*))); connect(newfriend->widget, SIGNAL(removeFriend(int)), this, SLOT(removeFriend(int))); connect(newfriend->widget, SIGNAL(copyFriendIdToClipboard(int)), this, SLOT(copyFriendIdToClipboard(int))); @@ -736,7 +714,7 @@ Group *Widget::createGroup(int groupId) layout->addWidget(newgroup->widget); if (!useNativeTheme) newgroup->widget->statusPic.setPixmap(QPixmap(":img/status/dot_groupchat.png")); - updateFriendListWidth(); + connect(newgroup->widget, SIGNAL(groupWidgetClicked(GroupWidget*)), this, SLOT(onGroupWidgetClicked(GroupWidget*))); connect(newgroup->widget, SIGNAL(removeGroup(int)), this, SLOT(removeGroup(int))); connect(newgroup->chatForm, SIGNAL(sendMessage(int,QString)), core, SLOT(sendGroupMessage(int,QString))); @@ -768,12 +746,6 @@ bool Widget::isFriendWidgetCurActiveWidget(Friend* f) return true; } -void Widget::resizeEvent(QResizeEvent *) -{ - updateFriendListWidth(); -} - - bool Widget::event(QEvent * e) { @@ -944,7 +916,6 @@ void Widget::moveWindow(QMouseEvent *e) void Widget::resizeWindow(QMouseEvent *e) { - updateFriendListWidth(); if (!useNativeTheme) { if (allowToResize) diff --git a/widget/widget.h b/widget/widget.h index 9db9057b5..0980cff69 100644 --- a/widget/widget.h +++ b/widget/widget.h @@ -18,7 +18,7 @@ #define WIDGET_H #include -#include +#include #include #include #include @@ -31,7 +31,7 @@ #define PIXELS_TO_ACT 7 namespace Ui { -class Widget; +class MainWindow; } class GroupWidget; @@ -39,7 +39,7 @@ struct FriendWidget; class Group; struct Friend; -class Widget : public QWidget +class Widget : public QMainWindow { Q_OBJECT @@ -60,7 +60,8 @@ public: void updateFriendStatusLights(int friendId); int useNativeTheme; ~Widget(); - void updateFriendListWidth(); + + virtual void closeEvent(QCloseEvent *event); signals: void friendRequestAccepted(const QString& userId); @@ -70,9 +71,6 @@ signals: void usernameChanged(const QString& username); void statusMessageChanged(const QString& statusMessage); -protected: - void resizeEvent(QResizeEvent *); - private slots: void maximizeBtnClicked(); void minimizeBtnClicked(); @@ -108,7 +106,6 @@ private slots: void removeFriend(int friendId); void copyFriendIdToClipboard(int friendId); void removeGroup(int groupId); - void splitterMoved(int pos, int index); void setStatusOnline(); void setStatusAway(); void setStatusBusy(); @@ -121,7 +118,7 @@ private: Group* createGroup(int groupId); private: - Ui::Widget *ui; + Ui::MainWindow *ui; QSplitter *centralLayout; QPoint dragPosition; TitleMode m_titleMode; From c9d04748dd38278a15456cf8048153d6afd598e1 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 11 Aug 2014 13:56:52 +0200 Subject: [PATCH 049/149] put back the not so native window decoration, status panel respects friendlist width, some tweaks to the layout --- mainwindow.ui | 112 ++++++------------------------ widget/adjustingscrollarea.cpp | 16 +++-- widget/adjustingscrollarea.h | 1 + widget/friendwidget.cpp | 11 +++ widget/widget.cpp | 120 +++++++++++++++++---------------- widget/widget.h | 1 - 6 files changed, 104 insertions(+), 157 deletions(-) diff --git a/mainwindow.ui b/mainwindow.ui index c4a3e92d7..3509b23d6 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -6,8 +6,8 @@ 0 0 - 882 - 600 + 716 + 543 @@ -232,6 +232,12 @@ 0 + + + 16777215 + 16777215 + + @@ -536,6 +542,9 @@ QSplitter:handle{ Qt::Horizontal + + 6 + false @@ -546,18 +555,6 @@ QSplitter:handle{ 0 - - - 225 - 0 - - - - - 1920 - 16777215 - - @@ -1030,12 +1027,6 @@ QSplitter:handle{ 0 - - - 225 - 60 - - @@ -2076,17 +2067,11 @@ QSplitter:handle{ - + 0 0 - - - 225 - 0 - - Qt::LeftToRight @@ -2107,10 +2092,11 @@ QSplitter:handle{ 0 0 - 501 - 430 + 335 + 379 + @@ -2120,17 +2106,11 @@ QSplitter:handle{ true - + 0 0 - - - 225 - 35 - - @@ -2597,22 +2577,6 @@ QSplitter:handle{ - - - - Qt::Horizontal - - - QSizePolicy::Maximum - - - - 500 - 20 - - - - @@ -2639,22 +2603,6 @@ QSplitter:handle{ - - - - Qt::Horizontal - - - QSizePolicy::Maximum - - - - 500 - 20 - - - - @@ -2687,22 +2635,6 @@ QSplitter:handle{ - - - - Qt::Horizontal - - - QSizePolicy::Maximum - - - - 500 - 20 - - - - @@ -2742,17 +2674,11 @@ QSplitter:handle{ - - 1 + + 0 0 - - - 375 - 0 - - @@ -3301,7 +3227,7 @@ QSplitter:handle{ 0 0 - 882 + 716 24 diff --git a/widget/adjustingscrollarea.cpp b/widget/adjustingscrollarea.cpp index 02e5b8746..f83db5024 100644 --- a/widget/adjustingscrollarea.cpp +++ b/widget/adjustingscrollarea.cpp @@ -18,18 +18,24 @@ #include #include +#include AdjustingScrollArea::AdjustingScrollArea(QWidget *parent) : QScrollArea(parent) { + } void AdjustingScrollArea::resizeEvent(QResizeEvent *ev) { - if (widget()) - { - widget()->setMinimumWidth(width()); - } - + updateGeometry(); QScrollArea::resizeEvent(ev); } + +QSize AdjustingScrollArea::sizeHint() const +{ + if (widget()) + return widget()->sizeHint(); + + return QScrollArea::sizeHint(); +} diff --git a/widget/adjustingscrollarea.h b/widget/adjustingscrollarea.h index de6a85ac3..a1645cbba 100644 --- a/widget/adjustingscrollarea.h +++ b/widget/adjustingscrollarea.h @@ -26,6 +26,7 @@ public: explicit AdjustingScrollArea(QWidget *parent = 0); virtual void resizeEvent(QResizeEvent *ev); + virtual QSize sizeHint() const override; signals: public slots: diff --git a/widget/friendwidget.cpp b/widget/friendwidget.cpp index a430288a0..782e541fd 100644 --- a/widget/friendwidget.cpp +++ b/widget/friendwidget.cpp @@ -25,6 +25,7 @@ FriendWidget::FriendWidget(int FriendId, QString id) : friendId(FriendId) { + setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); this->setMouseTracking(true); this->setAutoFillBackground(true); this->setFixedHeight(55); @@ -52,6 +53,9 @@ FriendWidget::FriendWidget(int FriendId, QString id) pal3.setColor(QPalette::Background, QColor(65,65,65,255)); this->setPalette(pal3); + name.setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + statusMessage.setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + textLayout.addStretch(); textLayout.addWidget(&name); textLayout.addWidget(&statusMessage); @@ -67,6 +71,13 @@ FriendWidget::FriendWidget(int FriendId, QString id) layout.addSpacing(5); isActiveWidget = 0; + + layout.invalidate(); + layout.update(); + layout.activate(); + updateGeometry(); + + qDebug() << "friend" << minimumSizeHint(); } void FriendWidget::mouseReleaseEvent (QMouseEvent*) diff --git a/widget/widget.cpp b/widget/widget.cpp index c7d6eda88..e9281a891 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -56,44 +56,54 @@ Widget::Widget(QWidget *parent) restoreGeometry(Settings::getInstance().getWindowGeometry()); restoreState(Settings::getInstance().getWindowState()); - ui->titleBar->hide(); - layout()->setContentsMargins(0, 0, 0, 0); - ui->friendList->setObjectName("friendList"); - ui->friendList->setStyleSheet(Style::get(":ui/friendList/friendList.css")); - - setStyleSheet(Style::get(":ui/window/window.css")); - //ui->statusPanel->setStyleSheet(QString("")); - //ui->friendList->setStyleSheet(QString("")); - - ui->friendList->setObjectName("friendList"); - ui->friendList->setStyleSheet(Style::get(":ui/friendList/friendList.css")); - - ui->tbMenu->setIcon(QIcon(":ui/window/applicationIcon.png")); - ui->pbMin->setObjectName("minimizeButton"); - ui->pbMax->setObjectName("maximizeButton"); - ui->pbClose->setObjectName("closeButton"); - - if (!Settings::getInstance().getUseNativeDecoration()) + if (Settings::getInstance().getUseNativeDecoration()) { + ui->titleBar->hide(); + this->layout()->setContentsMargins(0, 0, 0, 0); + + ui->friendList->setObjectName("friendList"); + ui->friendList->setStyleSheet(Style::get(":ui/friendList/friendList.css")); + } + else + { + this->setObjectName("activeWindow"); + this->setStyleSheet(Style::get(":ui/window/window.css")); + ui->statusPanel->setStyleSheet(QString("")); + ui->friendList->setStyleSheet(QString("")); + + ui->friendList->setObjectName("friendList"); + ui->friendList->setStyleSheet(Style::get(":ui/friendList/friendList.css")); + + ui->tbMenu->setIcon(QIcon(":ui/window/applicationIcon.png")); + ui->pbMin->setObjectName("minimizeButton"); + ui->pbMax->setObjectName("maximizeButton"); + ui->pbClose->setObjectName("closeButton"); + setWindowFlags(Qt::CustomizeWindowHint); setWindowFlags(Qt::FramelessWindowHint); + + addAction(ui->actionClose); + + connect(ui->pbMin, SIGNAL(clicked()), this, SLOT(minimizeBtnClicked())); + connect(ui->pbMax, SIGNAL(clicked()), this, SLOT(maximizeBtnClicked())); + connect(ui->pbClose, SIGNAL(clicked()), this, SLOT(close())); + + m_titleMode = FullTitle; + moveWidget = false; + inResizeZone = false; + allowToResize = false; + resizeVerSup = false; + resizeHorEsq = false; + resizeDiagSupEsq = false; + resizeDiagSupDer = false; + + if (isMaximized()) + { + showMaximized(); + ui->pbMax->setObjectName("restoreButton"); + } } - addAction(ui->actionClose); - - connect(ui->pbMin, SIGNAL(clicked()), this, SLOT(minimizeBtnClicked())); - connect(ui->pbMax, SIGNAL(clicked()), this, SLOT(maximizeBtnClicked())); - connect(ui->pbClose, SIGNAL(clicked()), this, SLOT(close())); - - m_titleMode = FullTitle; - moveWidget = false; - inResizeZone = false; - allowToResize = false; - resizeVerSup = false; - resizeHorEsq = false; - resizeDiagSupEsq = false; - resizeDiagSupDer = false; - isWindowMinimized = 0; ui->mainContent->setLayout(new QVBoxLayout()); @@ -102,9 +112,11 @@ Widget::Widget(QWidget *parent) ui->mainHead->layout()->setSpacing(0); QWidget* friendListWidget = new QWidget(); + //friendListWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding); friendListWidget->setLayout(new QVBoxLayout()); friendListWidget->layout()->setSpacing(0); friendListWidget->layout()->setMargin(0); + friendListWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); ui->friendList->setWidget(friendListWidget); // delay setting username and message until Core inits @@ -112,7 +124,6 @@ Widget::Widget(QWidget *parent) ui->nameLabel->label->setStyleSheet("QLabel { color : white; font-size: 11pt; font-weight:bold;}"); //ui->statusLabel->setText(core->getStatusMessage()); ui->statusLabel->label->setStyleSheet("QLabel { color : white; font-size: 8pt;}"); - ui->friendList->widget()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); ui->statusButton->setStyleSheet(Style::get(":/ui/statusButton/statusButton.css")); @@ -125,13 +136,6 @@ Widget::Widget(QWidget *parent) setStatusBusy->setIcon(QIcon(":ui/statusButton/dot_busy.png")); ui->statusButton->setMenu(statusButtonMenu); - -// this->setMouseTracking(true); - -// QList widgets = this->findChildren(); -// foreach (QWidget *widget, widgets) -// widget->setMouseTracking(true); - ui->titleBar->setMouseTracking(true); ui->LTitle->setMouseTracking(true); ui->tbMenu->setMouseTracking(true); @@ -140,11 +144,11 @@ Widget::Widget(QWidget *parent) ui->pbClose->setMouseTracking(true); ui->statusHead->setMouseTracking(true); - ui->friendList->viewport()->installEventFilter(this); + //ui->friendList->viewport()->installEventFilter(this); -// QList currentSizes = ui->centralWidget->sizes(); -// currentSizes[0] = 225; -// ui->centralWidget->setSizes(currentSizes); + // disable proportional scaling + ui->centralWidget->setStretchFactor(0,0); + ui->centralWidget->setStretchFactor(1,1); ui->statusButton->setObjectName("offline"); ui->statusButton->style()->polish(ui->statusButton); @@ -617,7 +621,7 @@ void Widget::onGroupMessageReceived(int groupnumber, int friendgroupnumber, cons newMessageAlert(); g->hasNewMessages = 1; g->userWasMentioned = 1; - if (useNativeTheme) + if (Settings::getInstance().getUseNativeDecoration()) g->widget->statusPic.setPixmap(QPixmap(":img/status/dot_online_notification.png")); else g->widget->statusPic.setPixmap(QPixmap(":img/status/dot_groupchat_notification.png")); @@ -626,7 +630,7 @@ void Widget::onGroupMessageReceived(int groupnumber, int friendgroupnumber, cons if (g->hasNewMessages == 0) { g->hasNewMessages = 1; - if (useNativeTheme) + if (Settings::getInstance().getUseNativeDecoration()) g->widget->statusPic.setPixmap(QPixmap(":img/status/dot_online_notification.png")); else g->widget->statusPic.setPixmap(QPixmap(":img/status/dot_groupchat_newmessages.png")); @@ -673,7 +677,7 @@ void Widget::onGroupWidgetClicked(GroupWidget* widget) { g->hasNewMessages = 0; g->userWasMentioned = 0; - if (useNativeTheme) + if (Settings::getInstance().getUseNativeDecoration()) g->widget->statusPic.setPixmap(QPixmap(":img/status/dot_online.png")); else g->widget->statusPic.setPixmap(QPixmap(":img/status/dot_groupchat.png")); @@ -712,7 +716,7 @@ Group *Widget::createGroup(int groupId) QWidget* widget = ui->friendList->widget(); QLayout* layout = widget->layout(); layout->addWidget(newgroup->widget); - if (!useNativeTheme) + if (!Settings::getInstance().getUseNativeDecoration()) newgroup->widget->statusPic.setPixmap(QPixmap(":img/status/dot_groupchat.png")); connect(newgroup->widget, SIGNAL(groupWidgetClicked(GroupWidget*)), this, SLOT(onGroupWidgetClicked(GroupWidget*))); @@ -758,7 +762,7 @@ bool Widget::event(QEvent * e) } else if (e->type() == QEvent::WindowActivate) { - if (!useNativeTheme) + if (!Settings::getInstance().getUseNativeDecoration()) { this->setObjectName("activeWindow"); this->style()->polish(this); @@ -775,18 +779,18 @@ bool Widget::event(QEvent * e) Group* g = GroupList::findGroup(activeGroupWidget->groupId); g->hasNewMessages = 0; g->userWasMentioned = 0; - if (useNativeTheme) + if (Settings::getInstance().getUseNativeDecoration()) g->widget->statusPic.setPixmap(QPixmap(":img/status/dot_online.png")); else g->widget->statusPic.setPixmap(QPixmap(":img/status/dot_groupchat.png")); } } - else if (e->type() == QEvent::WindowDeactivate && !useNativeTheme) + else if (e->type() == QEvent::WindowDeactivate && !Settings::getInstance().getUseNativeDecoration()) { this->setObjectName("inactiveWindow"); this->style()->polish(this); } - else if (e->type() == QEvent::MouseMove && !useNativeTheme) + else if (e->type() == QEvent::MouseMove && !Settings::getInstance().getUseNativeDecoration()) { QMouseEvent *k = (QMouseEvent *)e; int xMouse = k->pos().x(); @@ -831,7 +835,7 @@ bool Widget::event(QEvent * e) void Widget::mousePressEvent(QMouseEvent *e) { - if (!useNativeTheme) + if (!Settings::getInstance().getUseNativeDecoration()) { if (e->button() == Qt::LeftButton) { @@ -865,7 +869,7 @@ void Widget::mousePressEvent(QMouseEvent *e) void Widget::mouseReleaseEvent(QMouseEvent *e) { - if (!useNativeTheme) + if (!Settings::getInstance().getUseNativeDecoration()) { moveWidget = false; allowToResize = false; @@ -880,7 +884,7 @@ void Widget::mouseReleaseEvent(QMouseEvent *e) void Widget::mouseDoubleClickEvent(QMouseEvent *e) { - if (!useNativeTheme) + if (!Settings::getInstance().getUseNativeDecoration()) { if (e->pos().x() < ui->tbMenu->geometry().right() and e->pos().y() < ui->tbMenu->geometry().bottom() and e->pos().x() >= ui->tbMenu->geometry().x() and e->pos().y() >= ui->tbMenu->geometry().y() @@ -904,7 +908,7 @@ void Widget::paintEvent (QPaintEvent *) void Widget::moveWindow(QMouseEvent *e) { - if (!useNativeTheme) + if (!Settings::getInstance().getUseNativeDecoration()) { if (e->buttons() & Qt::LeftButton) { @@ -916,7 +920,7 @@ void Widget::moveWindow(QMouseEvent *e) void Widget::resizeWindow(QMouseEvent *e) { - if (!useNativeTheme) + if (!Settings::getInstance().getUseNativeDecoration()) { if (allowToResize) { diff --git a/widget/widget.h b/widget/widget.h index 0980cff69..a31e8e6f2 100644 --- a/widget/widget.h +++ b/widget/widget.h @@ -58,7 +58,6 @@ public: void newMessageAlert(); bool isFriendWidgetCurActiveWidget(Friend* f); void updateFriendStatusLights(int friendId); - int useNativeTheme; ~Widget(); virtual void closeEvent(QCloseEvent *event); From 6bb85c65b856d6412a05a7699983906f252206f3 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 11 Aug 2014 14:07:27 +0200 Subject: [PATCH 050/149] save/restore status of the splitter --- mainwindow.ui | 2 +- settings.cpp | 12 ++++++++++++ settings.h | 4 ++++ widget/widget.cpp | 6 ++++-- 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/mainwindow.ui b/mainwindow.ui index 3509b23d6..8622e3d68 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -225,7 +225,7 @@ - + 0 diff --git a/settings.cpp b/settings.cpp index 19e9e1f93..7d7571a14 100644 --- a/settings.cpp +++ b/settings.cpp @@ -106,6 +106,7 @@ void Settings::load() useNativeDecoration = s.value("nativeDecoration", true).toBool(); windowGeometry = s.value("windowGeometry", QByteArray()).toByteArray(); windowState = s.value("windowState", QByteArray()).toByteArray(); + splitterState = s.value("splitterState", QByteArray()).toByteArray(); s.endGroup(); s.beginGroup("Privacy"); @@ -166,6 +167,7 @@ void Settings::save(QString path) s.setValue("nativeDecoration", useNativeDecoration); s.setValue("windowGeometry", windowGeometry); s.setValue("windowState", windowState); + s.setValue("splitterState", splitterState); s.endGroup(); s.beginGroup("Privacy"); @@ -383,6 +385,16 @@ void Settings::setWindowState(const QByteArray &value) windowState = value; } +QByteArray Settings::getSplitterState() const +{ + return splitterState; +} + +void Settings::setSplitterState(const QByteArray &value) +{ + splitterState = value; +} + bool Settings::isMinimizeOnCloseEnabled() const { return minimizeOnClose; diff --git a/settings.h b/settings.h index a514350d5..c32203f41 100644 --- a/settings.h +++ b/settings.h @@ -124,6 +124,9 @@ public: QByteArray getWindowState() const; void setWindowState(const QByteArray &value); + QByteArray getSplitterState() const; + void setSplitterState(const QByteArray &value); + private: Settings(); Settings(Settings &settings) = delete; @@ -163,6 +166,7 @@ private: bool useNativeDecoration; QByteArray windowGeometry; QByteArray windowState; + QByteArray splitterState; // ChatView int firstColumnHandlePos; diff --git a/widget/widget.cpp b/widget/widget.cpp index e9281a891..6b4353368 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -55,6 +55,7 @@ Widget::Widget(QWidget *parent) //restore window state restoreGeometry(Settings::getInstance().getWindowGeometry()); restoreState(Settings::getInstance().getWindowState()); + ui->mainSplitter->restoreState(Settings::getInstance().getSplitterState()); if (Settings::getInstance().getUseNativeDecoration()) { @@ -147,8 +148,8 @@ Widget::Widget(QWidget *parent) //ui->friendList->viewport()->installEventFilter(this); // disable proportional scaling - ui->centralWidget->setStretchFactor(0,0); - ui->centralWidget->setStretchFactor(1,1); + ui->mainSplitter->setStretchFactor(0,0); + ui->mainSplitter->setStretchFactor(1,1); ui->statusButton->setObjectName("offline"); ui->statusButton->style()->polish(ui->statusButton); @@ -253,6 +254,7 @@ void Widget::closeEvent(QCloseEvent *event) { Settings::getInstance().setWindowGeometry(saveGeometry()); Settings::getInstance().setWindowState(saveState()); + Settings::getInstance().setSplitterState(ui->mainSplitter->saveState()); QWidget::closeEvent(event); } From 5304621e86d6455faf151d06f4de99d4786de78e Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 11 Aug 2014 14:13:13 +0200 Subject: [PATCH 051/149] fixed warnings --- core.cpp | 4 ++++ widget/camera.cpp | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/core.cpp b/core.cpp index 509a5fdfc..efefd6d10 100644 --- a/core.cpp +++ b/core.cpp @@ -1405,6 +1405,8 @@ void Core::cleanupCall(int callId) void Core::playCallAudio(ToxAv*, int32_t callId, int16_t *data, int length, void *user_data) { + Q_UNUSED(user_data); + if (!calls[callId].active || calls[callId].audioOutput == nullptr) return; calls[callId].audioBuffer.write((char*)data, length*2); @@ -1451,6 +1453,8 @@ void Core::sendCallAudio(int callId, ToxAv* toxav) void Core::playCallVideo(ToxAv*, int32_t callId, vpx_image_t* img, void *user_data) { + Q_UNUSED(user_data); + if (!calls[callId].active || !calls[callId].videoEnabled) return; diff --git a/widget/camera.cpp b/widget/camera.cpp index 7c8c5582c..7b5270bab 100644 --- a/widget/camera.cpp +++ b/widget/camera.cpp @@ -267,11 +267,11 @@ vpx_image Camera::getLastVPXImage() uint8_t* rgb = lastFrame.bits(); size_t i=0, j=0; - for( size_t line = 0; line < h; ++line ) + for( int line = 0; line < h; ++line ) { if( !(line % 2) ) { - for( size_t x = 0; x < w; x += 2 ) + for( int x = 0; x < w; x += 2 ) { uint8_t r = rgb[4 * i + 1]; uint8_t g = rgb[4 * i + 2]; @@ -293,7 +293,7 @@ vpx_image Camera::getLastVPXImage() } else { - for( size_t x = 0; x < w; x += 1 ) + for( int x = 0; x < w; x += 1 ) { uint8_t r = rgb[4 * i + 1]; uint8_t g = rgb[4 * i + 2]; From 0d748b93d603a1894ecf131503b1a517e0422bb9 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 11 Aug 2014 17:06:57 +0200 Subject: [PATCH 052/149] consider scrollbar's width --- widget/adjustingscrollarea.cpp | 6 +++++- widget/widget.cpp | 1 - 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/widget/adjustingscrollarea.cpp b/widget/adjustingscrollarea.cpp index f83db5024..bb273fa90 100644 --- a/widget/adjustingscrollarea.cpp +++ b/widget/adjustingscrollarea.cpp @@ -18,6 +18,7 @@ #include #include +#include #include AdjustingScrollArea::AdjustingScrollArea(QWidget *parent) : @@ -35,7 +36,10 @@ void AdjustingScrollArea::resizeEvent(QResizeEvent *ev) QSize AdjustingScrollArea::sizeHint() const { if (widget()) - return widget()->sizeHint(); + { + int scrollbarWidth = verticalScrollBar()->isVisible() ? verticalScrollBar()->width() : 0; + return widget()->sizeHint() + QSize(scrollbarWidth, 0); + } return QScrollArea::sizeHint(); } diff --git a/widget/widget.cpp b/widget/widget.cpp index 6b4353368..38c047259 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -113,7 +113,6 @@ Widget::Widget(QWidget *parent) ui->mainHead->layout()->setSpacing(0); QWidget* friendListWidget = new QWidget(); - //friendListWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding); friendListWidget->setLayout(new QVBoxLayout()); friendListWidget->layout()->setSpacing(0); friendListWidget->layout()->setMargin(0); From 1c27b55470d319f17b980be31c955dcb9d00a30c Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 11 Aug 2014 17:23:41 +0200 Subject: [PATCH 053/149] use Style::get --- widget/emoticonswidget.cpp | 7 ++----- widget/filetransfertwidget.cpp | 23 +++++---------------- widget/form/groupchatform.cpp | 37 +++++----------------------------- 3 files changed, 12 insertions(+), 55 deletions(-) diff --git a/widget/emoticonswidget.cpp b/widget/emoticonswidget.cpp index b2796c999..bab7abe8d 100644 --- a/widget/emoticonswidget.cpp +++ b/widget/emoticonswidget.cpp @@ -16,6 +16,7 @@ #include "emoticonswidget.h" #include "smileypack.h" +#include "style.h" #include #include @@ -26,11 +27,7 @@ EmoticonsWidget::EmoticonsWidget(QWidget *parent) : QMenu(parent) { - QFile f(":/ui/emoticonWidget/emoticonWidget.css"); - f.open(QFile::ReadOnly | QFile::Text); - QString pageButtonCss = f.readAll(); - setStyleSheet(pageButtonCss); - + setStyleSheet(Style::get(":/ui/emoticonWidget/emoticonWidget.css")); setLayout(&layout); layout.addWidget(&stack); diff --git a/widget/filetransfertwidget.cpp b/widget/filetransfertwidget.cpp index e90d8b2d0..36027257f 100644 --- a/widget/filetransfertwidget.cpp +++ b/widget/filetransfertwidget.cpp @@ -18,6 +18,7 @@ #include "widget.h" #include "core.h" #include "math.h" +#include "style.h" #include #include #include @@ -36,10 +37,7 @@ FileTransfertWidget::FileTransfertWidget(ToxFile File) QFont prettysmall; prettysmall.setPixelSize(10); this->setObjectName("default"); - QFile f0(":/ui/fileTransferWidget/fileTransferWidget.css"); - f0.open(QFile::ReadOnly | QFile::Text); - QTextStream fileTransfertWidgetStylesheet(&f0); - this->setStyleSheet(fileTransfertWidgetStylesheet.readAll()); + this->setStyleSheet(Style::get(":/ui/fileTransferWidget/fileTransferWidget.css")); QPalette greybg; greybg.setColor(QPalette::Window, QColor(209,209,209)); greybg.setColor(QPalette::Base, QColor(150,150,150)); @@ -71,20 +69,9 @@ FileTransfertWidget::FileTransfertWidget(ToxFile File) buttonWidget->setAutoFillBackground(true); buttonWidget->setLayout(buttonLayout); - QFile f1(":/ui/stopFileButton/style.css"); - f1.open(QFile::ReadOnly | QFile::Text); - QTextStream stopFileButtonStylesheetStream(&f1); - stopFileButtonStylesheet = stopFileButtonStylesheetStream.readAll(); - - QFile f2(":/ui/pauseFileButton/style.css"); - f2.open(QFile::ReadOnly | QFile::Text); - QTextStream pauseFileButtonStylesheetStream(&f2); - pauseFileButtonStylesheet = pauseFileButtonStylesheetStream.readAll(); - - QFile f3(":/ui/acceptFileButton/style.css"); - f3.open(QFile::ReadOnly | QFile::Text); - QTextStream acceptFileButtonStylesheetStream(&f3); - acceptFileButtonStylesheet = acceptFileButtonStylesheetStream.readAll(); + stopFileButtonStylesheet = Style::get(":/ui/stopFileButton/style.css"); + pauseFileButtonStylesheet = Style::get(":/ui/pauseFileButton/style.css"); + acceptFileButtonStylesheet = Style::get(":/ui/acceptFileButton/style.css"); topright->setStyleSheet(stopFileButtonStylesheet); if (File.direction == ToxFile::SENDING) diff --git a/widget/form/groupchatform.cpp b/widget/form/groupchatform.cpp index 919c457d7..e5e630ae1 100644 --- a/widget/form/groupchatform.cpp +++ b/widget/form/groupchatform.cpp @@ -20,6 +20,7 @@ #include "widget/widget.h" #include "friend.h" #include "friendlist.h" +#include "style.h" #include #include #include @@ -55,16 +56,8 @@ GroupChatForm::GroupChatForm(Group* chatGroup) namesList->setFont(small); chatAreaWidget->setLayout(mainChatLayout); - QString chatAreaStylesheet = ""; - try - { - QFile f(":/ui/chatArea/chatArea.css"); - f.open(QFile::ReadOnly | QFile::Text); - QTextStream chatAreaStylesheetStream(&f); - chatAreaStylesheet = chatAreaStylesheetStream.readAll(); - } - catch (int e) {} - chatArea->setStyleSheet(chatAreaStylesheet); + + chatArea->setStyleSheet(Style::get(":/ui/chatArea/chatArea.css")); chatArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); chatArea->setWidgetResizable(true); chatArea->setContextMenuPolicy(Qt::CustomContextMenu); @@ -73,35 +66,15 @@ GroupChatForm::GroupChatForm(Group* chatGroup) mainChatLayout->setColumnStretch(1,1); mainChatLayout->setSpacing(10); - - QString msgEditStylesheet = ""; - try - { - QFile f(":/ui/msgEdit/msgEdit.css"); - f.open(QFile::ReadOnly | QFile::Text); - QTextStream msgEditStylesheetStream(&f); - msgEditStylesheet = msgEditStylesheetStream.readAll(); - } - catch (int e) {} msgEdit->setObjectName("group"); - msgEdit->setStyleSheet(msgEditStylesheet); + msgEdit->setStyleSheet(Style::get(":/ui/msgEdit/msgEdit.css")); msgEdit->setFixedHeight(50); msgEdit->setFrameStyle(QFrame::NoFrame); mainChatLayout->setColumnStretch(1,1); mainChatLayout->setHorizontalSpacing(10); - QString sendButtonStylesheet = ""; - try - { - QFile f(":/ui/sendButton/sendButton.css"); - f.open(QFile::ReadOnly | QFile::Text); - QTextStream sendButtonStylesheetStream(&f); - sendButtonStylesheet = sendButtonStylesheetStream.readAll(); - } - catch (int e) {} - sendButton->setStyleSheet(sendButtonStylesheet); - + sendButton->setStyleSheet(Style::get(":/ui/sendButton/sendButton.css")); sendButton->setFixedSize(50, 50); main->setLayout(mainLayout); From 62bcb86c8b7dcca3a78d3ef1db0527d47adf0c93 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 11 Aug 2014 17:33:32 +0200 Subject: [PATCH 054/149] State group in settings --- settings.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/settings.cpp b/settings.cpp index 1dc3c8309..1662e44b0 100644 --- a/settings.cpp +++ b/settings.cpp @@ -104,6 +104,9 @@ void Settings::load() minimizeOnClose = s.value("minimizeOnClose", false).toBool(); useNativeStyle = s.value("nativeStyle", false).toBool(); useNativeDecoration = s.value("nativeDecoration", true).toBool(); + s.endGroup(); + + s.beginGroup("State"); windowGeometry = s.value("windowGeometry", QByteArray()).toByteArray(); windowState = s.value("windowState", QByteArray()).toByteArray(); splitterState = s.value("splitterState", QByteArray()).toByteArray(); @@ -169,6 +172,9 @@ void Settings::save(QString path) s.setValue("minimizeOnClose", minimizeOnClose); s.setValue("nativeStyle", useNativeStyle); s.setValue("nativeDecoration", useNativeDecoration); + s.endGroup(); + + s.beginGroup("State"); s.setValue("windowGeometry", windowGeometry); s.setValue("windowState", windowState); s.setValue("splitterState", splitterState); From e5f0ac7c916e9677ee26322646243e46bbac3462 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 11 Aug 2014 19:46:14 +0200 Subject: [PATCH 055/149] moved scrollbar to the left, cleanup --- widget/friendwidget.cpp | 10 +++++----- widget/groupwidget.cpp | 9 +++++---- widget/widget.cpp | 1 + 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/widget/friendwidget.cpp b/widget/friendwidget.cpp index 782e541fd..90edf8fc8 100644 --- a/widget/friendwidget.cpp +++ b/widget/friendwidget.cpp @@ -25,16 +25,16 @@ FriendWidget::FriendWidget(int FriendId, QString id) : friendId(FriendId) { - setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - this->setMouseTracking(true); - this->setAutoFillBackground(true); - this->setFixedHeight(55); - this->setLayout(&layout); + setMouseTracking(true); + setAutoFillBackground(true); + setFixedHeight(55); + setLayout(&layout); layout.setSpacing(0); layout.setMargin(0); layout.setStretchFactor(this, 100); textLayout.setSpacing(0); textLayout.setMargin(0); + setLayoutDirection(Qt::LeftToRight); // parent might have set Qt::RightToLeft avatar.setPixmap(QPixmap(":img/contact.png")); name.setText(id); diff --git a/widget/groupwidget.cpp b/widget/groupwidget.cpp index 7a138e28a..ac0608b1b 100644 --- a/widget/groupwidget.cpp +++ b/widget/groupwidget.cpp @@ -24,14 +24,15 @@ GroupWidget::GroupWidget(int GroupId, QString Name) : groupId{GroupId} { - this->setMouseTracking(true); - this->setAutoFillBackground(true); - this->setLayout(&layout); - this->setFixedHeight(55); + setMouseTracking(true); + setAutoFillBackground(true); + setLayout(&layout); + setFixedHeight(55); layout.setSpacing(0); layout.setMargin(0); textLayout.setSpacing(0); textLayout.setMargin(0); + setLayoutDirection(Qt::LeftToRight); // parent might have set Qt::RightToLeft avatar.setPixmap(QPixmap(":img/group.png")); statusPic.setPixmap(QPixmap(":img/status/dot_online.png")); diff --git a/widget/widget.cpp b/widget/widget.cpp index 38c047259..0b1a4ba51 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -118,6 +118,7 @@ Widget::Widget(QWidget *parent) friendListWidget->layout()->setMargin(0); friendListWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); ui->friendList->setWidget(friendListWidget); + ui->friendList->setLayoutDirection(Qt::RightToLeft); // delay setting username and message until Core inits //ui->nameLabel->setText(core->getUsername()); From 5f4c282215e8f50ad7ce445eb015a710e5b1cc9f Mon Sep 17 00:00:00 2001 From: apprb Date: Thu, 14 Aug 2014 18:55:04 +0700 Subject: [PATCH 056/149] Fix #102 (Greentext only lines with ">") --- widget/form/chatform.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index f5c1487a8..09651b5a2 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -185,8 +185,6 @@ void ChatForm::addMessage(QString author, QString message, QString date) void ChatForm::addMessage(QLabel* author, QLabel* message, QLabel* date) { - QPalette greentext; - greentext.setColor(QPalette::WindowText, QColor(61,204,61)); QScrollBar* scroll = chatArea->verticalScrollBar(); lockSliderToBottom = scroll && scroll->value() == scroll->maximum(); author->setAlignment(Qt::AlignTop | Qt::AlignRight); @@ -214,8 +212,23 @@ void ChatForm::addMessage(QLabel* author, QLabel* message, QLabel* date) } else if (curRow)// onSaveLogClicked expects 0 or 3 QLabel per line author->setText(""); - if (message->text()[0] == '>') - message->setPalette(greentext); + + QColor greentext(61,204,61); + QString fontTemplate = "%2"; + + QString finalMessage; + QStringList messageLines = message->text().split("\n"); + for (QString& s : messageLines) + { + if (QRegExp("^[ ]*>.*").exactMatch(s)) + finalMessage += fontTemplate.arg(greentext.name(), s.replace(" ", " ")); + else + finalMessage += s.replace(" ", " "); + finalMessage += "
"; + } + message->setText(finalMessage.left(finalMessage.length()-4)); + message->setTextFormat(Qt::RichText); + mainChatLayout->addWidget(author, curRow, 0); mainChatLayout->addWidget(message, curRow, 1); mainChatLayout->addWidget(date, curRow, 3); From 920c7e55043292fce18b7562a623ccce5d16cbc0 Mon Sep 17 00:00:00 2001 From: benwaffle Date: Fri, 15 Aug 2014 18:20:57 -0400 Subject: [PATCH 057/149] My server no longer exists --- res/settings.ini | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/res/settings.ini b/res/settings.ini index e1420de5b..94878406f 100644 --- a/res/settings.ini +++ b/res/settings.ini @@ -52,15 +52,11 @@ dhtServerList\13\name=anonymous dhtServerList\13\userId=5CD7EB176C19A2FD840406CD56177BB8E75587BB366F7BB3004B19E3EDC04143 dhtServerList\13\address=192.184.81.118 dhtServerList\13\port=33445 -dhtServerList\14\name=benwaffle -dhtServerList\14\userId=8E6667FF967EA30B3DC3DB57A4B533152476E7AAE090158B9C2D9DF58ECC7B78 -dhtServerList\14\address=192.3.30.132 +dhtServerList\14\name=zlacki RU #1 +dhtServerList\14\userId=D59F99384592DE4C8AB9D534D5197DB90F4755CC9E975ED0C565E18468A1445B +dhtServerList\14\address=31.192.105.19 dhtServerList\14\port=33445 -dhtServerList\15\name=zlacki RU #1 -dhtServerList\15\userId=D59F99384592DE4C8AB9D534D5197DB90F4755CC9E975ED0C565E18468A1445B -dhtServerList\15\address=31.192.105.19 +dhtServerList\15\name=zlacki US +dhtServerList\15\userId=9430A83211A7AD1C294711D069D587028CA0B4782FA43CB9B30008247A43C944 +dhtServerList\15\address=69.42.220.58 dhtServerList\15\port=33445 -dhtServerList\16\name=zlacki US -dhtServerList\16\userId=9430A83211A7AD1C294711D069D587028CA0B4782FA43CB9B30008247A43C944 -dhtServerList\16\address=69.42.220.58 -dhtServerList\16\port=33445 From 2cbbfb703729f9d4471eb5caf5586e9e665f0127 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Wed, 13 Aug 2014 22:54:03 +0200 Subject: [PATCH 058/149] this actually belongs here --- widget/form/chatform.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index 09651b5a2..f4882751b 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -179,12 +179,13 @@ void ChatForm::addFriendMessage(QString message) void ChatForm::addMessage(QString author, QString message, QString date) { - message = SmileyPack::getInstance().smileyfied(message); addMessage(new QLabel(author), new QLabel(message), new QLabel(date)); } void ChatForm::addMessage(QLabel* author, QLabel* message, QLabel* date) { + message->setText(SmileyPack::getInstance().smileyfied(message->text())); + QScrollBar* scroll = chatArea->verticalScrollBar(); lockSliderToBottom = scroll && scroll->value() == scroll->maximum(); author->setAlignment(Qt::AlignTop | Qt::AlignRight); From 1f92ad18a8677a28de4d6aebf50b2f88ba49f4d2 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Thu, 14 Aug 2014 09:47:30 +0200 Subject: [PATCH 059/149] CroppingLabel, fixes issue #184 --- qtox.pro | 6 +++-- widget/croppinglabel.cpp | 48 ++++++++++++++++++++++++++++++++++++++++ widget/croppinglabel.h | 41 ++++++++++++++++++++++++++++++++++ widget/friendwidget.cpp | 4 ---- widget/friendwidget.h | 5 ++++- 5 files changed, 97 insertions(+), 7 deletions(-) create mode 100644 widget/croppinglabel.cpp create mode 100644 widget/croppinglabel.h diff --git a/qtox.pro b/qtox.pro index 1ebaad38f..c975ceea5 100644 --- a/qtox.pro +++ b/qtox.pro @@ -88,7 +88,8 @@ HEADERS += widget/form/addfriendform.h \ smileypack.h \ widget/emoticonswidget.h \ style.h \ - widget/adjustingscrollarea.h + widget/adjustingscrollarea.h \ + widget/croppinglabel.h SOURCES += \ widget/form/addfriendform.cpp \ @@ -124,4 +125,5 @@ SOURCES += \ smileypack.cpp \ widget/emoticonswidget.cpp \ style.cpp \ - widget/adjustingscrollarea.cpp + widget/adjustingscrollarea.cpp \ + widget/croppinglabel.cpp diff --git a/widget/croppinglabel.cpp b/widget/croppinglabel.cpp new file mode 100644 index 000000000..ef0f54383 --- /dev/null +++ b/widget/croppinglabel.cpp @@ -0,0 +1,48 @@ +/* + Copyright (C) 2014 by Project Tox + + 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. +*/ + +#include "croppinglabel.h" + +CroppingLabel::CroppingLabel(QWidget *parent) + : QLabel(parent) +{ + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); +} + +void CroppingLabel::setText(const QString &text) +{ + origText = text; + setToolTip(text); + + QLabel::setText(fontMetrics().elidedText(text, Qt::ElideRight, width())); +} + +void CroppingLabel::resizeEvent(QResizeEvent *ev) +{ + setText(origText); + + QLabel::resizeEvent(ev); +} + +QSize CroppingLabel::sizeHint() const +{ + return QSize(0, QLabel::sizeHint().height()); +} + +QSize CroppingLabel::minimumSizeHint() const +{ + return QSize(fontMetrics().width("..."), QLabel::minimumSizeHint().height()); +} diff --git a/widget/croppinglabel.h b/widget/croppinglabel.h new file mode 100644 index 000000000..7ed99704a --- /dev/null +++ b/widget/croppinglabel.h @@ -0,0 +1,41 @@ +/* + Copyright (C) 2014 by Project Tox + + 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. +*/ + +#ifndef CROPPINGLABEL_H +#define CROPPINGLABEL_H + +#include + +class CroppingLabel : public QLabel +{ + Q_OBJECT +public: + explicit CroppingLabel(QWidget *parent = 0); + + virtual void setText(const QString& text); + virtual void resizeEvent(QResizeEvent *ev); + virtual QSize sizeHint() const; + virtual QSize minimumSizeHint() const; + +signals: + +public slots: + +private: + QString origText; +}; + +#endif // CROPPINGLABEL_H diff --git a/widget/friendwidget.cpp b/widget/friendwidget.cpp index 90edf8fc8..1be5817a4 100644 --- a/widget/friendwidget.cpp +++ b/widget/friendwidget.cpp @@ -54,7 +54,6 @@ FriendWidget::FriendWidget(int FriendId, QString id) this->setPalette(pal3); name.setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - statusMessage.setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); textLayout.addStretch(); textLayout.addWidget(&name); @@ -65,7 +64,6 @@ FriendWidget::FriendWidget(int FriendId, QString id) layout.addWidget(&avatar); layout.addSpacing(5); layout.addLayout(&textLayout); - layout.addStretch(); layout.addSpacing(5); layout.addWidget(&statusPic); layout.addSpacing(5); @@ -76,8 +74,6 @@ FriendWidget::FriendWidget(int FriendId, QString id) layout.update(); layout.activate(); updateGeometry(); - - qDebug() << "friend" << minimumSizeHint(); } void FriendWidget::mouseReleaseEvent (QMouseEvent*) diff --git a/widget/friendwidget.h b/widget/friendwidget.h index 6afcdc1aa..756578dce 100644 --- a/widget/friendwidget.h +++ b/widget/friendwidget.h @@ -22,6 +22,8 @@ #include #include +#include "croppinglabel.h" + struct FriendWidget : public QWidget { Q_OBJECT @@ -42,7 +44,8 @@ signals: public: int friendId; - QLabel avatar, name, statusMessage, statusPic; + QLabel avatar, name, statusPic; + CroppingLabel statusMessage; QHBoxLayout layout; QVBoxLayout textLayout; From eefa8d8ae61a35e94c9d18eafbea64dc6ff4ba8a Mon Sep 17 00:00:00 2001 From: krepa098 Date: Thu, 14 Aug 2014 11:42:03 +0200 Subject: [PATCH 060/149] only show tooltip if required --- widget/croppinglabel.cpp | 24 ++++++++++++++++-------- widget/croppinglabel.h | 5 ++--- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/widget/croppinglabel.cpp b/widget/croppinglabel.cpp index ef0f54383..656eb2b70 100644 --- a/widget/croppinglabel.cpp +++ b/widget/croppinglabel.cpp @@ -16,24 +16,21 @@ #include "croppinglabel.h" -CroppingLabel::CroppingLabel(QWidget *parent) +CroppingLabel::CroppingLabel(QWidget* parent) : QLabel(parent) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); } -void CroppingLabel::setText(const QString &text) +void CroppingLabel::setText(const QString& text) { origText = text; - setToolTip(text); - - QLabel::setText(fontMetrics().elidedText(text, Qt::ElideRight, width())); + setElidedText(); } -void CroppingLabel::resizeEvent(QResizeEvent *ev) +void CroppingLabel::resizeEvent(QResizeEvent* ev) { - setText(origText); - + setElidedText(); QLabel::resizeEvent(ev); } @@ -46,3 +43,14 @@ QSize CroppingLabel::minimumSizeHint() const { return QSize(fontMetrics().width("..."), QLabel::minimumSizeHint().height()); } + +void CroppingLabel::setElidedText() +{ + QString elidedText = fontMetrics().elidedText(origText, Qt::ElideRight, width()); + if (elidedText != origText) + setToolTip(origText); + else + setToolTip(QString()); + + QLabel::setText(elidedText); +} diff --git a/widget/croppinglabel.h b/widget/croppinglabel.h index 7ed99704a..decc5ad19 100644 --- a/widget/croppinglabel.h +++ b/widget/croppinglabel.h @@ -30,9 +30,8 @@ public: virtual QSize sizeHint() const; virtual QSize minimumSizeHint() const; -signals: - -public slots: +protected: + void setElidedText(); private: QString origText; From 18f0e05778a1eb599db3ca7a3bbb504f4f773bce Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 17 Aug 2014 14:57:54 +0200 Subject: [PATCH 061/149] Compat with Toxcore Fixes #190 --- core.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/core.cpp b/core.cpp index efefd6d10..499acb177 100644 --- a/core.cpp +++ b/core.cpp @@ -94,12 +94,21 @@ void Core::start() qDebug() << "Core starting with IPv6 enabled"; else qWarning() << "Core starting with IPv6 disabled. LAN discovery may not work properly."; - tox = tox_new(enableIPv6); + + Tox_Options toxOptions; + toxOptions.ipv6enabled = enableIPv6; + toxOptions.udp_disabled = 0; + toxOptions.proxy_enabled = false; + toxOptions.proxy_address[0] = 0; + toxOptions.proxy_port = 0; + + tox = tox_new(&toxOptions); if (tox == nullptr) { if (enableIPv6) // Fallback to IPv4 { - tox = tox_new(false); + toxOptions.ipv6enabled = false; + tox = tox_new(&toxOptions); if (tox == nullptr) { qCritical() << "Tox core failed to start"; @@ -711,7 +720,7 @@ void Core::bootstrapDht() { const Settings::DhtServer& dhtServer = dhtServerList[j % listSize]; if (tox_bootstrap_from_address(tox, dhtServer.address.toLatin1().data(), - 0, qToBigEndian(dhtServer.port), CUserId(dhtServer.userId).data()) == 1) + qToBigEndian(dhtServer.port), CUserId(dhtServer.userId).data()) == 1) qDebug() << QString("Core: Bootstraping from ")+dhtServer.name+QString(", addr ")+dhtServer.address.toLatin1().data() +QString(", port ")+QString().setNum(dhtServer.port); else From 7e67078187c454bfb0c51f0ec28a78b208c42137 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 18 Aug 2014 10:58:51 +0200 Subject: [PATCH 062/149] fix issue #184 --- widget/friendwidget.cpp | 2 -- widget/friendwidget.h | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/widget/friendwidget.cpp b/widget/friendwidget.cpp index 1be5817a4..84866e755 100644 --- a/widget/friendwidget.cpp +++ b/widget/friendwidget.cpp @@ -53,8 +53,6 @@ FriendWidget::FriendWidget(int FriendId, QString id) pal3.setColor(QPalette::Background, QColor(65,65,65,255)); this->setPalette(pal3); - name.setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - textLayout.addStretch(); textLayout.addWidget(&name); textLayout.addWidget(&statusMessage); diff --git a/widget/friendwidget.h b/widget/friendwidget.h index 756578dce..3fa37649a 100644 --- a/widget/friendwidget.h +++ b/widget/friendwidget.h @@ -44,8 +44,8 @@ signals: public: int friendId; - QLabel avatar, name, statusPic; - CroppingLabel statusMessage; + QLabel avatar, statusPic; + CroppingLabel name, statusMessage; QHBoxLayout layout; QVBoxLayout textLayout; From 01c31247225947aef308a79d1154c730776d7c3f Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 18 Aug 2014 15:56:48 +0200 Subject: [PATCH 063/149] use trimmed() --- widget/croppinglabel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget/croppinglabel.cpp b/widget/croppinglabel.cpp index 656eb2b70..f69e81c4c 100644 --- a/widget/croppinglabel.cpp +++ b/widget/croppinglabel.cpp @@ -24,7 +24,7 @@ CroppingLabel::CroppingLabel(QWidget* parent) void CroppingLabel::setText(const QString& text) { - origText = text; + origText = text.trimmed(); setElidedText(); } From 75f15dd349704c2b4148f97a294cc21789549ae1 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 18 Aug 2014 17:35:43 +0200 Subject: [PATCH 064/149] fixed null dereference --- widget/widget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget/widget.cpp b/widget/widget.cpp index 0b1a4ba51..650d2499d 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -616,7 +616,7 @@ void Widget::onGroupMessageReceived(int groupnumber, int friendgroupnumber, cons g->chatForm->addGroupMessage(message, friendgroupnumber); - if ((isGroupWidgetActive != 1 || (g->groupId != activeGroupWidget->groupId)) || isWindowMinimized || !isActiveWindow()) + if ((isGroupWidgetActive != 1 || (activeGroupWidget && g->groupId != activeGroupWidget->groupId)) || isWindowMinimized || !isActiveWindow()) { if (message.contains(core->getUsername(), Qt::CaseInsensitive)) { From d5cb1182cf48a2f4e6e008661a0980a9e12a7ec3 Mon Sep 17 00:00:00 2001 From: Ansa89 Date: Tue, 19 Aug 2014 16:47:26 +0200 Subject: [PATCH 065/149] Italian translation: update --- translations/it.qm | Bin 6298 -> 6228 bytes translations/it.ts | 130 +++++++++++++++++++++++++++++---------------- 2 files changed, 84 insertions(+), 46 deletions(-) diff --git a/translations/it.qm b/translations/it.qm index 4c8c5f1eac59191ad08d918872f408b5455c907f..6577e1330a01501ebeca838e932bd1e1aea44a6b 100644 GIT binary patch delta 512 zcmbPbc*S6XNZ<_ymSvR;4D2ZktRAKe48jK(*t0Vj7=&aP)D9{$Fo=mVnEYd5VBl(E za4en7z`!z%!OLta1A{;&!|cCTfb>j;`SGkkeQ8YmS;-6xf)W!`?YIPb({EBO-Zzzol#;60|V~~ zb}rTF3=C|iAT(bE`>E&6K$CAwHf40H7o5ja9R3*SAYq>O>brrOIe1ex6fiLGT;VO* zG7+eak@tksWd;WReL(s%0}$|@njH$XbSa;Vz7o)(Z~0_qqyRAYrF)(mw@&y$D zJtn}#7u3BT=s{M#U>Tr(&MABw(zXB{>7EG;g=l7=K}rmc44avlcJWU(7qj8!@=eUl z3(w3;$uFN=B^H9hzbdAR!ewmVMu-jJCK2-bn|w>V@#W$i1;(IcK~IW7#RUYfr7aJ delta 541 zcmca&Fw1a)NZYR4rS#IjyG5-6HK zajl$^@H|%g3>5|jMjqB4?j;Ni+?lNX{hdHrF4k4uhkM=ri^a&VyZmF;g5k166SfYzMFwT=oxRyh5`l#o-4d1 zTP6avG4h^Jx(sxnC6NBi00g|JW`_bTUCJk;uLSg13ZKl36riXYpYi-S1_lmIzMul2 z$3zNA0Em^pcapu}b_rd9l#ZAA_; zshThZGbA&lGNd!)Fk~_)FcdH(0{O`d89=cTAj}7frA}rPmlPHXPR&V8E>S4X&CE%y zR47PH&YrwLRBZDeiQ9`P4c9)PdoP9$`O&hA7ks0Vk yHii(ORTUf{@3H|gb4Y##JBST6lT)~w7g@c) ChatForm - + Send a file Invia un file - - + + Save chat log Salva il log della chat @@ -113,19 +113,19 @@ FileTransfertWidget - + Save a file Title of the file saving dialog Salva file - + Location not writable Title of permissions popup Errore - + You do not have permission to write that location. Choose another, or cancel the save dialog. text of permissions popup Non hai sufficienti permessi per scrivere in questa locazione. Scegli un'altra posizione, o annulla il salvataggio. @@ -189,19 +189,19 @@ FriendWidget - + Copy friend ID Menu to copy the Tox ID of that friend Copia Tox ID del contatto - + Invite in group Menu to invite a friend in a groupchat Invita nel gruppo - + Remove friend Menu to remove the friend from our friendlist Rimuovi contatto @@ -210,23 +210,23 @@ GroupChatForm - + %1 users in chat Number of users in chat %1 utenti in chat - + <Unknown> <Sconosciuto> - + %1 users in chat %1 utenti in chat - + Save chat log Salva il log della chat @@ -235,23 +235,71 @@ GroupWidget - + %1 users in chat %1 utenti in chat - + 0 users in chat 0 utenti in chat - + Quit group Menu to quit a groupchat Esci dal gruppo + + MainWindow + + + qTox + qTox + + + + Your name + qTox User + + + + Your status + Toxin on qTox + + + + Add friends + Aggiungi contatto + + + + Create a group chat + Crea un gruppo + + + + View completed file transfers + Visualizza i trasferimenti completati + + + + Change your settings + Cambia le impostazioni + + + + Close + Chiudi + + + + Ctrl+Q + Ctrl+Q + + SelfCamView @@ -264,121 +312,111 @@ SettingsForm - + User Settings "Headline" of the window Impostazioni - + Name Username/nick Nome - + Status Status message Stato - + (click here to copy) Click on this text to copy TID to clipboard (clicca qui per copiare) - + Test video Text on a button to test the video/webcam Prova la webcam - + Enable IPv6 (recommended) Text on a checkbox to enable IPv6 Abilita IPv6 (consigliato) - + Use translations Text on a checkbox to enable translations Abilita traduzioni - + Make Tox portable Text on a checkbox to make qTox a portable application Rendi qTox portabile - + Save settings to the working directory instead of the usual conf dir describes makeToxPortable checkbox Slava le impostazioni nella directory di lavoro corrente, invece della directory di default - + Smiley Pack Text on smiley pack label Emoticons - Select smiley pack - Scegli pacchetto emoticons + Scegli pacchetto emoticons Widget - Tox - Tox + Tox - Your name - Tox User + Tox User - Your status - Toxin on qTox + Toxin on qTox - Add friends - Aggiungi contatto + Aggiungi contatto - Create a group chat - Crea un gruppo + Crea un gruppo - View completed file transfers - Visualizza i trasferimenti completati + Visualizza i trasferimenti completati (button inactive currently) (bottone attualmente inattivo) - Change your settings - Cambia le impostazioni + Cambia le impostazioni - Close - Chiudi + Chiudi - Ctrl+Q - Ctrl+Q + Ctrl+Q Online From a75666a072834cab56d94951b310c17eaa0af1d0 Mon Sep 17 00:00:00 2001 From: midnight079 Date: Wed, 13 Aug 2014 18:02:05 +0400 Subject: [PATCH 066/149] Added buttons for microphone and volume control --- res.qrc | 7 +++++++ ui/micButton/micButton.png | Bin 0 -> 456 bytes ui/micButton/micButtonDisabled.png | Bin 0 -> 513 bytes ui/micButton/micButtonHover.png | Bin 0 -> 492 bytes ui/micButton/micButtonPressed.png | Bin 0 -> 640 bytes ui/volButton/volButton.png | Bin 0 -> 469 bytes ui/volButton/volButtonHover.png | Bin 0 -> 497 bytes ui/volButton/volButtonPressed.png | Bin 0 -> 526 bytes 8 files changed, 7 insertions(+) create mode 100644 ui/micButton/micButton.png create mode 100644 ui/micButton/micButtonDisabled.png create mode 100644 ui/micButton/micButtonHover.png create mode 100644 ui/micButton/micButtonPressed.png create mode 100644 ui/volButton/volButton.png create mode 100644 ui/volButton/volButtonHover.png create mode 100644 ui/volButton/volButtonPressed.png diff --git a/res.qrc b/res.qrc index 3afbcf5a4..e47bab30e 100644 --- a/res.qrc +++ b/res.qrc @@ -115,5 +115,12 @@ ui/emoticonWidget/dot_page_current.png ui/emoticonWidget/emoticonWidget.css ui/emoticonWidget/dot_page_hover.png + ui/volButton/volButton.png + ui/volButton/volButtonHover.png + ui/volButton/volButtonPressed.png + ui/micButton/micButton.png + ui/micButton/micButtonDisabled.png + ui/micButton/micButtonHover.png + ui/micButton/micButtonPressed.png diff --git a/ui/micButton/micButton.png b/ui/micButton/micButton.png new file mode 100644 index 0000000000000000000000000000000000000000..cc5d7109c04223373d0348a727bff78ce71fd51b GIT binary patch literal 456 zcmV;(0XP1MP)P000yS1^@s6cz2e)00006VoOIv0C@n% z0B=NW#mxW!00(qQO+^RZ2n`J~EryNXv;Y7BYDq*vR5;7cl|3(mQ5462=iVl*h=B$R zG57+eMhw1yNldot+JTS4ATf{_ET&p&V32e%FxZ4eBwiAstq5A4=N^L=eSeCI|8#TD zz4v$j=iCEs6NC_}c=d@%>4mznsC`gK80~1V*Ow$|g`{+}Y zjng#_ZuVPE?=eBPQVjqQgsG9~Kvn`lssUy7g`*Wvr~daLL8K@korRR$bR6=dn*1w> z$T!lZstxn3D1L*}RIO06pcPwpaaBe6+`!j%TTToXBNj!;6|*I04nZ(tuwuD?$+rYF zhZwgCY zvIBX)aP0ufkcVb3aWvA;%;+pb-NQApll(DTXPXrKLNmsLjm?b>0^^NF6#Qq7ZV$;7 yvqVB&SYx?P000yS1^@s6cz2e)00006VoOIv0C@n% z0B=NW#mxW!00(qQO+^RZ2n`K272(eD?EnA)qe(hJk{cj#CAYMkfQkajh=2eo63t4HXrMy;$_|hX-k~9oUuP5GmG*dM_M5k3 zilS(%3}Y6NVdP%t z+3C!cpNe;TOon~@lh`nVm&K}U6I?2luu<7SKA-7 z3jhESp;E4l7|8Jatcna4=qe0DD{NM{M5ONo)5@yIEQzPa^=p^e;_5{<3S%~|9?RL{ z>L$0rC?s|>8P|E5rjzF>1ct?48cZ%CFveIL!fGZ-lJw1mh``KfwOW5yq<&gQ9LL|C z6A_3A^|O;9{*&(s3FM1ouar_yNJuCH@7#a)oRdMXW0u*d3SByYx}EgoRKkFYc!ipByj>S=Yg5=@c4j>%L_CbjZ7O0 z3AF!yO;HpD&rA1*;bUQwB-@kI{EmeLZ$Wak5Qp2Ju?e!`gt;#o00000NkvXXu0mjf DpFHGN literal 0 HcmV?d00001 diff --git a/ui/micButton/micButtonHover.png b/ui/micButton/micButtonHover.png new file mode 100644 index 0000000000000000000000000000000000000000..92ad9fbaca04fec1485bd13b0f9c51f3d13a58b1 GIT binary patch literal 492 zcmVP000yS1^@s6cz2e)00006VoOIv0C@n% z0B=NW#mxW!00(qQO+^RZ2n`K3GH>Y@MF0Q+j!8s8R5;7+l|4%XK@f)DnZ4Y_q%anO zpn`>9tDyMii%D3q?T`5kU({5g`b6iXeyqqa;yCa(B61i+p&we4UDr z!go2Ao!i}Kc9@-|WGbPTtEFv27;yqK07ytsy}6~JT5R62Teh;RwzPM{T6jyVIOTnv z^;H5lCo}*GsyTM|?s?r5pn%5A8w*p-30|k08I*KVo++u!fgX7MIWGxXNC@QBGHYgoG`vBTA+cA=9ZG>TE2w)p$?p0;>6L i`bc$UN$WHyg7Hsu2#LCVErV+S0000CFNF literal 0 HcmV?d00001 diff --git a/ui/micButton/micButtonPressed.png b/ui/micButton/micButtonPressed.png new file mode 100644 index 0000000000000000000000000000000000000000..f5288da5609bd1985cf07ce9c6f7536530842288 GIT binary patch literal 640 zcmV-`0)PF9P)P000yS1^@s6cz2e)00006VoOIv0C@n% z0B=NW#mxW!00(qQO+^RZ2n`K5I1#_o)c^njB1uF+R5;6(RXuOhP!v7q*^bmNsVJz) z0!SqbAW%03S4F_m0SOjsAO%suQbq@>gzu@mml%l!)@(G!W1b5 z)x&ZwnJA{cD8Ti?#T6RVq>I(vU95Mza9gc~wbmH!?cw6+2$WeMD+79#aVbS9>Ouej zPzvkaE`&({v1bVYZVfhy0n+_;yVP-Y5L&pE%!0HEqB4jWm$f3C*nr1!SHe66G|q%+ zCP@JZ07naW8JLD(OztUwYZlRbZllZ0Nb-P8`O>6oUd}d17U%z?G5031L#PZzmBpA9 zfCwat>Z!}g^q)%SDQc1VN2O|IqF4h-6a)+BB%l=FIEaSBdO=F1l9`WsJw$`SA{!DQ zG3xc|sqb{#7h1$cvxfn-__u*}g~dY3%2EWEuA9QckD8voauzBGpb03+w{2%*1I-sN z(dcvv#(zG4!rA^lFqxDFh#kUt{Orz7Gnj6AkyzWkjK>(ieS>HaK&`HTu8Z({AESc< zoF5(nVQBwF00=$eM`!t%ec!(pv>Wf5zo$2-EiHn1W6fDznTXPdO_>N?%IWQu54XNt aJoyI;|JPV`81z;E0000P000yS1^@s6cz2e)00006VoOIv0BZok z0AR>C-ctsTU1vTWUzIF=DHAG<)bIqi*0meA;WE>L_4Ox$L$SaKniL- zP6sXbts(_BzUo)n>%)0-Ew!x$wIw0JnkFoYd+t`07WpDK%#(;>pf#_dD zQtvO-canC1c#6|4Rt}fYXbdKAP1~CO&>&-xiSLTK$s}Dsl#u>N{Q%@*=X#r`w?}5W z=MaR8m-D};E3313lowS%VvIpVIJ!Gv|8|e(>=VgM!i5u2yxUo{tx=+K%?d&Cs_5+g zghcwXsN)P000yS1^@s6cz2e)00006VoOIv0RI60 z0RN!9r;`8x00(qQO+^RZ2n`J>F1E5olmGw$lSxEDR5;7EmAgs=F%*XXb7ppS@PZb@d zzrbFy20a*~G$EzpJ6U{JDiKv_7~2;?g=C&qh~6&$qGmx=uAni`fc|wW@Yz zYNnc8zVxe>FBbA(Is6XEh!I4t zOS&)IsX>G+mdzbL?js{CEDfxHK)B9dM3XD{XqDo`O5xyP4;f+M*?Ee#69Pd75=52V zIh8)fP5vshC|&phhE{5BOw~EgqkWI_>}lD2LFB=foj!9sTiNh)ZY~t?{Q7ds* literal 0 HcmV?d00001 diff --git a/ui/volButton/volButtonPressed.png b/ui/volButton/volButtonPressed.png new file mode 100644 index 0000000000000000000000000000000000000000..fe7c192a3df48bb96670ce08dda591d42aed28c9 GIT binary patch literal 526 zcmV+p0`dKcP)P000yS1^@s6cz2e)00006VoOIv0RI60 z0RN!9r;`8x00(qQO+^RZ2n`J=1auO;0{{R4ut`KgR5;76l(9=3K@`Tn_h$Caji)FI zNyMZ%^uQukDeNLz3L%jsT116_g<>K0`cH^|K)}i_U7Bb>6tS|fxtJ&%D1sp_7r9Gz zcV3!!DDKEQ>ziVj`DWga`QGs8)u-VF0xb!o1rEW)Fk%ul#rh;R(F-P`MOOd-D*ynD zi60m8Ez2w-t;i60)nwHKf_hjRVq}czXLER2d}Gxk6LBU8flzAi!@JT1n!RRw-LgPN zd&cqTK^JnI!}Es&_YWB>O<=4v*;p6bdaY;mZHZO}KZ2P6(6#+~Ttj!^>9xJC!V@=0 zhu;asD%Hz;?Yr3(n>e+79(!&Ofk_P!fg8l!0a6VEM~I|{1b+gz!q0x00*G$bDh@GH ze2urg??L~6UZr|uhY$#YWJ7<4RqMsI@+!`1XPD`q2Z6BvbI)#<4Ui_*E1$7-{1w69 za~%9CgFv8!mun(|h&yQabQ?c{0~i<(l5=TA%0v=5x0mndWo%w-G+KM2U7Gb?mL_>} zaeS+;m3PSXsQ$rIxo=D?iZz&26i26xT+~qH)_Ge;(Pv16o-TV0RJn8&D^y= Qr~m)}07*qoM6N<$f(~}&vH$=8 literal 0 HcmV?d00001 From fdfbd9b162c5c448ce7242c31813fc0a80d2ec5a Mon Sep 17 00:00:00 2001 From: midnight079 Date: Wed, 13 Aug 2014 19:03:32 +0400 Subject: [PATCH 067/149] added stylesheets for micButton and volButton --- ui/micButton/micButton.css | 34 ++++++++++++++++++++++++++++++++++ ui/volButton/volButton.css | 20 ++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 ui/micButton/micButton.css create mode 100644 ui/volButton/volButton.css diff --git a/ui/micButton/micButton.css b/ui/micButton/micButton.css new file mode 100644 index 000000000..a0c8bb74a --- /dev/null +++ b/ui/micButton/micButton.css @@ -0,0 +1,34 @@ +QPushButton#green +{ + background-color: transparent; + background-image: url(":/micButton/micButton.css"); + background-repeat: none; + border: none; + width: 25px; + height: 20px; +} + +QPushButton#green:hover +{ + background-image:url(":/ui/micButton/micButtonHover.png"); +} + +QPushButton#red +{ + background-color: transparent; + background-image: url(":/ui/micButton/micButtonPressed.png"); + background-repeat: none; + border: none; + width: 25px; + height: 20px; +} + +QPushButton#grey +{ + background-color: transparent; + background-image: url(":/ui/callButton/callButtonDisabled.png"); + background-repeat: none; + border: none; + width: 25px; + height: 20px; +} \ No newline at end of file diff --git a/ui/volButton/volButton.css b/ui/volButton/volButton.css new file mode 100644 index 000000000..fbcf5b181 --- /dev/null +++ b/ui/volButton/volButton.css @@ -0,0 +1,20 @@ +QPushButton#green +{ + background-color: transparent; + background-image: url(":/ui/volButton/volButton.png"); + background-repeat: none; + border: none; + width: 25px; + height: 20px; +} + +QPushButton#green:hover +{ + background-image: url(":/ui/volButton/volButtonHover.png"); +} + +QPushButton#green:pressed +{ + background-image: url(":/ui/volButton/volButtonPressed.png"); +} + From ca9a9b79cbff1dc67fa20964fe47376ea03c1f93 Mon Sep 17 00:00:00 2001 From: midnight079 Date: Sat, 16 Aug 2014 00:08:19 +0400 Subject: [PATCH 068/149] micButton and volButton were added to chatForm, but micButton for some reason is blinking --- res.qrc | 2 ++ ui/micButton/micButton.css | 8 ++++++-- ui/volButton/volButton.css | 3 +++ widget/form/chatform.cpp | 35 +++++++++++++++++++++++++++++++++-- widget/form/chatform.h | 4 ++-- 5 files changed, 46 insertions(+), 6 deletions(-) diff --git a/res.qrc b/res.qrc index e47bab30e..f413e0209 100644 --- a/res.qrc +++ b/res.qrc @@ -122,5 +122,7 @@ ui/micButton/micButtonDisabled.png ui/micButton/micButtonHover.png ui/micButton/micButtonPressed.png + ui/micButton/micButton.css + ui/volButton/volButton.css diff --git a/ui/micButton/micButton.css b/ui/micButton/micButton.css index a0c8bb74a..bf16f8d37 100644 --- a/ui/micButton/micButton.css +++ b/ui/micButton/micButton.css @@ -26,9 +26,13 @@ QPushButton#red QPushButton#grey { background-color: transparent; - background-image: url(":/ui/callButton/callButtonDisabled.png"); + background-image: url(":/ui/micButton/micButtonDisabled.png"); background-repeat: none; border: none; width: 25px; height: 20px; -} \ No newline at end of file +} + +QPushButton:focus { + outline: none; +} diff --git a/ui/volButton/volButton.css b/ui/volButton/volButton.css index fbcf5b181..066d9ae66 100644 --- a/ui/volButton/volButton.css +++ b/ui/volButton/volButton.css @@ -18,3 +18,6 @@ QPushButton#green:pressed background-image: url(":/ui/volButton/volButtonPressed.png"); } +QPushButton:focus { + outline: none; +} diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index f4882751b..66b8afdc2 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -36,10 +36,13 @@ ChatForm::ChatForm(Friend* chatFriend) main = new QWidget(), head = new QWidget(), chatAreaWidget = new QWidget(); name = new QLabel(), avatar = new QLabel(), statusMessage = new QLabel(); headLayout = new QHBoxLayout(), mainFootLayout = new QHBoxLayout(); - headTextLayout = new QVBoxLayout(), mainLayout = new QVBoxLayout(), footButtonsSmall = new QVBoxLayout(); + headTextLayout = new QVBoxLayout(), mainLayout = new QVBoxLayout(), + footButtonsSmall = new QVBoxLayout(), volMicLayout = new QVBoxLayout(); mainChatLayout = new QGridLayout(); msgEdit = new ChatTextEdit(); - sendButton = new QPushButton(), fileButton = new QPushButton(), emoteButton = new QPushButton(), callButton = new QPushButton(), videoButton = new QPushButton(); + sendButton = new QPushButton(), fileButton = new QPushButton(), emoteButton = new QPushButton(), + callButton = new QPushButton(), videoButton = new QPushButton(), + volButton = new QPushButton(), micButton = new QPushButton(); chatArea = new QScrollArea(); netcam = new NetCamView(); @@ -80,6 +83,30 @@ ChatForm::ChatForm(Friend* chatFriend) videoButton->setObjectName("green"); videoButton->setStyleSheet(Style::get(":/ui/videoButton/videoButton.css")); + QString volButtonStylesheet = ""; + try + { + QFile f(":/ui/volButton/volButton.css"); + f.open(QFile::ReadOnly | QFile::Text); + QTextStream volButtonStylesheetStream(&f); + volButtonStylesheet = volButtonStylesheetStream.readAll(); + } + catch (int e) {} + volButton->setObjectName("green"); + volButton->setStyleSheet(volButtonStylesheet); + + QString micButtonStylesheet = ""; + try + { + QFile f(":/ui/micButton/micButton.css"); + f.open(QFile::ReadOnly | QFile::Text); + QTextStream micButtonStylesheetStream(&f); + micButtonStylesheet = micButtonStylesheetStream.readAll(); + } + catch (int e) {} + micButton->setObjectName("green"); + micButton->setStyleSheet(micButtonStylesheet); + main->setLayout(mainLayout); mainLayout->addWidget(chatArea); mainLayout->addLayout(mainFootLayout); @@ -98,9 +125,13 @@ ChatForm::ChatForm(Friend* chatFriend) headLayout->addWidget(avatar); headLayout->addLayout(headTextLayout); headLayout->addStretch(); + headLayout->addLayout(volMicLayout); headLayout->addWidget(callButton); headLayout->addWidget(videoButton); + volMicLayout->addWidget(micButton); + volMicLayout->addWidget(volButton); + headTextLayout->addStretch(); headTextLayout->addWidget(name); headTextLayout->addWidget(statusMessage); diff --git a/widget/form/chatform.h b/widget/form/chatform.h index 3354629d6..55b80eb42 100644 --- a/widget/form/chatform.h +++ b/widget/form/chatform.h @@ -89,11 +89,11 @@ private slots: private: Friend* f; QHBoxLayout *headLayout, *mainFootLayout; - QVBoxLayout *headTextLayout, *mainLayout, *footButtonsSmall; + QVBoxLayout *headTextLayout, *mainLayout, *footButtonsSmall, *volMicLayout; QGridLayout *mainChatLayout; QLabel *avatar, *name, *statusMessage; ChatTextEdit *msgEdit; - QPushButton *sendButton, *fileButton, *emoteButton, *callButton, *videoButton; + QPushButton *sendButton, *fileButton, *emoteButton, *callButton, *videoButton, *volButton, *micButton; QScrollArea *chatArea; QWidget *main, *head, *chatAreaWidget; QString previousName; From b474ff2c2bb5ff539af4a9429d2e652af56f2a90 Mon Sep 17 00:00:00 2001 From: midnight079 Date: Tue, 19 Aug 2014 19:20:20 +0400 Subject: [PATCH 069/149] realized micButton for calls --- core.cpp | 11 +- core.cpp.autosave | 1519 ++++++++++++++++++++++++++++++++++++ core.h | 2 + ui/micButton/micButton.css | 2 +- widget/form/chatform.cpp | 30 +- widget/form/chatform.h | 4 +- widget/widget.cpp | 1 + 7 files changed, 1563 insertions(+), 6 deletions(-) create mode 100644 core.cpp.autosave diff --git a/core.cpp b/core.cpp index 499acb177..e98a809e5 100644 --- a/core.cpp +++ b/core.cpp @@ -30,6 +30,7 @@ #include #include #include +#include const QString Core::CONFIG_FILE_NAME = "data"; QList Core::fileSendQueue; @@ -1519,5 +1520,13 @@ void Core::increaseVideoBusyness() void Core::decreaseVideoBusyness() { - videoBusyness--; + videoBusyness--; +} + +void Core::micMuteToggle(int callId) +{ +// if (calls[callId].audioInput->state() == QAudio::ActiveState) +// calls[callId].audioInput->stop(); +// else +// calls[callId].audioInput->start(); } diff --git a/core.cpp.autosave b/core.cpp.autosave new file mode 100644 index 000000000..ed4de6843 --- /dev/null +++ b/core.cpp.autosave @@ -0,0 +1,1519 @@ +/* + Copyright (C) 2013 by Maxim Biro + + This file is part of Tox Qt GUI. + + 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 COPYING file for more details. +*/ + +#include "core.h" +#include "cdata.h" +#include "cstring.h" +#include "settings.h" +#include "widget/widget.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const QString Core::CONFIG_FILE_NAME = "data"; +QList Core::fileSendQueue; +QList Core::fileRecvQueue; +ToxCall Core::calls[TOXAV_MAX_CALLS]; +const int Core::videobufsize{TOXAV_MAX_VIDEO_WIDTH * TOXAV_MAX_VIDEO_HEIGHT * 4}; +uint8_t* Core::videobuf; +int Core::videoBusyness; + +Core::Core(Camera* cam, QThread *coreThread) : + tox(nullptr), camera(cam) +{ + videobuf = new uint8_t[videobufsize]; + videoBusyness=0; + + toxTimer = new QTimer(this); + toxTimer->setSingleShot(true); + //saveTimer = new QTimer(this); + //saveTimer->start(TOX_SAVE_INTERVAL); + //fileTimer = new QTimer(this); + //fileTimer->start(TOX_FILE_INTERVAL); + bootstrapTimer = new QTimer(this); + bootstrapTimer->start(TOX_BOOTSTRAP_INTERVAL); + connect(toxTimer, &QTimer::timeout, this, &Core::process); + //connect(saveTimer, &QTimer::timeout, this, &Core::saveConfiguration); //Disable save timer in favor of saving on events + //connect(fileTimer, &QTimer::timeout, this, &Core::fileHeartbeat); + connect(bootstrapTimer, &QTimer::timeout, this, &Core::onBootstrapTimer); + connect(&Settings::getInstance(), &Settings::dhtServerListChanged, this, &Core::bootstrapDht); + connect(this, SIGNAL(fileTransferFinished(ToxFile)), this, SLOT(onFileTransferFinished(ToxFile))); + + for (int i=0; imoveToThread(coreThread); + calls[i].sendVideoTimer->moveToThread(coreThread); + connect(calls[i].sendVideoTimer, &QTimer::timeout, [this,i](){sendCallVideo(i);}); + } +} + +Core::~Core() +{ + if (tox) { + saveConfiguration(); + toxav_kill(toxav); + tox_kill(tox); + } + + if (videobuf) + { + delete[] videobuf; + videobuf=nullptr; + } +} + +void Core::start() +{ + // IPv6 needed for LAN discovery, but can crash some weird routers. On by default, can be disabled in options. + bool enableIPv6 = Settings::getInstance().getEnableIPv6(); + if (enableIPv6) + qDebug() << "Core starting with IPv6 enabled"; + else + qWarning() << "Core starting with IPv6 disabled. LAN discovery may not work properly."; + tox = tox_new(enableIPv6); + if (tox == nullptr) + { + if (enableIPv6) // Fallback to IPv4 + { + tox = tox_new(false); + if (tox == nullptr) + { + qCritical() << "Tox core failed to start"; + emit failedToStart(); + return; + } + else + qWarning() << "Core failed to start with IPv6, falling back to IPv4. LAN discovery may not work properly."; + } + else + { + qCritical() << "Tox core failed to start"; + emit failedToStart(); + return; + } + } + + toxav = toxav_new(tox, TOXAV_MAX_CALLS); + if (toxav == nullptr) + { + qCritical() << "Toxav core failed to start"; + emit failedToStart(); + return; + } + + qsrand(time(nullptr)); + + loadConfiguration(); + + tox_callback_friend_request(tox, onFriendRequest, this); + tox_callback_friend_message(tox, onFriendMessage, this); + tox_callback_friend_action(tox, onAction, this); + tox_callback_name_change(tox, onFriendNameChange, this); + tox_callback_typing_change(tox, onFriendTypingChange, this); + tox_callback_status_message(tox, onStatusMessageChanged, this); + tox_callback_user_status(tox, onUserStatusChanged, this); + tox_callback_connection_status(tox, onConnectionStatusChanged, this); + tox_callback_group_invite(tox, onGroupInvite, this); + tox_callback_group_message(tox, onGroupMessage, this); + tox_callback_group_namelist_change(tox, onGroupNamelistChange, this); + tox_callback_file_send_request(tox, onFileSendRequestCallback, this); + tox_callback_file_control(tox, onFileControlCallback, this); + tox_callback_file_data(tox, onFileDataCallback, this); + + toxav_register_callstate_callback(toxav, onAvInvite, av_OnInvite, this); + toxav_register_callstate_callback(toxav, onAvStart, av_OnStart, this); + toxav_register_callstate_callback(toxav, onAvCancel, av_OnCancel, this); + toxav_register_callstate_callback(toxav, onAvReject, av_OnReject, this); + toxav_register_callstate_callback(toxav, onAvEnd, av_OnEnd, this); + toxav_register_callstate_callback(toxav, onAvRinging, av_OnRinging, this); + toxav_register_callstate_callback(toxav, onAvStarting, av_OnStarting, this); + toxav_register_callstate_callback(toxav, onAvEnding, av_OnEnding, this); + toxav_register_callstate_callback(toxav, onAvMediaChange, av_OnMediaChange, this); + toxav_register_callstate_callback(toxav, onAvRequestTimeout, av_OnRequestTimeout, this); + toxav_register_callstate_callback(toxav, onAvPeerTimeout, av_OnPeerTimeout, this); + + toxav_register_audio_recv_callback(toxav, playCallAudio, this); + toxav_register_video_recv_callback(toxav, playCallVideo, this); + + uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE]; + tox_get_address(tox, friendAddress); + + emit friendAddressGenerated(CFriendAddress::toString(friendAddress)); + + bootstrapDht(); + + toxTimer->start(tox_do_interval(tox)); +} + +void Core::onBootstrapTimer() +{ + if (!tox) + return; + if(!tox_isconnected(tox)) + bootstrapDht(); +} + +void Core::onFriendRequest(Tox*/* tox*/, const uint8_t* cUserId, const uint8_t* cMessage, uint16_t cMessageSize, void* core) +{ + emit static_cast(core)->friendRequestReceived(CUserId::toString(cUserId), CString::toString(cMessage, cMessageSize)); +} + +void Core::onFriendMessage(Tox*/* tox*/, int friendId, const uint8_t* cMessage, uint16_t cMessageSize, void* core) +{ + emit static_cast(core)->friendMessageReceived(friendId, CString::toString(cMessage, cMessageSize)); +} + +void Core::onFriendNameChange(Tox*/* tox*/, int friendId, const uint8_t* cName, uint16_t cNameSize, void* core) +{ + emit static_cast(core)->friendUsernameChanged(friendId, CString::toString(cName, cNameSize)); +} + +void Core::onFriendTypingChange(Tox*/* tox*/, int friendId, uint8_t isTyping, void *core) +{ + emit static_cast(core)->friendTypingChanged(friendId, isTyping ? true : false); +} + +void Core::onStatusMessageChanged(Tox*/* tox*/, int friendId, const uint8_t* cMessage, uint16_t cMessageSize, void* core) +{ + emit static_cast(core)->friendStatusMessageChanged(friendId, CString::toString(cMessage, cMessageSize)); +} + +void Core::onUserStatusChanged(Tox*/* tox*/, int friendId, uint8_t userstatus, void* core) +{ + Status status; + switch (userstatus) { + case TOX_USERSTATUS_NONE: + status = Status::Online; + break; + case TOX_USERSTATUS_AWAY: + status = Status::Away; + break; + case TOX_USERSTATUS_BUSY: + status = Status::Busy; + break; + default: + status = Status::Online; + break; + } + emit static_cast(core)->friendStatusChanged(friendId, status); +} + +void Core::onConnectionStatusChanged(Tox*/* tox*/, int friendId, uint8_t status, void* core) +{ + Status friendStatus = status ? Status::Online : Status::Offline; + emit static_cast(core)->friendStatusChanged(friendId, friendStatus); + if (friendStatus == Status::Offline) { + static_cast(core)->checkLastOnline(friendId); + } +} + +void Core::onAction(Tox*/* tox*/, int friendId, const uint8_t *cMessage, uint16_t cMessageSize, void *core) +{ + emit static_cast(core)->actionReceived(friendId, CString::toString(cMessage, cMessageSize)); +} + +void Core::onGroupInvite(Tox*, int friendnumber, const uint8_t *group_public_key, void *core) +{ + qDebug() << QString("Core: Group invite by %1").arg(friendnumber); + emit static_cast(core)->groupInviteReceived(friendnumber, group_public_key); +} + +void Core::onGroupMessage(Tox*, int groupnumber, int friendgroupnumber, const uint8_t * message, uint16_t length, void *core) +{ + emit static_cast(core)->groupMessageReceived(groupnumber, friendgroupnumber, CString::toString(message, length)); +} + +void Core::onGroupNamelistChange(Tox*, int groupnumber, int peernumber, uint8_t change, void *core) +{ + qDebug() << QString("Core: Group namelist change %1:%2 %3").arg(groupnumber).arg(peernumber).arg(change); + emit static_cast(core)->groupNamelistChanged(groupnumber, peernumber, change); +} + +void Core::onFileSendRequestCallback(Tox*, int32_t friendnumber, uint8_t filenumber, uint64_t filesize, + const uint8_t *filename, uint16_t filename_length, void *core) +{ + qDebug() << QString("Core: Received file request %1 with friend %2").arg(filenumber).arg(friendnumber); + + ToxFile file{filenumber, friendnumber, + CString::toString(filename,filename_length).toUtf8(), "", ToxFile::RECEIVING}; + file.filesize = filesize; + fileRecvQueue.append(file); + emit static_cast(core)->fileReceiveRequested(fileRecvQueue.last()); +} +void Core::onFileControlCallback(Tox* tox, int32_t friendnumber, uint8_t receive_send, uint8_t filenumber, + uint8_t control_type, const uint8_t*, uint16_t, void *core) +{ + ToxFile* file{nullptr}; + if (receive_send == 1) + { + for (ToxFile& f : fileSendQueue) + { + if (f.fileNum == filenumber && f.friendId == friendnumber) + { + file = &f; + break; + } + } + } + else + { + for (ToxFile& f : fileRecvQueue) + { + if (f.fileNum == filenumber && f.friendId == friendnumber) + { + file = &f; + break; + } + } + } + if (!file) + { + qWarning("Core::onFileControlCallback: No such file in queue"); + return; + } + if (receive_send == 1 && control_type == TOX_FILECONTROL_ACCEPT) + { + file->status = ToxFile::TRANSMITTING; + emit static_cast(core)->fileTransferAccepted(*file); + qDebug() << "Core: File control callback, file accepted"; + file->sendFuture = QtConcurrent::run(sendAllFileData, static_cast(core), file); + } + else if (receive_send == 1 && control_type == TOX_FILECONTROL_KILL) + { + qDebug() << QString("Core::onFileControlCallback: Transfer of file %1 cancelled by friend %2") + .arg(file->fileNum).arg(file->friendId); + file->status = ToxFile::STOPPED; + emit static_cast(core)->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); + file->sendFuture.waitForFinished(); // Wait for sendAllFileData to return before deleting the ToxFile + removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum); + } + else if (receive_send == 1 && control_type == TOX_FILECONTROL_FINISHED) + { + qDebug() << QString("Core::onFileControlCallback: Transfer of file %1 to friend %2 is complete") + .arg(file->fileNum).arg(file->friendId); + file->status = ToxFile::STOPPED; + emit static_cast(core)->fileTransferFinished(*file); + removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum); + } + else if (receive_send == 0 && control_type == TOX_FILECONTROL_KILL) + { + qDebug() << QString("Core::onFileControlCallback: Transfer of file %1 cancelled by friend %2") + .arg(file->fileNum).arg(file->friendId); + file->status = ToxFile::STOPPED; + emit static_cast(core)->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::RECEIVING); + removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum); + } + else if (receive_send == 0 && control_type == TOX_FILECONTROL_FINISHED) + { + qDebug() << QString("Core::onFileControlCallback: Reception of file %1 from %2 finished") + .arg(file->fileNum).arg(file->friendId); + file->status = ToxFile::STOPPED; + emit static_cast(core)->fileTransferFinished(*file); + removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum); + // confirm receive is complete + tox_file_send_control(tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_FINISHED, nullptr, 0); + } + else + { + qDebug() << QString("Core: File control callback, receive_send=%1, control_type=%2") + .arg(receive_send).arg(control_type); + } +} + +void Core::onFileDataCallback(Tox*, int32_t friendnumber, uint8_t filenumber, const uint8_t *data, uint16_t length, void *core) +{ + ToxFile* file{nullptr}; + for (ToxFile& f : fileRecvQueue) + { + if (f.fileNum == filenumber && f.friendId == friendnumber) + { + file = &f; + break; + } + } + if (!file) + { + qWarning("Core::onFileDataCallback: No such file in queue"); + return; + } + + file->file->write((char*)data,length); + file->bytesSent += length; + //qDebug() << QString("Core::onFileDataCallback: received %1/%2 bytes").arg(file->bytesSent).arg(file->filesize); + emit static_cast(core)->fileTransferInfo(file->friendId, file->fileNum, + file->filesize, file->bytesSent, ToxFile::RECEIVING); +} + +void Core::acceptFriendRequest(const QString& userId) +{ + int friendId = tox_add_friend_norequest(tox, CUserId(userId).data()); + if (friendId == -1) { + emit failedToAddFriend(userId); + } else { + saveConfiguration(); + emit friendAdded(friendId, userId); + } +} + +void Core::requestFriendship(const QString& friendAddress, const QString& message) +{ + qDebug() << "Core: requesting friendship of "+friendAddress; + CString cMessage(message); + + int friendId = tox_add_friend(tox, CFriendAddress(friendAddress).data(), cMessage.data(), cMessage.size()); + const QString userId = friendAddress.mid(0, TOX_CLIENT_ID_SIZE * 2); + if (friendId < 0) { + emit failedToAddFriend(userId); + } else { + emit friendAdded(friendId, userId); + } + saveConfiguration(); +} + +void Core::sendMessage(int friendId, const QString& message) +{ + CString cMessage(message); + + int messageId = tox_send_message(tox, friendId, cMessage.data(), cMessage.size()); + emit messageSentResult(friendId, message, messageId); +} + +void Core::sendAction(int friendId, const QString &action) +{ + CString cMessage(action); + int ret = tox_send_action(tox, friendId, cMessage.data(), cMessage.size()); + emit actionSentResult(friendId, action, ret); +} + +void Core::sendTyping(int friendId, bool typing) +{ + int ret = tox_set_user_is_typing(tox, friendId, typing); + if (ret == -1) + emit failedToSetTyping(typing); +} + +void Core::sendGroupMessage(int groupId, const QString& message) +{ + CString cMessage(message); + + tox_group_message_send(tox, groupId, cMessage.data(), cMessage.size()); +} + +void Core::sendFile(int32_t friendId, QString Filename, QString FilePath, long long filesize) +{ + QByteArray fileName = Filename.toUtf8(); + int fileNum = tox_new_file_sender(tox, friendId, filesize, (uint8_t*)fileName.data(), fileName.size()); + if (fileNum == -1) + { + qWarning() << "Core::sendFile: Can't create the Tox file sender"; + return; + } + qDebug() << QString("Core::sendFile: Created file sender %1 with friend %2").arg(fileNum).arg(friendId); + + ToxFile file{fileNum, friendId, fileName, FilePath, ToxFile::SENDING}; + file.filesize = filesize; + if (!file.open(false)) + { + qWarning() << QString("Core::sendFile: Can't open file, error: %1").arg(file.file->errorString()); + } + fileSendQueue.append(file); + + emit fileSendStarted(fileSendQueue.last()); +} + +void Core::pauseResumeFileSend(int friendId, int fileNum) +{ + ToxFile* file{nullptr}; + for (ToxFile& f : fileSendQueue) + { + if (f.fileNum == fileNum && f.friendId == friendId) + { + file = &f; + break; + } + } + if (!file) + { + qWarning("Core::cancelFileSend: No such file in queue"); + return; + } + if (file->status == ToxFile::TRANSMITTING) + { + file->status = ToxFile::PAUSED; + emit fileTransferPaused(file->friendId, file->fileNum, ToxFile::SENDING); + tox_file_send_control(tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_PAUSE, nullptr, 0); + } + else if (file->status == ToxFile::PAUSED) + { + file->status = ToxFile::TRANSMITTING; + emit fileTransferAccepted(*file); + tox_file_send_control(tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_ACCEPT, nullptr, 0); + } + else + qWarning() << "Core::pauseResumeFileSend: File is stopped"; +} + +void Core::pauseResumeFileRecv(int friendId, int fileNum) +{ + ToxFile* file{nullptr}; + for (ToxFile& f : fileRecvQueue) + { + if (f.fileNum == fileNum && f.friendId == friendId) + { + file = &f; + break; + } + } + if (!file) + { + qWarning("Core::cancelFileRecv: No such file in queue"); + return; + } + if (file->status == ToxFile::TRANSMITTING) + { + file->status = ToxFile::PAUSED; + emit fileTransferPaused(file->friendId, file->fileNum, ToxFile::RECEIVING); + tox_file_send_control(tox, file->friendId, 1, file->fileNum, TOX_FILECONTROL_PAUSE, nullptr, 0); + } + else if (file->status == ToxFile::PAUSED) + { + file->status = ToxFile::TRANSMITTING; + emit fileTransferAccepted(*file); + tox_file_send_control(tox, file->friendId, 1, file->fileNum, TOX_FILECONTROL_ACCEPT, nullptr, 0); + } + else + qWarning() << "Core::pauseResumeFileRecv: File is stopped"; +} + +void Core::cancelFileSend(int friendId, int fileNum) +{ + ToxFile* file{nullptr}; + for (ToxFile& f : fileSendQueue) + { + if (f.fileNum == fileNum && f.friendId == friendId) + { + file = &f; + break; + } + } + if (!file) + { + qWarning("Core::cancelFileSend: No such file in queue"); + return; + } + file->status = ToxFile::STOPPED; + emit fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); + tox_file_send_control(tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0); + file->sendFuture.waitForFinished(); // Wait until sendAllFileData returns before deleting + removeFileFromQueue(true, friendId, fileNum); +} + +void Core::cancelFileRecv(int friendId, int fileNum) +{ + ToxFile* file{nullptr}; + for (ToxFile& f : fileRecvQueue) + { + if (f.fileNum == fileNum && f.friendId == friendId) + { + file = &f; + break; + } + } + if (!file) + { + qWarning("Core::cancelFileRecv: No such file in queue"); + return; + } + file->status = ToxFile::STOPPED; + emit fileTransferCancelled(file->friendId, file->fileNum, ToxFile::RECEIVING); + tox_file_send_control(tox, file->friendId, 1, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0); + removeFileFromQueue(true, friendId, fileNum); +} + +void Core::rejectFileRecvRequest(int friendId, int fileNum) +{ + ToxFile* file{nullptr}; + for (ToxFile& f : fileRecvQueue) + { + if (f.fileNum == fileNum && f.friendId == friendId) + { + file = &f; + break; + } + } + if (!file) + { + qWarning("Core::rejectFileRecvRequest: No such file in queue"); + return; + } + file->status = ToxFile::STOPPED; + emit fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); + tox_file_send_control(tox, file->friendId, 1, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0); + removeFileFromQueue(false, friendId, fileNum); +} + +void Core::acceptFileRecvRequest(int friendId, int fileNum, QString path) +{ + ToxFile* file{nullptr}; + for (ToxFile& f : fileRecvQueue) + { + if (f.fileNum == fileNum && f.friendId == friendId) + { + file = &f; + break; + } + } + if (!file) + { + qWarning("Core::acceptFileRecvRequest: No such file in queue"); + return; + } + file->setFilePath(path); + if (!file->open(true)) + { + qWarning() << "Core::acceptFileRecvRequest: Unable to open file"; + return; + } + file->status = ToxFile::TRANSMITTING; + emit fileTransferAccepted(*file); + tox_file_send_control(tox, file->friendId, 1, file->fileNum, TOX_FILECONTROL_ACCEPT, nullptr, 0); +} + +void Core::removeFriend(int friendId) +{ + if (tox_del_friend(tox, friendId) == -1) { + emit failedToRemoveFriend(friendId); + } else { + saveConfiguration(); + emit friendRemoved(friendId); + } +} + +void Core::removeGroup(int groupId) +{ + tox_del_groupchat(tox, groupId); +} + +QString Core::getUsername() +{ + int size = tox_get_self_name_size(tox); + uint8_t* name = new uint8_t[size]; + if (tox_get_self_name(tox, name) == size) + return QString(CString::toString(name, size)); + else + return QString(); + delete[] name; +} + +void Core::setUsername(const QString& username) +{ + CString cUsername(username); + + if (tox_set_name(tox, cUsername.data(), cUsername.size()) == -1) { + emit failedToSetUsername(username); + } else { + saveConfiguration(); + emit usernameSet(username); + } +} + +QString Core::getStatusMessage() +{ + int size = tox_get_self_status_message_size(tox); + uint8_t* name = new uint8_t[size]; + if (tox_get_self_status_message(tox, name, size) == size) + return QString(CString::toString(name, size)); + else + return QString(); + delete[] name; +} + +void Core::setStatusMessage(const QString& message) +{ + CString cMessage(message); + + if (tox_set_status_message(tox, cMessage.data(), cMessage.size()) == -1) { + emit failedToSetStatusMessage(message); + } else { + saveConfiguration(); + emit statusMessageSet(message); + } +} + +void Core::setStatus(Status status) +{ + TOX_USERSTATUS userstatus; + switch (status) { + case Status::Online: + userstatus = TOX_USERSTATUS_NONE; + break; + case Status::Away: + userstatus = TOX_USERSTATUS_AWAY; + break; + case Status::Busy: + userstatus = TOX_USERSTATUS_BUSY; + break; + default: + userstatus = TOX_USERSTATUS_INVALID; + break; + } + + if (tox_set_user_status(tox, userstatus) == 0) { + saveConfiguration(); + emit statusSet(status); + } else { + emit failedToSetStatus(status); + } +} + +void Core::onFileTransferFinished(ToxFile file) +{ + if (file.direction == file.SENDING) + emit fileUploadFinished(file.filePath); + else + emit fileDownloadFinished(file.filePath); +} + +void Core::bootstrapDht() +{ + qDebug() << "Core: Bootstraping DHT"; + const Settings& s = Settings::getInstance(); + QList dhtServerList = s.getDhtServerList(); + + int listSize = dhtServerList.size(); + static int j = qrand() % listSize; + int i=0; + while (i<5) + { + const Settings::DhtServer& dhtServer = dhtServerList[j % listSize]; + if (tox_bootstrap_from_address(tox, dhtServer.address.toLatin1().data(), + 0, qToBigEndian(dhtServer.port), CUserId(dhtServer.userId).data()) == 1) + qDebug() << QString("Core: Bootstraping from ")+dhtServer.name+QString(", addr ")+dhtServer.address.toLatin1().data() + +QString(", port ")+QString().setNum(dhtServer.port); + else + qDebug() << "Core: Error bootstraping from "+dhtServer.name; + + j++; + i++; + } +} + +void Core::process() +{ + tox_do(tox); +#ifdef DEBUG + //we want to see the debug messages immediately + fflush(stdout); +#endif + checkConnection(); + //int toxInterval = tox_do_interval(tox); + //qDebug() << QString("Tox interval %1").arg(toxInterval); + toxTimer->start(50); +} + +void Core::checkConnection() +{ + static bool isConnected = false; + + if (tox_isconnected(tox) && !isConnected) { + qDebug() << "Core: Connected to DHT"; + emit connected(); + isConnected = true; + } else if (!tox_isconnected(tox) && isConnected) { + qDebug() << "Core: Disconnected to DHT"; + emit disconnected(); + isConnected = false; + } +} + +void Core::loadConfiguration() +{ + QString path = Settings::getSettingsDirPath() + '/' + CONFIG_FILE_NAME; + + QFile configurationFile(path); + + if (!configurationFile.exists()) { + qWarning() << "The Tox configuration file was not found"; + return; + } + + if (!configurationFile.open(QIODevice::ReadOnly)) { + qCritical() << "File " << path << " cannot be opened"; + return; + } + + qint64 fileSize = configurationFile.size(); + if (fileSize > 0) { + QByteArray data = configurationFile.readAll(); + tox_load(tox, reinterpret_cast(data.data()), data.size()); + } + + configurationFile.close(); + + // set GUI with user and statusmsg + QString name = getUsername(); + if (name != "") + emit usernameSet(name); + + QString msg = getStatusMessage(); + if (msg != "") + emit statusMessageSet(msg); + + loadFriends(); +} + +void Core::saveConfiguration() +{ + if (!tox) + { + qWarning() << "Core::saveConfiguration: Tox not started, aborting!"; + return; + } + + QString path = Settings::getSettingsDirPath(); + + QDir directory(path); + + if (!directory.exists() && !directory.mkpath(directory.absolutePath())) { + qCritical() << "Error while creating directory " << path; + return; + } + + path += '/' + CONFIG_FILE_NAME; + QSaveFile configurationFile(path); + if (!configurationFile.open(QIODevice::WriteOnly)) { + qCritical() << "File " << path << " cannot be opened"; + return; + } + + qDebug() << "Core: writing tox_save"; + uint32_t fileSize = tox_size(tox); + if (fileSize > 0 && fileSize <= INT32_MAX) { + uint8_t *data = new uint8_t[fileSize]; + tox_save(tox, data); + configurationFile.write(reinterpret_cast(data), fileSize); + configurationFile.commit(); + delete[] data; + } +} + +void Core::loadFriends() +{ + const uint32_t friendCount = tox_count_friendlist(tox); + if (friendCount > 0) { + // assuming there are not that many friends to fill up the whole stack + int32_t *ids = new int32_t[friendCount]; + tox_get_friendlist(tox, ids, friendCount); + uint8_t clientId[TOX_CLIENT_ID_SIZE]; + for (int32_t i = 0; i < static_cast(friendCount); ++i) { + if (tox_get_client_id(tox, ids[i], clientId) == 0) { + emit friendAdded(ids[i], CUserId::toString(clientId)); + + const int nameSize = tox_get_name_size(tox, ids[i]); + if (nameSize > 0) { + uint8_t *name = new uint8_t[nameSize]; + if (tox_get_name(tox, ids[i], name) == nameSize) { + emit friendUsernameLoaded(ids[i], CString::toString(name, nameSize)); + } + delete[] name; + } + + const int statusMessageSize = tox_get_status_message_size(tox, ids[i]); + if (statusMessageSize > 0) { + uint8_t *statusMessage = new uint8_t[statusMessageSize]; + if (tox_get_status_message(tox, ids[i], statusMessage, statusMessageSize) == statusMessageSize) { + emit friendStatusMessageLoaded(ids[i], CString::toString(statusMessage, statusMessageSize)); + } + delete[] statusMessage; + } + + checkLastOnline(ids[i]); + } + + } + delete[] ids; + } +} + +void Core::checkLastOnline(int friendId) { + const uint64_t lastOnline = tox_get_last_online(tox, friendId); + if (lastOnline > 0) { + emit friendLastSeenChanged(friendId, QDateTime::fromTime_t(lastOnline)); + } +} + +int Core::getGroupNumberPeers(int groupId) const +{ + return tox_group_number_peers(tox, groupId); +} + +QString Core::getGroupPeerName(int groupId, int peerId) const +{ + QString name; + uint8_t nameArray[TOX_MAX_NAME_LENGTH]; + int length = tox_group_peername(tox, groupId, peerId, nameArray); + if (length == -1) + { + qWarning() << "Core::getGroupPeerName: Unknown error"; + return name; + } + name = CString::toString(nameArray, length); + return name; +} + +QList Core::getGroupPeerNames(int groupId) const +{ + QList names; + int nPeers = getGroupNumberPeers(groupId); + if (nPeers == -1) + { + qWarning() << "Core::getGroupPeerNames: Unable to get number of peers"; + return names; + } + uint8_t namesArray[nPeers][TOX_MAX_NAME_LENGTH]; + uint16_t* lengths = new uint16_t[nPeers]; + int result = tox_group_get_names(tox, groupId, namesArray, lengths, nPeers); + if (result != nPeers) + { + qWarning() << "Core::getGroupPeerNames: Unexpected result"; + return names; + } + for (int i=0; iclose(); + delete fileSendQueue[i].file; + fileSendQueue.removeAt(i); + continue; + } + i++; + } + } + else + { + for (int i=0; iclose(); + delete fileRecvQueue[i].file; + fileRecvQueue.removeAt(i); + continue; + } + i++; + } + } + if (!found) + qWarning() << "Core::removeFileFromQueue: No such file in queue"; +} + +void Core::sendAllFileData(Core *core, ToxFile* file) +{ + while (file->bytesSent < file->filesize) + { + if (file->status == ToxFile::PAUSED) + { + QThread::sleep(5); + continue; + } + else if (file->status == ToxFile::STOPPED) + { + qWarning("Core::sendAllFileData: File is stopped"); + return; + } + emit core->fileTransferInfo(file->friendId, file->fileNum, file->filesize, file->bytesSent, ToxFile::SENDING); + qApp->processEvents(); + long long chunkSize = tox_file_data_size(core->tox, file->friendId); + if (chunkSize == -1) + { + qWarning("Core::fileHeartbeat: Error getting preffered chunk size, aborting file send"); + file->status = ToxFile::STOPPED; + emit core->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); + tox_file_send_control(core->tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0); + removeFileFromQueue(true, file->friendId, file->fileNum); + return; + } + qDebug() << "chunkSize: " << chunkSize; + chunkSize = std::min(chunkSize, file->filesize); + uint8_t* data = new uint8_t[chunkSize]; + file->file->seek(file->bytesSent); + int readSize = file->file->read((char*)data, chunkSize); + if (readSize == -1) + { + qWarning() << QString("Core::sendAllFileData: Error reading from file: %1").arg(file->file->errorString()); + delete[] data; + QThread::msleep(5); + continue; + } + else if (readSize == 0) + { + qWarning() << QString("Core::sendAllFileData: Nothing to read from file: %1").arg(file->file->errorString()); + delete[] data; + QThread::msleep(5); + continue; + } + if (tox_file_send_data(core->tox, file->friendId, file->fileNum, data, readSize) == -1) + { + //qWarning("Core::fileHeartbeat: Error sending data chunk"); + core->process(); + delete[] data; + QThread::msleep(5); + continue; + } + delete[] data; + file->bytesSent += readSize; + //qDebug() << QString("Core::fileHeartbeat: sent %1/%2 bytes").arg(file->bytesSent).arg(file->fileData.size()); + } + qDebug("Core::fileHeartbeat: Transfer finished"); + tox_file_send_control(core->tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_FINISHED, nullptr, 0); +} + +void Core::onAvInvite(void* _toxav, int32_t call_index, void* core) +{ + ToxAv* toxav = static_cast(_toxav); + + int friendId = toxav_get_peer_id(toxav, call_index, 0); + if (friendId < 0) + { + qWarning() << "Core: Received invalid AV invite"; + return; + } + + ToxAvCSettings* transSettings = new ToxAvCSettings; + int err = toxav_get_peer_csettings(toxav, call_index, 0, transSettings); + if (err != ErrorNone) + { + qWarning() << "Core::onAvInvite: error getting call type"; + delete transSettings; + return; + } + + if (transSettings->call_type == TypeVideo) + { + qDebug() << QString("Core: AV invite from %1 with video").arg(friendId); + emit static_cast(core)->avInvite(friendId, call_index, true); + } + else + { + qDebug() << QString("Core: AV invite from %1 without video").arg(friendId); + emit static_cast(core)->avInvite(friendId, call_index, false); + } + + delete transSettings; +} + +void Core::onAvStart(void* _toxav, int32_t call_index, void* core) +{ + ToxAv* toxav = static_cast(_toxav); + + int friendId = toxav_get_peer_id(toxav, call_index, 0); + if (friendId < 0) + { + qWarning() << "Core: Received invalid AV start"; + return; + } + + ToxAvCSettings* transSettings = new ToxAvCSettings; + int err = toxav_get_peer_csettings(toxav, call_index, 0, transSettings); + if (err != ErrorNone) + { + qWarning() << "Core::onAvStart: error getting call type"; + delete transSettings; + return; + } + + if (transSettings->call_type == TypeVideo) + { + qDebug() << QString("Core: AV start from %1 with video").arg(friendId); + prepareCall(friendId, call_index, toxav, true); + emit static_cast(core)->avStart(friendId, call_index, true); + } + else + { + qDebug() << QString("Core: AV start from %1 without video").arg(friendId); + prepareCall(friendId, call_index, toxav, false); + emit static_cast(core)->avStart(friendId, call_index, false); + } + + delete transSettings; +} + +void Core::onAvCancel(void* _toxav, int32_t call_index, void* core) +{ + ToxAv* toxav = static_cast(_toxav); + + int friendId = toxav_get_peer_id(toxav, call_index, 0); + if (friendId < 0) + { + qWarning() << "Core: Received invalid AV cancel"; + return; + } + qDebug() << QString("Core: AV cancel from %1").arg(friendId); + + emit static_cast(core)->avCancel(friendId, call_index); +} + +void Core::onAvReject(void*, int32_t, void*) +{ + qDebug() << "Core: AV reject"; +} + +void Core::onAvEnd(void* _toxav, int32_t call_index, void* core) +{ + ToxAv* toxav = static_cast(_toxav); + + int friendId = toxav_get_peer_id(toxav, call_index, 0); + if (friendId < 0) + { + qWarning() << "Core: Received invalid AV end"; + return; + } + qDebug() << QString("Core: AV end from %1").arg(friendId); + + cleanupCall(call_index); + + emit static_cast(core)->avEnd(friendId, call_index); +} + +void Core::onAvRinging(void* _toxav, int32_t call_index, void* core) +{ + ToxAv* toxav = static_cast(_toxav); + + int friendId = toxav_get_peer_id(toxav, call_index, 0); + if (friendId < 0) + { + qWarning() << "Core: Received invalid AV ringing"; + return; + } + + if (calls[call_index].videoEnabled) + { + qDebug() << QString("Core: AV ringing with %1 with video").arg(friendId); + emit static_cast(core)->avRinging(friendId, call_index, true); + } + else + { + qDebug() << QString("Core: AV ringing with %1 without video").arg(friendId); + emit static_cast(core)->avRinging(friendId, call_index, false); + } +} + +void Core::onAvStarting(void* _toxav, int32_t call_index, void* core) +{ + ToxAv* toxav = static_cast(_toxav); + + int friendId = toxav_get_peer_id(toxav, call_index, 0); + if (friendId < 0) + { + qWarning() << "Core: Received invalid AV starting"; + return; + } + + ToxAvCSettings* transSettings = new ToxAvCSettings; + int err = toxav_get_peer_csettings(toxav, call_index, 0, transSettings); + if (err != ErrorNone) + { + qWarning() << "Core::onAvStarting: error getting call type"; + delete transSettings; + return; + } + + if (transSettings->call_type == TypeVideo) + { + qDebug() << QString("Core: AV starting from %1 with video").arg(friendId); + prepareCall(friendId, call_index, toxav, true); + emit static_cast(core)->avStarting(friendId, call_index, true); + } + else + { + qDebug() << QString("Core: AV starting from %1 without video").arg(friendId); + prepareCall(friendId, call_index, toxav, false); + emit static_cast(core)->avStarting(friendId, call_index, false); + } + + delete transSettings; +} + +void Core::onAvEnding(void* _toxav, int32_t call_index, void* core) +{ + ToxAv* toxav = static_cast(_toxav); + + int friendId = toxav_get_peer_id(toxav, call_index, 0); + if (friendId < 0) + { + qWarning() << "Core: Received invalid AV ending"; + return; + } + qDebug() << QString("Core: AV ending from %1").arg(friendId); + + cleanupCall(call_index); + + emit static_cast(core)->avEnding(friendId, call_index); +} + +void Core::onAvRequestTimeout(void* _toxav, int32_t call_index, void* core) +{ + ToxAv* toxav = static_cast(_toxav); + + int friendId = toxav_get_peer_id(toxav, call_index, 0); + if (friendId < 0) + { + qWarning() << "Core: Received invalid AV request timeout"; + return; + } + qDebug() << QString("Core: AV request timeout with %1").arg(friendId); + + cleanupCall(call_index); + + emit static_cast(core)->avRequestTimeout(friendId, call_index); +} + +void Core::onAvPeerTimeout(void* _toxav, int32_t call_index, void* core) +{ + ToxAv* toxav = static_cast(_toxav); + + int friendId = toxav_get_peer_id(toxav, call_index, 0); + if (friendId < 0) + { + qWarning() << "Core: Received invalid AV peer timeout"; + return; + } + qDebug() << QString("Core: AV peer timeout with %1").arg(friendId); + + cleanupCall(call_index); + + emit static_cast(core)->avPeerTimeout(friendId, call_index); +} + +void Core::onAvMediaChange(void*, int32_t, void*) +{ + // HALP, PLS COMPLETE MEH + qWarning() << "If you see this, please complain on GitHub about seeing me! (Don't forget to say what caused me!)"; +} + +void Core::answerCall(int callId) +{ + int friendId = toxav_get_peer_id(toxav, callId, 0); + if (friendId < 0) + { + qWarning() << "Core: Received invalid AV answer peer ID"; + return; + } + + ToxAvCSettings* transSettings = new ToxAvCSettings; + int err = toxav_get_peer_csettings(toxav, callId, 0, transSettings); + if (err != ErrorNone) + { + qWarning() << "Core::answerCall: error getting call settings"; + delete transSettings; + return; + } + + if (transSettings->call_type == TypeVideo) + { + qDebug() << QString("Core: answering call %1 with video").arg(callId); + toxav_answer(toxav, callId, transSettings); + } + else + { + qDebug() << QString("Core: answering call %1 without video").arg(callId); + toxav_answer(toxav, callId, transSettings); + } + + delete transSettings; +} + +void Core::hangupCall(int callId) +{ + qDebug() << QString("Core: hanging up call %1").arg(callId); + calls[callId].active = false; + toxav_hangup(toxav, callId); +} + +void Core::startCall(int friendId, bool video) +{ + int callId; + ToxAvCSettings cSettings = av_DefaultSettings; + cSettings.max_video_width = TOXAV_MAX_VIDEO_WIDTH; + cSettings.max_video_height = TOXAV_MAX_VIDEO_HEIGHT; + if (video) + { + qDebug() << QString("Core: Starting new call with %1 with video").arg(friendId); + cSettings.call_type = TypeVideo; + toxav_call(toxav, &callId, friendId, &cSettings, TOXAV_RINGING_TIME); + calls[callId].videoEnabled=true; + } + else + { + qDebug() << QString("Core: Starting new call with %1 without video").arg(friendId); + cSettings.call_type = TypeAudio; + toxav_call(toxav, &callId, friendId, &cSettings, TOXAV_RINGING_TIME); + calls[callId].videoEnabled=false; + } +} + +void Core::cancelCall(int callId, int friendId) +{ + qDebug() << QString("Core: Cancelling call with %1").arg(friendId); + calls[callId].active = false; + toxav_cancel(toxav, callId, friendId, 0); +} + +void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled) +{ + qDebug() << QString("Core: preparing call %1").arg(callId); + calls[callId].callId = callId; + calls[callId].friendId = friendId; + // the following three lines are also now redundant from startCall, but are + // necessary there for outbound and here for inbound + calls[callId].codecSettings = av_DefaultSettings; + calls[callId].codecSettings.max_video_width = TOXAV_MAX_VIDEO_WIDTH; + calls[callId].codecSettings.max_video_height = TOXAV_MAX_VIDEO_HEIGHT; + calls[callId].videoEnabled = videoEnabled; + toxav_prepare_transmission(toxav, callId, av_jbufdc, av_VADd, videoEnabled); + + // Prepare output + QAudioFormat format; + format.setSampleRate(calls[callId].codecSettings.audio_sample_rate); + format.setChannelCount(calls[callId].codecSettings.audio_channels); + format.setSampleSize(16); + format.setCodec("audio/pcm"); + format.setByteOrder(QAudioFormat::LittleEndian); + format.setSampleType(QAudioFormat::SignedInt); + if (!QAudioDeviceInfo::defaultOutputDevice().isFormatSupported(format)) + { + calls[callId].audioOutput = nullptr; + qWarning() << "Core: Raw audio format not supported by output backend, cannot play audio."; + } + else if (calls[callId].audioOutput==nullptr) + { + calls[callId].audioOutput = new QAudioOutput(format); + calls[callId].audioOutput->setBufferSize(1900*30); // Make this bigger to get less underflows, but more latency + calls[callId].audioOutput->start(&calls[callId].audioBuffer); + int error = calls[callId].audioOutput->error(); + if (error != QAudio::NoError) + { + qWarning() << QString("Core: Error %1 when starting audio output").arg(error); + } + } + + // Start input + if (!QAudioDeviceInfo::defaultInputDevice().isFormatSupported(format)) + { + calls[callId].audioInput = nullptr; + qWarning() << "Default input format not supported, cannot record audio"; + } + else if (calls[callId].audioInput==nullptr) + { + calls[callId].audioInput = new QAudioInput(format); + calls[callId].audioInputDevice = calls[callId].audioInput->start(); + } + + // Go + calls[callId].active = true; + + if (calls[callId].audioInput != nullptr) + { + calls[callId].sendAudioTimer->setInterval(2); + calls[callId].sendAudioTimer->setSingleShot(true); + connect(calls[callId].sendAudioTimer, &QTimer::timeout, [=](){sendCallAudio(callId,toxav);}); + calls[callId].sendAudioTimer->start(); + } + + if (calls[callId].videoEnabled) + { + calls[callId].sendVideoTimer->setInterval(50); + calls[callId].sendVideoTimer->setSingleShot(true); + calls[callId].sendVideoTimer->start(); + + Widget::getInstance()->getCamera()->suscribe(); + } + else if (calls[callId].audioInput == nullptr && calls[callId].audioOutput == nullptr) + { + qWarning() << "Audio only call can neither play nor record audio, killing call"; + toxav_hangup(toxav, callId); + } +} + +void Core::cleanupCall(int callId) +{ + qDebug() << QString("Core: cleaning up call %1").arg(callId); + calls[callId].active = false; + disconnect(calls[callId].sendAudioTimer,0,0,0); + calls[callId].sendAudioTimer->stop(); + calls[callId].sendVideoTimer->stop(); + if (calls[callId].audioOutput != nullptr) + { + calls[callId].audioOutput->stop(); + } + if (calls[callId].audioInput != nullptr) + { + calls[callId].audioInput->stop(); + } + if (calls[callId].videoEnabled) + Widget::getInstance()->getCamera()->unsuscribe(); + calls[callId].audioBuffer.clear(); +} + +void Core::playCallAudio(ToxAv*, int32_t callId, int16_t *data, int length, void *user_data) +{ + if (!calls[callId].active || calls[callId].audioOutput == nullptr) + return; + calls[callId].audioBuffer.write((char*)data, length*2); + int state = calls[callId].audioOutput->state(); + if (state != QAudio::ActiveState) + { + qDebug() << QString("Core: Audio state is %1").arg(state); + calls[callId].audioOutput->start(&calls[callId].audioBuffer); + } + int error = calls[callId].audioOutput->error(); + if (error != QAudio::NoError) + qWarning() << QString("Core::playCallAudio: Error: %1").arg(error); +} + +void Core::sendCallAudio(int callId, ToxAv* toxav) +{ + if (!calls[callId].active || calls[callId].audioInput == nullptr) + return; + int framesize = (calls[callId].codecSettings.audio_frame_duration * calls[callId].codecSettings.audio_sample_rate) / 1000; + uint8_t buf[framesize*2], dest[framesize*2]; + int bytesReady = calls[callId].audioInput->bytesReady(); + if (bytesReady >= framesize*2) + { + calls[callId].audioInputDevice->read((char*)buf, framesize*2); + int result = toxav_prepare_audio_frame(toxav, callId, dest, framesize*2, (int16_t*)buf, framesize); + if (result < 0) + { + qWarning() << QString("Core: Unable to prepare audio frame, error %1").arg(result); + calls[callId].sendAudioTimer->start(); + return; + } + result = toxav_send_audio(toxav, callId, dest, result); + if (result < 0) + { + qWarning() << QString("Core: Unable to send audio frame, error %1").arg(result); + calls[callId].sendAudioTimer->start(); + return; + } + calls[callId].sendAudioTimer->start(); + } + else + calls[callId].sendAudioTimer->start(); +} + +void Core::playCallVideo(ToxAv*, int32_t callId, vpx_image_t* img, void *user_data) +{ + if (!calls[callId].active || !calls[callId].videoEnabled) + return; + + if (videoBusyness >= 1) + qWarning() << "Core: playCallVideo: Busy, dropping current frame"; + else + emit Widget::getInstance()->getCore()->videoFrameReceived(img); + vpx_img_free(img); +} + +void Core::sendCallVideo(int callId) +{ + if (!calls[callId].active || !calls[callId].videoEnabled) + return; + + vpx_image frame = camera->getLastVPXImage(); + if (frame.w && frame.h) + { + int result; + if((result = toxav_prepare_video_frame(toxav, callId, videobuf, videobufsize, &frame)) < 0) + { + qDebug() << QString("Core: toxav_prepare_video_frame: error %1").arg(result); + vpx_img_free(&frame); + calls[callId].sendVideoTimer->start(); + return; + } + + if((result = toxav_send_video(toxav, callId, (uint8_t*)videobuf, result)) < 0) + qDebug() << QString("Core: toxav_send_video error: %1").arg(result); + + vpx_img_free(&frame); + } + else + qDebug("Core::sendCallVideo: Invalid frame (bad camera ?)"); + + calls[callId].sendVideoTimer->start(); +} + +void Core::groupInviteFriend(int friendId, int groupId) +{ + tox_invite_friend(tox, friendId, groupId); +} + +void Core::createGroup() +{ + emit emptyGroupCreated(tox_add_groupchat(tox)); +} + +void Core::increaseVideoBusyness() +{ + videoBusyness++; +} + +void Core::decreaseVideoBusyness() +{ + videoBusyness--; +} + +void Core::micMuteToggle(int callId) +{ + if (calls[callId].audioInput->state() == QAudio::ActiveState) + calls[callId].audioInput->stop(); + else + calls[callId].audioInput->start(); +} diff --git a/core.h b/core.h index 704022442..b07f9a60e 100644 --- a/core.h +++ b/core.h @@ -165,6 +165,8 @@ public slots: void startCall(int friendId, bool video=false); void cancelCall(int callId, int friendId); + void micMuteToggle(int callId); + signals: void connected(); void disconnected(); diff --git a/ui/micButton/micButton.css b/ui/micButton/micButton.css index bf16f8d37..ec784ae7a 100644 --- a/ui/micButton/micButton.css +++ b/ui/micButton/micButton.css @@ -1,7 +1,7 @@ QPushButton#green { background-color: transparent; - background-image: url(":/micButton/micButton.css"); + background-image: url(":/ui/micButton/micButton.png"); background-repeat: none; border: none; width: 25px; diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index 66b8afdc2..1c436cd42 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -45,6 +45,7 @@ ChatForm::ChatForm(Friend* chatFriend) volButton = new QPushButton(), micButton = new QPushButton(); chatArea = new QScrollArea(); netcam = new NetCamView(); + audioInputFlag = false; QFont bold; bold.setBold(true); @@ -159,6 +160,7 @@ ChatForm::ChatForm(Friend* chatFriend) connect(chatArea->verticalScrollBar(), &QScrollBar::rangeChanged, this, &ChatForm::onSliderRangeChanged); connect(chatArea, &QScrollArea::customContextMenuRequested, this, &ChatForm::onChatContextMenuRequested); connect(emoteButton, &QPushButton::clicked, this, &ChatForm::onEmoteButtonClicked); + connect(micButton, SIGNAL(clicked()), this, SLOT(onMicMuteToggle())); } ChatForm::~ChatForm() @@ -559,19 +561,22 @@ void ChatForm::onAvPeerTimeout(int FriendId, int) void ChatForm::onAnswerCallTriggered() { + audioInputFlag = !audioInputFlag; emit answerCall(callId); } void ChatForm::onHangupCallTriggered() { + audioInputFlag = !audioInputFlag; emit hangupCall(callId); } void ChatForm::onCallTriggered() { - callButton->disconnect(); - videoButton->disconnect(); - emit startCall(f->friendId); + audioInputFlag = !audioInputFlag; + callButton->disconnect(); + videoButton->disconnect(); + emit startCall(f->friendId); } void ChatForm::onVideoCallTriggered() @@ -583,6 +588,7 @@ void ChatForm::onVideoCallTriggered() void ChatForm::onCancelCallTriggered() { + audioInputFlag = !audioInputFlag; callButton->disconnect(); videoButton->disconnect(); callButton->setObjectName("green"); @@ -664,3 +670,21 @@ void ChatForm::onEmoteInsertRequested(QString str) msgEdit->setFocus(); // refocus so that we can continue typing } + +void ChatForm::onMicMuteToggle() +{ + if (audioInputFlag == true) + { + emit micMuteToggle(callId); + if (micButton->objectName() == "red") + { + micButton->setObjectName("green"); + micButton->style()->polish(micButton); + } + else + { + micButton->setObjectName("red"); + micButton->style()->polish(micButton); + } + } +} diff --git a/widget/form/chatform.h b/widget/form/chatform.h index 55b80eb42..d29d9e8f1 100644 --- a/widget/form/chatform.h +++ b/widget/form/chatform.h @@ -58,6 +58,7 @@ signals: void answerCall(int callId); void hangupCall(int callId); void cancelCall(int callId, int friendId); + void micMuteToggle(int callId); public slots: void startFileSend(ToxFile file); @@ -71,6 +72,7 @@ public slots: void onAvEnding(int FriendId, int CallId); void onAvRequestTimeout(int FriendId, int CallId); void onAvPeerTimeout(int FriendId, int CallId); + void onMicMuteToggle(); private slots: void onSendTriggered(); @@ -99,7 +101,7 @@ private: QString previousName; NetCamView* netcam; int curRow; - bool lockSliderToBottom; + bool lockSliderToBottom, audioInputFlag; int callId; }; diff --git a/widget/widget.cpp b/widget/widget.cpp index 650d2499d..1b102ef9b 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -427,6 +427,7 @@ void Widget::addFriend(int friendId, const QString &userId) connect(newfriend->chatForm, SIGNAL(startCall(int)), core, SLOT(startCall(int))); connect(newfriend->chatForm, SIGNAL(startVideoCall(int,bool)), core, SLOT(startCall(int,bool))); connect(newfriend->chatForm, SIGNAL(cancelCall(int,int)), core, SLOT(cancelCall(int,int))); + connect(newfriend->chatForm, SIGNAL(micMuteToggle(int)), core, SLOT(micMuteToggle(int))); connect(core, &Core::fileReceiveRequested, newfriend->chatForm, &ChatForm::onFileRecvRequest); connect(core, &Core::avInvite, newfriend->chatForm, &ChatForm::onAvInvite); connect(core, &Core::avStart, newfriend->chatForm, &ChatForm::onAvStart); From a18ba9d7ed75e134ade430b157429d378f0d7730 Mon Sep 17 00:00:00 2001 From: midnight079 Date: Tue, 19 Aug 2014 21:11:27 +0400 Subject: [PATCH 070/149] fixed some bugs with micButton --- core.cpp | 9 +- core.cpp.autosave | 1519 --------------------------------------------- 2 files changed, 4 insertions(+), 1524 deletions(-) delete mode 100644 core.cpp.autosave diff --git a/core.cpp b/core.cpp index e98a809e5..c8dbfb7a9 100644 --- a/core.cpp +++ b/core.cpp @@ -30,7 +30,6 @@ #include #include #include -#include const QString Core::CONFIG_FILE_NAME = "data"; QList Core::fileSendQueue; @@ -1525,8 +1524,8 @@ void Core::decreaseVideoBusyness() void Core::micMuteToggle(int callId) { -// if (calls[callId].audioInput->state() == QAudio::ActiveState) -// calls[callId].audioInput->stop(); -// else -// calls[callId].audioInput->start(); + if (calls[callId].audioInput->state() == QAudio::ActiveState) + calls[callId].audioInput->stop(); + else + calls[callId].audioInput->start(); } diff --git a/core.cpp.autosave b/core.cpp.autosave deleted file mode 100644 index ed4de6843..000000000 --- a/core.cpp.autosave +++ /dev/null @@ -1,1519 +0,0 @@ -/* - Copyright (C) 2013 by Maxim Biro - - This file is part of Tox Qt GUI. - - 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 COPYING file for more details. -*/ - -#include "core.h" -#include "cdata.h" -#include "cstring.h" -#include "settings.h" -#include "widget/widget.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -const QString Core::CONFIG_FILE_NAME = "data"; -QList Core::fileSendQueue; -QList Core::fileRecvQueue; -ToxCall Core::calls[TOXAV_MAX_CALLS]; -const int Core::videobufsize{TOXAV_MAX_VIDEO_WIDTH * TOXAV_MAX_VIDEO_HEIGHT * 4}; -uint8_t* Core::videobuf; -int Core::videoBusyness; - -Core::Core(Camera* cam, QThread *coreThread) : - tox(nullptr), camera(cam) -{ - videobuf = new uint8_t[videobufsize]; - videoBusyness=0; - - toxTimer = new QTimer(this); - toxTimer->setSingleShot(true); - //saveTimer = new QTimer(this); - //saveTimer->start(TOX_SAVE_INTERVAL); - //fileTimer = new QTimer(this); - //fileTimer->start(TOX_FILE_INTERVAL); - bootstrapTimer = new QTimer(this); - bootstrapTimer->start(TOX_BOOTSTRAP_INTERVAL); - connect(toxTimer, &QTimer::timeout, this, &Core::process); - //connect(saveTimer, &QTimer::timeout, this, &Core::saveConfiguration); //Disable save timer in favor of saving on events - //connect(fileTimer, &QTimer::timeout, this, &Core::fileHeartbeat); - connect(bootstrapTimer, &QTimer::timeout, this, &Core::onBootstrapTimer); - connect(&Settings::getInstance(), &Settings::dhtServerListChanged, this, &Core::bootstrapDht); - connect(this, SIGNAL(fileTransferFinished(ToxFile)), this, SLOT(onFileTransferFinished(ToxFile))); - - for (int i=0; imoveToThread(coreThread); - calls[i].sendVideoTimer->moveToThread(coreThread); - connect(calls[i].sendVideoTimer, &QTimer::timeout, [this,i](){sendCallVideo(i);}); - } -} - -Core::~Core() -{ - if (tox) { - saveConfiguration(); - toxav_kill(toxav); - tox_kill(tox); - } - - if (videobuf) - { - delete[] videobuf; - videobuf=nullptr; - } -} - -void Core::start() -{ - // IPv6 needed for LAN discovery, but can crash some weird routers. On by default, can be disabled in options. - bool enableIPv6 = Settings::getInstance().getEnableIPv6(); - if (enableIPv6) - qDebug() << "Core starting with IPv6 enabled"; - else - qWarning() << "Core starting with IPv6 disabled. LAN discovery may not work properly."; - tox = tox_new(enableIPv6); - if (tox == nullptr) - { - if (enableIPv6) // Fallback to IPv4 - { - tox = tox_new(false); - if (tox == nullptr) - { - qCritical() << "Tox core failed to start"; - emit failedToStart(); - return; - } - else - qWarning() << "Core failed to start with IPv6, falling back to IPv4. LAN discovery may not work properly."; - } - else - { - qCritical() << "Tox core failed to start"; - emit failedToStart(); - return; - } - } - - toxav = toxav_new(tox, TOXAV_MAX_CALLS); - if (toxav == nullptr) - { - qCritical() << "Toxav core failed to start"; - emit failedToStart(); - return; - } - - qsrand(time(nullptr)); - - loadConfiguration(); - - tox_callback_friend_request(tox, onFriendRequest, this); - tox_callback_friend_message(tox, onFriendMessage, this); - tox_callback_friend_action(tox, onAction, this); - tox_callback_name_change(tox, onFriendNameChange, this); - tox_callback_typing_change(tox, onFriendTypingChange, this); - tox_callback_status_message(tox, onStatusMessageChanged, this); - tox_callback_user_status(tox, onUserStatusChanged, this); - tox_callback_connection_status(tox, onConnectionStatusChanged, this); - tox_callback_group_invite(tox, onGroupInvite, this); - tox_callback_group_message(tox, onGroupMessage, this); - tox_callback_group_namelist_change(tox, onGroupNamelistChange, this); - tox_callback_file_send_request(tox, onFileSendRequestCallback, this); - tox_callback_file_control(tox, onFileControlCallback, this); - tox_callback_file_data(tox, onFileDataCallback, this); - - toxav_register_callstate_callback(toxav, onAvInvite, av_OnInvite, this); - toxav_register_callstate_callback(toxav, onAvStart, av_OnStart, this); - toxav_register_callstate_callback(toxav, onAvCancel, av_OnCancel, this); - toxav_register_callstate_callback(toxav, onAvReject, av_OnReject, this); - toxav_register_callstate_callback(toxav, onAvEnd, av_OnEnd, this); - toxav_register_callstate_callback(toxav, onAvRinging, av_OnRinging, this); - toxav_register_callstate_callback(toxav, onAvStarting, av_OnStarting, this); - toxav_register_callstate_callback(toxav, onAvEnding, av_OnEnding, this); - toxav_register_callstate_callback(toxav, onAvMediaChange, av_OnMediaChange, this); - toxav_register_callstate_callback(toxav, onAvRequestTimeout, av_OnRequestTimeout, this); - toxav_register_callstate_callback(toxav, onAvPeerTimeout, av_OnPeerTimeout, this); - - toxav_register_audio_recv_callback(toxav, playCallAudio, this); - toxav_register_video_recv_callback(toxav, playCallVideo, this); - - uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE]; - tox_get_address(tox, friendAddress); - - emit friendAddressGenerated(CFriendAddress::toString(friendAddress)); - - bootstrapDht(); - - toxTimer->start(tox_do_interval(tox)); -} - -void Core::onBootstrapTimer() -{ - if (!tox) - return; - if(!tox_isconnected(tox)) - bootstrapDht(); -} - -void Core::onFriendRequest(Tox*/* tox*/, const uint8_t* cUserId, const uint8_t* cMessage, uint16_t cMessageSize, void* core) -{ - emit static_cast(core)->friendRequestReceived(CUserId::toString(cUserId), CString::toString(cMessage, cMessageSize)); -} - -void Core::onFriendMessage(Tox*/* tox*/, int friendId, const uint8_t* cMessage, uint16_t cMessageSize, void* core) -{ - emit static_cast(core)->friendMessageReceived(friendId, CString::toString(cMessage, cMessageSize)); -} - -void Core::onFriendNameChange(Tox*/* tox*/, int friendId, const uint8_t* cName, uint16_t cNameSize, void* core) -{ - emit static_cast(core)->friendUsernameChanged(friendId, CString::toString(cName, cNameSize)); -} - -void Core::onFriendTypingChange(Tox*/* tox*/, int friendId, uint8_t isTyping, void *core) -{ - emit static_cast(core)->friendTypingChanged(friendId, isTyping ? true : false); -} - -void Core::onStatusMessageChanged(Tox*/* tox*/, int friendId, const uint8_t* cMessage, uint16_t cMessageSize, void* core) -{ - emit static_cast(core)->friendStatusMessageChanged(friendId, CString::toString(cMessage, cMessageSize)); -} - -void Core::onUserStatusChanged(Tox*/* tox*/, int friendId, uint8_t userstatus, void* core) -{ - Status status; - switch (userstatus) { - case TOX_USERSTATUS_NONE: - status = Status::Online; - break; - case TOX_USERSTATUS_AWAY: - status = Status::Away; - break; - case TOX_USERSTATUS_BUSY: - status = Status::Busy; - break; - default: - status = Status::Online; - break; - } - emit static_cast(core)->friendStatusChanged(friendId, status); -} - -void Core::onConnectionStatusChanged(Tox*/* tox*/, int friendId, uint8_t status, void* core) -{ - Status friendStatus = status ? Status::Online : Status::Offline; - emit static_cast(core)->friendStatusChanged(friendId, friendStatus); - if (friendStatus == Status::Offline) { - static_cast(core)->checkLastOnline(friendId); - } -} - -void Core::onAction(Tox*/* tox*/, int friendId, const uint8_t *cMessage, uint16_t cMessageSize, void *core) -{ - emit static_cast(core)->actionReceived(friendId, CString::toString(cMessage, cMessageSize)); -} - -void Core::onGroupInvite(Tox*, int friendnumber, const uint8_t *group_public_key, void *core) -{ - qDebug() << QString("Core: Group invite by %1").arg(friendnumber); - emit static_cast(core)->groupInviteReceived(friendnumber, group_public_key); -} - -void Core::onGroupMessage(Tox*, int groupnumber, int friendgroupnumber, const uint8_t * message, uint16_t length, void *core) -{ - emit static_cast(core)->groupMessageReceived(groupnumber, friendgroupnumber, CString::toString(message, length)); -} - -void Core::onGroupNamelistChange(Tox*, int groupnumber, int peernumber, uint8_t change, void *core) -{ - qDebug() << QString("Core: Group namelist change %1:%2 %3").arg(groupnumber).arg(peernumber).arg(change); - emit static_cast(core)->groupNamelistChanged(groupnumber, peernumber, change); -} - -void Core::onFileSendRequestCallback(Tox*, int32_t friendnumber, uint8_t filenumber, uint64_t filesize, - const uint8_t *filename, uint16_t filename_length, void *core) -{ - qDebug() << QString("Core: Received file request %1 with friend %2").arg(filenumber).arg(friendnumber); - - ToxFile file{filenumber, friendnumber, - CString::toString(filename,filename_length).toUtf8(), "", ToxFile::RECEIVING}; - file.filesize = filesize; - fileRecvQueue.append(file); - emit static_cast(core)->fileReceiveRequested(fileRecvQueue.last()); -} -void Core::onFileControlCallback(Tox* tox, int32_t friendnumber, uint8_t receive_send, uint8_t filenumber, - uint8_t control_type, const uint8_t*, uint16_t, void *core) -{ - ToxFile* file{nullptr}; - if (receive_send == 1) - { - for (ToxFile& f : fileSendQueue) - { - if (f.fileNum == filenumber && f.friendId == friendnumber) - { - file = &f; - break; - } - } - } - else - { - for (ToxFile& f : fileRecvQueue) - { - if (f.fileNum == filenumber && f.friendId == friendnumber) - { - file = &f; - break; - } - } - } - if (!file) - { - qWarning("Core::onFileControlCallback: No such file in queue"); - return; - } - if (receive_send == 1 && control_type == TOX_FILECONTROL_ACCEPT) - { - file->status = ToxFile::TRANSMITTING; - emit static_cast(core)->fileTransferAccepted(*file); - qDebug() << "Core: File control callback, file accepted"; - file->sendFuture = QtConcurrent::run(sendAllFileData, static_cast(core), file); - } - else if (receive_send == 1 && control_type == TOX_FILECONTROL_KILL) - { - qDebug() << QString("Core::onFileControlCallback: Transfer of file %1 cancelled by friend %2") - .arg(file->fileNum).arg(file->friendId); - file->status = ToxFile::STOPPED; - emit static_cast(core)->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); - file->sendFuture.waitForFinished(); // Wait for sendAllFileData to return before deleting the ToxFile - removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum); - } - else if (receive_send == 1 && control_type == TOX_FILECONTROL_FINISHED) - { - qDebug() << QString("Core::onFileControlCallback: Transfer of file %1 to friend %2 is complete") - .arg(file->fileNum).arg(file->friendId); - file->status = ToxFile::STOPPED; - emit static_cast(core)->fileTransferFinished(*file); - removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum); - } - else if (receive_send == 0 && control_type == TOX_FILECONTROL_KILL) - { - qDebug() << QString("Core::onFileControlCallback: Transfer of file %1 cancelled by friend %2") - .arg(file->fileNum).arg(file->friendId); - file->status = ToxFile::STOPPED; - emit static_cast(core)->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::RECEIVING); - removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum); - } - else if (receive_send == 0 && control_type == TOX_FILECONTROL_FINISHED) - { - qDebug() << QString("Core::onFileControlCallback: Reception of file %1 from %2 finished") - .arg(file->fileNum).arg(file->friendId); - file->status = ToxFile::STOPPED; - emit static_cast(core)->fileTransferFinished(*file); - removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum); - // confirm receive is complete - tox_file_send_control(tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_FINISHED, nullptr, 0); - } - else - { - qDebug() << QString("Core: File control callback, receive_send=%1, control_type=%2") - .arg(receive_send).arg(control_type); - } -} - -void Core::onFileDataCallback(Tox*, int32_t friendnumber, uint8_t filenumber, const uint8_t *data, uint16_t length, void *core) -{ - ToxFile* file{nullptr}; - for (ToxFile& f : fileRecvQueue) - { - if (f.fileNum == filenumber && f.friendId == friendnumber) - { - file = &f; - break; - } - } - if (!file) - { - qWarning("Core::onFileDataCallback: No such file in queue"); - return; - } - - file->file->write((char*)data,length); - file->bytesSent += length; - //qDebug() << QString("Core::onFileDataCallback: received %1/%2 bytes").arg(file->bytesSent).arg(file->filesize); - emit static_cast(core)->fileTransferInfo(file->friendId, file->fileNum, - file->filesize, file->bytesSent, ToxFile::RECEIVING); -} - -void Core::acceptFriendRequest(const QString& userId) -{ - int friendId = tox_add_friend_norequest(tox, CUserId(userId).data()); - if (friendId == -1) { - emit failedToAddFriend(userId); - } else { - saveConfiguration(); - emit friendAdded(friendId, userId); - } -} - -void Core::requestFriendship(const QString& friendAddress, const QString& message) -{ - qDebug() << "Core: requesting friendship of "+friendAddress; - CString cMessage(message); - - int friendId = tox_add_friend(tox, CFriendAddress(friendAddress).data(), cMessage.data(), cMessage.size()); - const QString userId = friendAddress.mid(0, TOX_CLIENT_ID_SIZE * 2); - if (friendId < 0) { - emit failedToAddFriend(userId); - } else { - emit friendAdded(friendId, userId); - } - saveConfiguration(); -} - -void Core::sendMessage(int friendId, const QString& message) -{ - CString cMessage(message); - - int messageId = tox_send_message(tox, friendId, cMessage.data(), cMessage.size()); - emit messageSentResult(friendId, message, messageId); -} - -void Core::sendAction(int friendId, const QString &action) -{ - CString cMessage(action); - int ret = tox_send_action(tox, friendId, cMessage.data(), cMessage.size()); - emit actionSentResult(friendId, action, ret); -} - -void Core::sendTyping(int friendId, bool typing) -{ - int ret = tox_set_user_is_typing(tox, friendId, typing); - if (ret == -1) - emit failedToSetTyping(typing); -} - -void Core::sendGroupMessage(int groupId, const QString& message) -{ - CString cMessage(message); - - tox_group_message_send(tox, groupId, cMessage.data(), cMessage.size()); -} - -void Core::sendFile(int32_t friendId, QString Filename, QString FilePath, long long filesize) -{ - QByteArray fileName = Filename.toUtf8(); - int fileNum = tox_new_file_sender(tox, friendId, filesize, (uint8_t*)fileName.data(), fileName.size()); - if (fileNum == -1) - { - qWarning() << "Core::sendFile: Can't create the Tox file sender"; - return; - } - qDebug() << QString("Core::sendFile: Created file sender %1 with friend %2").arg(fileNum).arg(friendId); - - ToxFile file{fileNum, friendId, fileName, FilePath, ToxFile::SENDING}; - file.filesize = filesize; - if (!file.open(false)) - { - qWarning() << QString("Core::sendFile: Can't open file, error: %1").arg(file.file->errorString()); - } - fileSendQueue.append(file); - - emit fileSendStarted(fileSendQueue.last()); -} - -void Core::pauseResumeFileSend(int friendId, int fileNum) -{ - ToxFile* file{nullptr}; - for (ToxFile& f : fileSendQueue) - { - if (f.fileNum == fileNum && f.friendId == friendId) - { - file = &f; - break; - } - } - if (!file) - { - qWarning("Core::cancelFileSend: No such file in queue"); - return; - } - if (file->status == ToxFile::TRANSMITTING) - { - file->status = ToxFile::PAUSED; - emit fileTransferPaused(file->friendId, file->fileNum, ToxFile::SENDING); - tox_file_send_control(tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_PAUSE, nullptr, 0); - } - else if (file->status == ToxFile::PAUSED) - { - file->status = ToxFile::TRANSMITTING; - emit fileTransferAccepted(*file); - tox_file_send_control(tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_ACCEPT, nullptr, 0); - } - else - qWarning() << "Core::pauseResumeFileSend: File is stopped"; -} - -void Core::pauseResumeFileRecv(int friendId, int fileNum) -{ - ToxFile* file{nullptr}; - for (ToxFile& f : fileRecvQueue) - { - if (f.fileNum == fileNum && f.friendId == friendId) - { - file = &f; - break; - } - } - if (!file) - { - qWarning("Core::cancelFileRecv: No such file in queue"); - return; - } - if (file->status == ToxFile::TRANSMITTING) - { - file->status = ToxFile::PAUSED; - emit fileTransferPaused(file->friendId, file->fileNum, ToxFile::RECEIVING); - tox_file_send_control(tox, file->friendId, 1, file->fileNum, TOX_FILECONTROL_PAUSE, nullptr, 0); - } - else if (file->status == ToxFile::PAUSED) - { - file->status = ToxFile::TRANSMITTING; - emit fileTransferAccepted(*file); - tox_file_send_control(tox, file->friendId, 1, file->fileNum, TOX_FILECONTROL_ACCEPT, nullptr, 0); - } - else - qWarning() << "Core::pauseResumeFileRecv: File is stopped"; -} - -void Core::cancelFileSend(int friendId, int fileNum) -{ - ToxFile* file{nullptr}; - for (ToxFile& f : fileSendQueue) - { - if (f.fileNum == fileNum && f.friendId == friendId) - { - file = &f; - break; - } - } - if (!file) - { - qWarning("Core::cancelFileSend: No such file in queue"); - return; - } - file->status = ToxFile::STOPPED; - emit fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); - tox_file_send_control(tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0); - file->sendFuture.waitForFinished(); // Wait until sendAllFileData returns before deleting - removeFileFromQueue(true, friendId, fileNum); -} - -void Core::cancelFileRecv(int friendId, int fileNum) -{ - ToxFile* file{nullptr}; - for (ToxFile& f : fileRecvQueue) - { - if (f.fileNum == fileNum && f.friendId == friendId) - { - file = &f; - break; - } - } - if (!file) - { - qWarning("Core::cancelFileRecv: No such file in queue"); - return; - } - file->status = ToxFile::STOPPED; - emit fileTransferCancelled(file->friendId, file->fileNum, ToxFile::RECEIVING); - tox_file_send_control(tox, file->friendId, 1, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0); - removeFileFromQueue(true, friendId, fileNum); -} - -void Core::rejectFileRecvRequest(int friendId, int fileNum) -{ - ToxFile* file{nullptr}; - for (ToxFile& f : fileRecvQueue) - { - if (f.fileNum == fileNum && f.friendId == friendId) - { - file = &f; - break; - } - } - if (!file) - { - qWarning("Core::rejectFileRecvRequest: No such file in queue"); - return; - } - file->status = ToxFile::STOPPED; - emit fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); - tox_file_send_control(tox, file->friendId, 1, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0); - removeFileFromQueue(false, friendId, fileNum); -} - -void Core::acceptFileRecvRequest(int friendId, int fileNum, QString path) -{ - ToxFile* file{nullptr}; - for (ToxFile& f : fileRecvQueue) - { - if (f.fileNum == fileNum && f.friendId == friendId) - { - file = &f; - break; - } - } - if (!file) - { - qWarning("Core::acceptFileRecvRequest: No such file in queue"); - return; - } - file->setFilePath(path); - if (!file->open(true)) - { - qWarning() << "Core::acceptFileRecvRequest: Unable to open file"; - return; - } - file->status = ToxFile::TRANSMITTING; - emit fileTransferAccepted(*file); - tox_file_send_control(tox, file->friendId, 1, file->fileNum, TOX_FILECONTROL_ACCEPT, nullptr, 0); -} - -void Core::removeFriend(int friendId) -{ - if (tox_del_friend(tox, friendId) == -1) { - emit failedToRemoveFriend(friendId); - } else { - saveConfiguration(); - emit friendRemoved(friendId); - } -} - -void Core::removeGroup(int groupId) -{ - tox_del_groupchat(tox, groupId); -} - -QString Core::getUsername() -{ - int size = tox_get_self_name_size(tox); - uint8_t* name = new uint8_t[size]; - if (tox_get_self_name(tox, name) == size) - return QString(CString::toString(name, size)); - else - return QString(); - delete[] name; -} - -void Core::setUsername(const QString& username) -{ - CString cUsername(username); - - if (tox_set_name(tox, cUsername.data(), cUsername.size()) == -1) { - emit failedToSetUsername(username); - } else { - saveConfiguration(); - emit usernameSet(username); - } -} - -QString Core::getStatusMessage() -{ - int size = tox_get_self_status_message_size(tox); - uint8_t* name = new uint8_t[size]; - if (tox_get_self_status_message(tox, name, size) == size) - return QString(CString::toString(name, size)); - else - return QString(); - delete[] name; -} - -void Core::setStatusMessage(const QString& message) -{ - CString cMessage(message); - - if (tox_set_status_message(tox, cMessage.data(), cMessage.size()) == -1) { - emit failedToSetStatusMessage(message); - } else { - saveConfiguration(); - emit statusMessageSet(message); - } -} - -void Core::setStatus(Status status) -{ - TOX_USERSTATUS userstatus; - switch (status) { - case Status::Online: - userstatus = TOX_USERSTATUS_NONE; - break; - case Status::Away: - userstatus = TOX_USERSTATUS_AWAY; - break; - case Status::Busy: - userstatus = TOX_USERSTATUS_BUSY; - break; - default: - userstatus = TOX_USERSTATUS_INVALID; - break; - } - - if (tox_set_user_status(tox, userstatus) == 0) { - saveConfiguration(); - emit statusSet(status); - } else { - emit failedToSetStatus(status); - } -} - -void Core::onFileTransferFinished(ToxFile file) -{ - if (file.direction == file.SENDING) - emit fileUploadFinished(file.filePath); - else - emit fileDownloadFinished(file.filePath); -} - -void Core::bootstrapDht() -{ - qDebug() << "Core: Bootstraping DHT"; - const Settings& s = Settings::getInstance(); - QList dhtServerList = s.getDhtServerList(); - - int listSize = dhtServerList.size(); - static int j = qrand() % listSize; - int i=0; - while (i<5) - { - const Settings::DhtServer& dhtServer = dhtServerList[j % listSize]; - if (tox_bootstrap_from_address(tox, dhtServer.address.toLatin1().data(), - 0, qToBigEndian(dhtServer.port), CUserId(dhtServer.userId).data()) == 1) - qDebug() << QString("Core: Bootstraping from ")+dhtServer.name+QString(", addr ")+dhtServer.address.toLatin1().data() - +QString(", port ")+QString().setNum(dhtServer.port); - else - qDebug() << "Core: Error bootstraping from "+dhtServer.name; - - j++; - i++; - } -} - -void Core::process() -{ - tox_do(tox); -#ifdef DEBUG - //we want to see the debug messages immediately - fflush(stdout); -#endif - checkConnection(); - //int toxInterval = tox_do_interval(tox); - //qDebug() << QString("Tox interval %1").arg(toxInterval); - toxTimer->start(50); -} - -void Core::checkConnection() -{ - static bool isConnected = false; - - if (tox_isconnected(tox) && !isConnected) { - qDebug() << "Core: Connected to DHT"; - emit connected(); - isConnected = true; - } else if (!tox_isconnected(tox) && isConnected) { - qDebug() << "Core: Disconnected to DHT"; - emit disconnected(); - isConnected = false; - } -} - -void Core::loadConfiguration() -{ - QString path = Settings::getSettingsDirPath() + '/' + CONFIG_FILE_NAME; - - QFile configurationFile(path); - - if (!configurationFile.exists()) { - qWarning() << "The Tox configuration file was not found"; - return; - } - - if (!configurationFile.open(QIODevice::ReadOnly)) { - qCritical() << "File " << path << " cannot be opened"; - return; - } - - qint64 fileSize = configurationFile.size(); - if (fileSize > 0) { - QByteArray data = configurationFile.readAll(); - tox_load(tox, reinterpret_cast(data.data()), data.size()); - } - - configurationFile.close(); - - // set GUI with user and statusmsg - QString name = getUsername(); - if (name != "") - emit usernameSet(name); - - QString msg = getStatusMessage(); - if (msg != "") - emit statusMessageSet(msg); - - loadFriends(); -} - -void Core::saveConfiguration() -{ - if (!tox) - { - qWarning() << "Core::saveConfiguration: Tox not started, aborting!"; - return; - } - - QString path = Settings::getSettingsDirPath(); - - QDir directory(path); - - if (!directory.exists() && !directory.mkpath(directory.absolutePath())) { - qCritical() << "Error while creating directory " << path; - return; - } - - path += '/' + CONFIG_FILE_NAME; - QSaveFile configurationFile(path); - if (!configurationFile.open(QIODevice::WriteOnly)) { - qCritical() << "File " << path << " cannot be opened"; - return; - } - - qDebug() << "Core: writing tox_save"; - uint32_t fileSize = tox_size(tox); - if (fileSize > 0 && fileSize <= INT32_MAX) { - uint8_t *data = new uint8_t[fileSize]; - tox_save(tox, data); - configurationFile.write(reinterpret_cast(data), fileSize); - configurationFile.commit(); - delete[] data; - } -} - -void Core::loadFriends() -{ - const uint32_t friendCount = tox_count_friendlist(tox); - if (friendCount > 0) { - // assuming there are not that many friends to fill up the whole stack - int32_t *ids = new int32_t[friendCount]; - tox_get_friendlist(tox, ids, friendCount); - uint8_t clientId[TOX_CLIENT_ID_SIZE]; - for (int32_t i = 0; i < static_cast(friendCount); ++i) { - if (tox_get_client_id(tox, ids[i], clientId) == 0) { - emit friendAdded(ids[i], CUserId::toString(clientId)); - - const int nameSize = tox_get_name_size(tox, ids[i]); - if (nameSize > 0) { - uint8_t *name = new uint8_t[nameSize]; - if (tox_get_name(tox, ids[i], name) == nameSize) { - emit friendUsernameLoaded(ids[i], CString::toString(name, nameSize)); - } - delete[] name; - } - - const int statusMessageSize = tox_get_status_message_size(tox, ids[i]); - if (statusMessageSize > 0) { - uint8_t *statusMessage = new uint8_t[statusMessageSize]; - if (tox_get_status_message(tox, ids[i], statusMessage, statusMessageSize) == statusMessageSize) { - emit friendStatusMessageLoaded(ids[i], CString::toString(statusMessage, statusMessageSize)); - } - delete[] statusMessage; - } - - checkLastOnline(ids[i]); - } - - } - delete[] ids; - } -} - -void Core::checkLastOnline(int friendId) { - const uint64_t lastOnline = tox_get_last_online(tox, friendId); - if (lastOnline > 0) { - emit friendLastSeenChanged(friendId, QDateTime::fromTime_t(lastOnline)); - } -} - -int Core::getGroupNumberPeers(int groupId) const -{ - return tox_group_number_peers(tox, groupId); -} - -QString Core::getGroupPeerName(int groupId, int peerId) const -{ - QString name; - uint8_t nameArray[TOX_MAX_NAME_LENGTH]; - int length = tox_group_peername(tox, groupId, peerId, nameArray); - if (length == -1) - { - qWarning() << "Core::getGroupPeerName: Unknown error"; - return name; - } - name = CString::toString(nameArray, length); - return name; -} - -QList Core::getGroupPeerNames(int groupId) const -{ - QList names; - int nPeers = getGroupNumberPeers(groupId); - if (nPeers == -1) - { - qWarning() << "Core::getGroupPeerNames: Unable to get number of peers"; - return names; - } - uint8_t namesArray[nPeers][TOX_MAX_NAME_LENGTH]; - uint16_t* lengths = new uint16_t[nPeers]; - int result = tox_group_get_names(tox, groupId, namesArray, lengths, nPeers); - if (result != nPeers) - { - qWarning() << "Core::getGroupPeerNames: Unexpected result"; - return names; - } - for (int i=0; iclose(); - delete fileSendQueue[i].file; - fileSendQueue.removeAt(i); - continue; - } - i++; - } - } - else - { - for (int i=0; iclose(); - delete fileRecvQueue[i].file; - fileRecvQueue.removeAt(i); - continue; - } - i++; - } - } - if (!found) - qWarning() << "Core::removeFileFromQueue: No such file in queue"; -} - -void Core::sendAllFileData(Core *core, ToxFile* file) -{ - while (file->bytesSent < file->filesize) - { - if (file->status == ToxFile::PAUSED) - { - QThread::sleep(5); - continue; - } - else if (file->status == ToxFile::STOPPED) - { - qWarning("Core::sendAllFileData: File is stopped"); - return; - } - emit core->fileTransferInfo(file->friendId, file->fileNum, file->filesize, file->bytesSent, ToxFile::SENDING); - qApp->processEvents(); - long long chunkSize = tox_file_data_size(core->tox, file->friendId); - if (chunkSize == -1) - { - qWarning("Core::fileHeartbeat: Error getting preffered chunk size, aborting file send"); - file->status = ToxFile::STOPPED; - emit core->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); - tox_file_send_control(core->tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0); - removeFileFromQueue(true, file->friendId, file->fileNum); - return; - } - qDebug() << "chunkSize: " << chunkSize; - chunkSize = std::min(chunkSize, file->filesize); - uint8_t* data = new uint8_t[chunkSize]; - file->file->seek(file->bytesSent); - int readSize = file->file->read((char*)data, chunkSize); - if (readSize == -1) - { - qWarning() << QString("Core::sendAllFileData: Error reading from file: %1").arg(file->file->errorString()); - delete[] data; - QThread::msleep(5); - continue; - } - else if (readSize == 0) - { - qWarning() << QString("Core::sendAllFileData: Nothing to read from file: %1").arg(file->file->errorString()); - delete[] data; - QThread::msleep(5); - continue; - } - if (tox_file_send_data(core->tox, file->friendId, file->fileNum, data, readSize) == -1) - { - //qWarning("Core::fileHeartbeat: Error sending data chunk"); - core->process(); - delete[] data; - QThread::msleep(5); - continue; - } - delete[] data; - file->bytesSent += readSize; - //qDebug() << QString("Core::fileHeartbeat: sent %1/%2 bytes").arg(file->bytesSent).arg(file->fileData.size()); - } - qDebug("Core::fileHeartbeat: Transfer finished"); - tox_file_send_control(core->tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_FINISHED, nullptr, 0); -} - -void Core::onAvInvite(void* _toxav, int32_t call_index, void* core) -{ - ToxAv* toxav = static_cast(_toxav); - - int friendId = toxav_get_peer_id(toxav, call_index, 0); - if (friendId < 0) - { - qWarning() << "Core: Received invalid AV invite"; - return; - } - - ToxAvCSettings* transSettings = new ToxAvCSettings; - int err = toxav_get_peer_csettings(toxav, call_index, 0, transSettings); - if (err != ErrorNone) - { - qWarning() << "Core::onAvInvite: error getting call type"; - delete transSettings; - return; - } - - if (transSettings->call_type == TypeVideo) - { - qDebug() << QString("Core: AV invite from %1 with video").arg(friendId); - emit static_cast(core)->avInvite(friendId, call_index, true); - } - else - { - qDebug() << QString("Core: AV invite from %1 without video").arg(friendId); - emit static_cast(core)->avInvite(friendId, call_index, false); - } - - delete transSettings; -} - -void Core::onAvStart(void* _toxav, int32_t call_index, void* core) -{ - ToxAv* toxav = static_cast(_toxav); - - int friendId = toxav_get_peer_id(toxav, call_index, 0); - if (friendId < 0) - { - qWarning() << "Core: Received invalid AV start"; - return; - } - - ToxAvCSettings* transSettings = new ToxAvCSettings; - int err = toxav_get_peer_csettings(toxav, call_index, 0, transSettings); - if (err != ErrorNone) - { - qWarning() << "Core::onAvStart: error getting call type"; - delete transSettings; - return; - } - - if (transSettings->call_type == TypeVideo) - { - qDebug() << QString("Core: AV start from %1 with video").arg(friendId); - prepareCall(friendId, call_index, toxav, true); - emit static_cast(core)->avStart(friendId, call_index, true); - } - else - { - qDebug() << QString("Core: AV start from %1 without video").arg(friendId); - prepareCall(friendId, call_index, toxav, false); - emit static_cast(core)->avStart(friendId, call_index, false); - } - - delete transSettings; -} - -void Core::onAvCancel(void* _toxav, int32_t call_index, void* core) -{ - ToxAv* toxav = static_cast(_toxav); - - int friendId = toxav_get_peer_id(toxav, call_index, 0); - if (friendId < 0) - { - qWarning() << "Core: Received invalid AV cancel"; - return; - } - qDebug() << QString("Core: AV cancel from %1").arg(friendId); - - emit static_cast(core)->avCancel(friendId, call_index); -} - -void Core::onAvReject(void*, int32_t, void*) -{ - qDebug() << "Core: AV reject"; -} - -void Core::onAvEnd(void* _toxav, int32_t call_index, void* core) -{ - ToxAv* toxav = static_cast(_toxav); - - int friendId = toxav_get_peer_id(toxav, call_index, 0); - if (friendId < 0) - { - qWarning() << "Core: Received invalid AV end"; - return; - } - qDebug() << QString("Core: AV end from %1").arg(friendId); - - cleanupCall(call_index); - - emit static_cast(core)->avEnd(friendId, call_index); -} - -void Core::onAvRinging(void* _toxav, int32_t call_index, void* core) -{ - ToxAv* toxav = static_cast(_toxav); - - int friendId = toxav_get_peer_id(toxav, call_index, 0); - if (friendId < 0) - { - qWarning() << "Core: Received invalid AV ringing"; - return; - } - - if (calls[call_index].videoEnabled) - { - qDebug() << QString("Core: AV ringing with %1 with video").arg(friendId); - emit static_cast(core)->avRinging(friendId, call_index, true); - } - else - { - qDebug() << QString("Core: AV ringing with %1 without video").arg(friendId); - emit static_cast(core)->avRinging(friendId, call_index, false); - } -} - -void Core::onAvStarting(void* _toxav, int32_t call_index, void* core) -{ - ToxAv* toxav = static_cast(_toxav); - - int friendId = toxav_get_peer_id(toxav, call_index, 0); - if (friendId < 0) - { - qWarning() << "Core: Received invalid AV starting"; - return; - } - - ToxAvCSettings* transSettings = new ToxAvCSettings; - int err = toxav_get_peer_csettings(toxav, call_index, 0, transSettings); - if (err != ErrorNone) - { - qWarning() << "Core::onAvStarting: error getting call type"; - delete transSettings; - return; - } - - if (transSettings->call_type == TypeVideo) - { - qDebug() << QString("Core: AV starting from %1 with video").arg(friendId); - prepareCall(friendId, call_index, toxav, true); - emit static_cast(core)->avStarting(friendId, call_index, true); - } - else - { - qDebug() << QString("Core: AV starting from %1 without video").arg(friendId); - prepareCall(friendId, call_index, toxav, false); - emit static_cast(core)->avStarting(friendId, call_index, false); - } - - delete transSettings; -} - -void Core::onAvEnding(void* _toxav, int32_t call_index, void* core) -{ - ToxAv* toxav = static_cast(_toxav); - - int friendId = toxav_get_peer_id(toxav, call_index, 0); - if (friendId < 0) - { - qWarning() << "Core: Received invalid AV ending"; - return; - } - qDebug() << QString("Core: AV ending from %1").arg(friendId); - - cleanupCall(call_index); - - emit static_cast(core)->avEnding(friendId, call_index); -} - -void Core::onAvRequestTimeout(void* _toxav, int32_t call_index, void* core) -{ - ToxAv* toxav = static_cast(_toxav); - - int friendId = toxav_get_peer_id(toxav, call_index, 0); - if (friendId < 0) - { - qWarning() << "Core: Received invalid AV request timeout"; - return; - } - qDebug() << QString("Core: AV request timeout with %1").arg(friendId); - - cleanupCall(call_index); - - emit static_cast(core)->avRequestTimeout(friendId, call_index); -} - -void Core::onAvPeerTimeout(void* _toxav, int32_t call_index, void* core) -{ - ToxAv* toxav = static_cast(_toxav); - - int friendId = toxav_get_peer_id(toxav, call_index, 0); - if (friendId < 0) - { - qWarning() << "Core: Received invalid AV peer timeout"; - return; - } - qDebug() << QString("Core: AV peer timeout with %1").arg(friendId); - - cleanupCall(call_index); - - emit static_cast(core)->avPeerTimeout(friendId, call_index); -} - -void Core::onAvMediaChange(void*, int32_t, void*) -{ - // HALP, PLS COMPLETE MEH - qWarning() << "If you see this, please complain on GitHub about seeing me! (Don't forget to say what caused me!)"; -} - -void Core::answerCall(int callId) -{ - int friendId = toxav_get_peer_id(toxav, callId, 0); - if (friendId < 0) - { - qWarning() << "Core: Received invalid AV answer peer ID"; - return; - } - - ToxAvCSettings* transSettings = new ToxAvCSettings; - int err = toxav_get_peer_csettings(toxav, callId, 0, transSettings); - if (err != ErrorNone) - { - qWarning() << "Core::answerCall: error getting call settings"; - delete transSettings; - return; - } - - if (transSettings->call_type == TypeVideo) - { - qDebug() << QString("Core: answering call %1 with video").arg(callId); - toxav_answer(toxav, callId, transSettings); - } - else - { - qDebug() << QString("Core: answering call %1 without video").arg(callId); - toxav_answer(toxav, callId, transSettings); - } - - delete transSettings; -} - -void Core::hangupCall(int callId) -{ - qDebug() << QString("Core: hanging up call %1").arg(callId); - calls[callId].active = false; - toxav_hangup(toxav, callId); -} - -void Core::startCall(int friendId, bool video) -{ - int callId; - ToxAvCSettings cSettings = av_DefaultSettings; - cSettings.max_video_width = TOXAV_MAX_VIDEO_WIDTH; - cSettings.max_video_height = TOXAV_MAX_VIDEO_HEIGHT; - if (video) - { - qDebug() << QString("Core: Starting new call with %1 with video").arg(friendId); - cSettings.call_type = TypeVideo; - toxav_call(toxav, &callId, friendId, &cSettings, TOXAV_RINGING_TIME); - calls[callId].videoEnabled=true; - } - else - { - qDebug() << QString("Core: Starting new call with %1 without video").arg(friendId); - cSettings.call_type = TypeAudio; - toxav_call(toxav, &callId, friendId, &cSettings, TOXAV_RINGING_TIME); - calls[callId].videoEnabled=false; - } -} - -void Core::cancelCall(int callId, int friendId) -{ - qDebug() << QString("Core: Cancelling call with %1").arg(friendId); - calls[callId].active = false; - toxav_cancel(toxav, callId, friendId, 0); -} - -void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled) -{ - qDebug() << QString("Core: preparing call %1").arg(callId); - calls[callId].callId = callId; - calls[callId].friendId = friendId; - // the following three lines are also now redundant from startCall, but are - // necessary there for outbound and here for inbound - calls[callId].codecSettings = av_DefaultSettings; - calls[callId].codecSettings.max_video_width = TOXAV_MAX_VIDEO_WIDTH; - calls[callId].codecSettings.max_video_height = TOXAV_MAX_VIDEO_HEIGHT; - calls[callId].videoEnabled = videoEnabled; - toxav_prepare_transmission(toxav, callId, av_jbufdc, av_VADd, videoEnabled); - - // Prepare output - QAudioFormat format; - format.setSampleRate(calls[callId].codecSettings.audio_sample_rate); - format.setChannelCount(calls[callId].codecSettings.audio_channels); - format.setSampleSize(16); - format.setCodec("audio/pcm"); - format.setByteOrder(QAudioFormat::LittleEndian); - format.setSampleType(QAudioFormat::SignedInt); - if (!QAudioDeviceInfo::defaultOutputDevice().isFormatSupported(format)) - { - calls[callId].audioOutput = nullptr; - qWarning() << "Core: Raw audio format not supported by output backend, cannot play audio."; - } - else if (calls[callId].audioOutput==nullptr) - { - calls[callId].audioOutput = new QAudioOutput(format); - calls[callId].audioOutput->setBufferSize(1900*30); // Make this bigger to get less underflows, but more latency - calls[callId].audioOutput->start(&calls[callId].audioBuffer); - int error = calls[callId].audioOutput->error(); - if (error != QAudio::NoError) - { - qWarning() << QString("Core: Error %1 when starting audio output").arg(error); - } - } - - // Start input - if (!QAudioDeviceInfo::defaultInputDevice().isFormatSupported(format)) - { - calls[callId].audioInput = nullptr; - qWarning() << "Default input format not supported, cannot record audio"; - } - else if (calls[callId].audioInput==nullptr) - { - calls[callId].audioInput = new QAudioInput(format); - calls[callId].audioInputDevice = calls[callId].audioInput->start(); - } - - // Go - calls[callId].active = true; - - if (calls[callId].audioInput != nullptr) - { - calls[callId].sendAudioTimer->setInterval(2); - calls[callId].sendAudioTimer->setSingleShot(true); - connect(calls[callId].sendAudioTimer, &QTimer::timeout, [=](){sendCallAudio(callId,toxav);}); - calls[callId].sendAudioTimer->start(); - } - - if (calls[callId].videoEnabled) - { - calls[callId].sendVideoTimer->setInterval(50); - calls[callId].sendVideoTimer->setSingleShot(true); - calls[callId].sendVideoTimer->start(); - - Widget::getInstance()->getCamera()->suscribe(); - } - else if (calls[callId].audioInput == nullptr && calls[callId].audioOutput == nullptr) - { - qWarning() << "Audio only call can neither play nor record audio, killing call"; - toxav_hangup(toxav, callId); - } -} - -void Core::cleanupCall(int callId) -{ - qDebug() << QString("Core: cleaning up call %1").arg(callId); - calls[callId].active = false; - disconnect(calls[callId].sendAudioTimer,0,0,0); - calls[callId].sendAudioTimer->stop(); - calls[callId].sendVideoTimer->stop(); - if (calls[callId].audioOutput != nullptr) - { - calls[callId].audioOutput->stop(); - } - if (calls[callId].audioInput != nullptr) - { - calls[callId].audioInput->stop(); - } - if (calls[callId].videoEnabled) - Widget::getInstance()->getCamera()->unsuscribe(); - calls[callId].audioBuffer.clear(); -} - -void Core::playCallAudio(ToxAv*, int32_t callId, int16_t *data, int length, void *user_data) -{ - if (!calls[callId].active || calls[callId].audioOutput == nullptr) - return; - calls[callId].audioBuffer.write((char*)data, length*2); - int state = calls[callId].audioOutput->state(); - if (state != QAudio::ActiveState) - { - qDebug() << QString("Core: Audio state is %1").arg(state); - calls[callId].audioOutput->start(&calls[callId].audioBuffer); - } - int error = calls[callId].audioOutput->error(); - if (error != QAudio::NoError) - qWarning() << QString("Core::playCallAudio: Error: %1").arg(error); -} - -void Core::sendCallAudio(int callId, ToxAv* toxav) -{ - if (!calls[callId].active || calls[callId].audioInput == nullptr) - return; - int framesize = (calls[callId].codecSettings.audio_frame_duration * calls[callId].codecSettings.audio_sample_rate) / 1000; - uint8_t buf[framesize*2], dest[framesize*2]; - int bytesReady = calls[callId].audioInput->bytesReady(); - if (bytesReady >= framesize*2) - { - calls[callId].audioInputDevice->read((char*)buf, framesize*2); - int result = toxav_prepare_audio_frame(toxav, callId, dest, framesize*2, (int16_t*)buf, framesize); - if (result < 0) - { - qWarning() << QString("Core: Unable to prepare audio frame, error %1").arg(result); - calls[callId].sendAudioTimer->start(); - return; - } - result = toxav_send_audio(toxav, callId, dest, result); - if (result < 0) - { - qWarning() << QString("Core: Unable to send audio frame, error %1").arg(result); - calls[callId].sendAudioTimer->start(); - return; - } - calls[callId].sendAudioTimer->start(); - } - else - calls[callId].sendAudioTimer->start(); -} - -void Core::playCallVideo(ToxAv*, int32_t callId, vpx_image_t* img, void *user_data) -{ - if (!calls[callId].active || !calls[callId].videoEnabled) - return; - - if (videoBusyness >= 1) - qWarning() << "Core: playCallVideo: Busy, dropping current frame"; - else - emit Widget::getInstance()->getCore()->videoFrameReceived(img); - vpx_img_free(img); -} - -void Core::sendCallVideo(int callId) -{ - if (!calls[callId].active || !calls[callId].videoEnabled) - return; - - vpx_image frame = camera->getLastVPXImage(); - if (frame.w && frame.h) - { - int result; - if((result = toxav_prepare_video_frame(toxav, callId, videobuf, videobufsize, &frame)) < 0) - { - qDebug() << QString("Core: toxav_prepare_video_frame: error %1").arg(result); - vpx_img_free(&frame); - calls[callId].sendVideoTimer->start(); - return; - } - - if((result = toxav_send_video(toxav, callId, (uint8_t*)videobuf, result)) < 0) - qDebug() << QString("Core: toxav_send_video error: %1").arg(result); - - vpx_img_free(&frame); - } - else - qDebug("Core::sendCallVideo: Invalid frame (bad camera ?)"); - - calls[callId].sendVideoTimer->start(); -} - -void Core::groupInviteFriend(int friendId, int groupId) -{ - tox_invite_friend(tox, friendId, groupId); -} - -void Core::createGroup() -{ - emit emptyGroupCreated(tox_add_groupchat(tox)); -} - -void Core::increaseVideoBusyness() -{ - videoBusyness++; -} - -void Core::decreaseVideoBusyness() -{ - videoBusyness--; -} - -void Core::micMuteToggle(int callId) -{ - if (calls[callId].audioInput->state() == QAudio::ActiveState) - calls[callId].audioInput->stop(); - else - calls[callId].audioInput->start(); -} From ec1facccf80d24dddb70d787e909d66d4756377f Mon Sep 17 00:00:00 2001 From: midnight079 Date: Tue, 19 Aug 2014 21:15:56 +0400 Subject: [PATCH 071/149] fixed some bugs with micButton --- core.cpp | 2 +- widget/form/chatform.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/core.cpp b/core.cpp index c8dbfb7a9..a9475071b 100644 --- a/core.cpp +++ b/core.cpp @@ -1525,7 +1525,7 @@ void Core::decreaseVideoBusyness() void Core::micMuteToggle(int callId) { if (calls[callId].audioInput->state() == QAudio::ActiveState) - calls[callId].audioInput->stop(); + calls[callId].audioInput->suspend(); else calls[callId].audioInput->start(); } diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index 1c436cd42..cbb245afb 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -569,6 +569,8 @@ void ChatForm::onHangupCallTriggered() { audioInputFlag = !audioInputFlag; emit hangupCall(callId); + micButton->setObjectName("green"); + micButton->style()->polish(micButton); } void ChatForm::onCallTriggered() From 5e5bb66409948f7d65d250fee3edfc2660757ba8 Mon Sep 17 00:00:00 2001 From: midnight079 Date: Tue, 19 Aug 2014 22:19:27 +0400 Subject: [PATCH 072/149] changed size of micButton and volButton --- ui/micButton/micButton.png | Bin 456 -> 634 bytes ui/micButton/micButtonDisabled.png | Bin 513 -> 523 bytes ui/micButton/micButtonHover.png | Bin 492 -> 534 bytes ui/micButton/micButtonPressed.png | Bin 640 -> 651 bytes ui/volButton/volButton.png | Bin 469 -> 582 bytes ui/volButton/volButtonHover.png | Bin 497 -> 607 bytes ui/volButton/volButtonPressed.png | Bin 526 -> 630 bytes 7 files changed, 0 insertions(+), 0 deletions(-) diff --git a/ui/micButton/micButton.png b/ui/micButton/micButton.png index cc5d7109c04223373d0348a727bff78ce71fd51b..7f0cf0c4d24eee0fe208f24843f10fa36fe4a157 100644 GIT binary patch literal 634 zcmV-=0)_pFP)XV!f9Kvi1A>%M5p5ccCTeV=Ci((K-MQ#9=-LlFA1ymi1P@NyPZ zQPMCV4JoPt1we>xj57{FravhHFMv%4YyhR{il6}}j3BnMA`4L1)u&;j+*O`fm5V*Sb^tcfrPfxwN@8rzKz9GvVEnHZCYm&`1q1n?mx zi4z_q>s&3?sK!+)@e0*A;ePcYNg=_j&kWNX!{ng?2r6L3;UpURt%~Xp5J`lU2qc5% zxtMwFm8^c$G96PEMo)S!WNGktHvauiF94Q_ZQ+`cj0IqwR5G5~kvRyN5f=m-3`R`O zV^4X> z1pzA-BNkPiuxA#yH$5*DMKw@%m$_ZJ!}VgFf-Qo;ssF>z-XV?d9^FA_9=vCOEufvd z)*^U3s!ILRDo<+9czo?CwPKy10Uy$tG0Rw6vS`qcy6wbajU6`6ds5O|wxP000yS1^@s6cz2e)00006VoOIv0C@n% z0B=NW#mxW!00(qQO+^RZ2n`J~EryNXv;Y7BYDq*vR5;7cl|3(mQ5462=iVl*h=B$R zG57+eMhw1yNldot+JTS4ATf{_ET&p&V32e%FxZ4eBwiAstq5A4=N^L=eSeCI|8#TD zz4v$j=iCEs6NC_}c=d@%>4mznsC`gK80~1V*Ow$|g`{+}Y zjng#_ZuVPE?=eBPQVjqQgsG9~Kvn`lssUy7g`*Wvr~daLL8K@korRR$bR6=dn*1w> z$T!lZstxn3D1L*}RIO06pcPwpaaBe6+`!j%TTToXBNj!;6|*I04nZ(tuwuD?$+rYF zhZwgCY zvIBX)aP0ufkcVb3aWvA;%;+pb-NQApll(DTXPXrKLNmsLjm?b>0^^NF6#Qq7ZV$;7 yvqVB&SYx?^C@ znZR>{`Y-TbA`>{ta?8P_nWY#HFSQWT>{6^!H7S9is|_ZrLsBblwOSw|Ff*7LB7*jF zI~6Rmi{y6)s*37$6~$r^A_6GjI1cU~?oy?h0xJNT(Y4uZ;_>M*{`-?uM3B$tm-<_j z?PQb9u1L@GP%f9@Zn%h|XaeoNby2I;5ClQ8#=WhVy5+?K84L!f*X!tXIxxn-7=!k6 z8;wQ-VHhStgTnBYPR@_FN6x6~^)^e1_F)1z?nv!&FAv?%R_?2C@C~Spud0|mBLe^c N002ovPDHLkV1hfU;f??R literal 513 zcmV+c0{;DpP)P000yS1^@s6cz2e)00006VoOIv0C@n% z0B=NW#mxW!00(qQO+^RZ2n`K272(eD?EnA)qe(hJk{cj#CAYMkfQkajh=2eo63t4HXrMy;$_|hX-k~9oUuP5GmG*dM_M5k3 zilS(%3}Y6NVdP%t z+3C!cpNe;TOon~@lh`nVm&K}U6I?2luu<7SKA-7 z3jhESp;E4l7|8Jatcna4=qe0DD{NM{M5ONo)5@yIEQzPa^=p^e;_5{<3S%~|9?RL{ z>L$0rC?s|>8P|E5rjzF>1ct?48cZ%CFveIL!fGZ-lJw1mh``KfwOW5yq<&gQ9LL|C z6A_3A^|O;9{*&(s3FM1ouar_yNJuCH@7#a)oRdMXW0u*d3SByYx}EgoRKkFYc!ipByj>S=Yg5=@c4j>%L_CbjZ7O0 z3AF!yO;HpD&rA1*;bUQwB-@kI{EmeLZ$Wak5Qp2Ju?e!`gt;#o00000NkvXXu0mjf DpFHGN diff --git a/ui/micButton/micButtonHover.png b/ui/micButton/micButtonHover.png index 92ad9fbaca04fec1485bd13b0f9c51f3d13a58b1..462337253b66b66b11d62091acadf2c8ca1d6748 100644 GIT binary patch literal 534 zcmV+x0_pvUP)LZw zDs(8Kt-&a?MbT7CUi$8FhzYMrUK8T#xm>vS+{5>M=Un*Y@vDbb!=48Xw?Hrq071xy zVS`-$oR7>h(wM#sE%%+fFYtBpB{43ZI1<4Q53!EhaUtG(Sh>2OZQl*)z8(uJ$}u``}Ol(4HJx} zaw8F8rB=txh!zL?X02X0jthWC<057M1UyUp2c8{x+K<#}3$4G*rdJ$^XQi8uLkoZtMaOT;S;Rkgd;~bh1wIjJq-2$t)Y=7{af!6B?}- zeEHp?T3)1DUZmMRVEb!>G)oJ+Ok-z9o@_t5Viva&4L6F|MfyL{^XX`@P-z;|H!6DP Y50DV60ddNU^#A|>07*qoM6N<$f=kQij{pDw literal 492 zcmVP000yS1^@s6cz2e)00006VoOIv0C@n% z0B=NW#mxW!00(qQO+^RZ2n`K3GH>Y@MF0Q+j!8s8R5;7+l|4%XK@f)DnZ4Y_q%anO zpn`>9tDyMii%D3q?T`5kU({5g`b6iXeyqqa;yCa(B61i+p&we4UDr z!go2Ao!i}Kc9@-|WGbPTtEFv27;yqK07ytsy}6~JT5R62Teh;RwzPM{T6jyVIOTnv z^;H5lCo}*GsyTM|?s?r5pn%5A8w*p-30|k08I*KVo++u!fgX7MIWGxXNC@QBGHYgoG`vBTA+cA=9ZG>TE2w)p$?p0;>6L i`bc$UN$WHyg7Hsu2#LCVErV+S0000CFNF diff --git a/ui/micButton/micButtonPressed.png b/ui/micButton/micButtonPressed.png index f5288da5609bd1985cf07ce9c6f7536530842288..cf46b7cf6a48252cd25203e7e1b662f02e87d124 100644 GIT binary patch literal 651 zcmV;60(AX}P)>hf{9Sw+oRNMCNAqA z9r5$kOT;NEGf*JBOfbwF3W!i@Hc>#G3#KZiMgtYefX0VOV`-jyzMs%MYIzP@DHbv1a(=!e#(&p6 zO27S?fzgdlF`JuIpTEG{sG_5BuwN`P>HMI#zYl}Ke2vfUt$p&XB!47f#N6d2zYY!< zeff&5ZDDIQhOHJ?hll9(b+SIT?%ZAN$mgezcE>C7q1v64GldeYjWMX_1uwo2>ZXMn l$|xEff8V+JtA?R?*nP000yS1^@s6cz2e)00006VoOIv0C@n% z0B=NW#mxW!00(qQO+^RZ2n`K5I1#_o)c^njB1uF+R5;6(RXuOhP!v7q*^bmNsVJz) z0!SqbAW%03S4F_m0SOjsAO%suQbq@>gzu@mml%l!)@(G!W1b5 z)x&ZwnJA{cD8Ti?#T6RVq>I(vU95Mza9gc~wbmH!?cw6+2$WeMD+79#aVbS9>Ouej zPzvkaE`&({v1bVYZVfhy0n+_;yVP-Y5L&pE%!0HEqB4jWm$f3C*nr1!SHe66G|q%+ zCP@JZ07naW8JLD(OztUwYZlRbZllZ0Nb-P8`O>6oUd}d17U%z?G5031L#PZzmBpA9 zfCwat>Z!}g^q)%SDQc1VN2O|IqF4h-6a)+BB%l=FIEaSBdO=F1l9`WsJw$`SA{!DQ zG3xc|sqb{#7h1$cvxfn-__u*}g~dY3%2EWEuA9QckD8voauzBGpb03+w{2%*1I-sN z(dcvv#(zG4!rA^lFqxDFh#kUt{Orz7Gnj6AkyzWkjK>(ieS>HaK&`HTu8Z({AESc< zoF5(nVQBwF00=$eM`!t%ec!(pv>Wf5zo$2-EiHn1W6fDznTXPdO_>N?%IWQu54XNt aJoyI;|JPV`81z;E0000;qc6P&->2E(^u;a;5o1cIR1Za0*@nL0Q62n zP!vIqAKwQGcN(awvRH4EL`@X6N_r0P^Me1B8TT$f;O^=gdC092Kle=YFy>OS#7e8n z?F)BUsGg_Pa;nY*3qn?o7!|)KcA5{l*y!-+YM*A@LJ+!VuTX|!iV<1htjt)y_Jo?R zPmUmDEG4TfH&;*;C!Th_Lr^^#xYUB{=Wf!foS8Dsi90k*5Ry1C4UA^ZG8j=3nTi&% zi@^ZTG%py2*jctOoYAoy%C<6mAYDN4 zd%r&MVr#%o`jK%MvpxKP7k{#j0|7w@8m0`2eTDDiZ@m8el6KM|D@Rm)%>P000yS1^@s6cz2e)00006VoOIv0BZok z0AR>C-ctsTU1vTWUzIF=DHAG<)bIqi*0meA;WE>L_4Ox$L$SaKniL- zP6sXbts(_BzUo)n>%)0-Ew!x$wIw0JnkFoYd+t`07WpDK%#(;>pf#_dD zQtvO-canC1c#6|4Rt}fYXbdKAP1~CO&>&-xiSLTK$s}Dsl#u>N{Q%@*=X#r`w?}5W z=MaR8m-D};E3313lowS%VvIpVIJ!Gv|8|e(>=VgM!i5u2yxUo{tx=+K%?d&Cs_5+g zghcwXsN)xa2n=CZG~ z-ZEEe(yFgvbV51jgx z$7@e1hNW|tLF!VLt1Dcu-8iXbz+z>Y&-{>Z)SIoHa}ks$n&^ zOW{OMdY`qDNG2~b5qSof&^$qLQ+gy{;YA0Izs*RURrRbCiqai+Ge4UMHe%TA?Qmqf zBTw=u<*-7tyl_%;Pj_&De~6h5Tnvi5{rWoNPp6hT{D%FYMbMANRIctSm9~mcrN&6NJ!tM`*&4VKNDN zs=$QobicFR`9cA~R^7;})ce-8a1x3iNZ2%WS;?D`|;gk$KhE&lJGIZXdNX~*rZ lRr}ww*y9F1E5olmGw$lSxEDR5;7EmAgs=F%*XXb7ppS@PZDDjkT(FW@@IIe_X!wtClYo z@?bgq4#|iYS^**>Kyo6h2nni(1ef;9(CLVd2?%inbF1K?V{;mEAd&KE_S{DzqqF z_yUGjYHm!`InJYfkMrzlKG}Rh})CYW*X^ elkO!GCf@*hEseIj#uuId0000+bIA50s~1zK~y-)os>Uo6hRoq zfA7rf<@R#tT_H+L2#LlB8VE+TP)Ow$@B@e<7K&wBm6U?5UA~2#AYyM5P!Rl+NK%Lp zxjXZBvp4fvXpY?NM3cPBH1qEMfA*PYo*B9I^5$bf<`uOZp^O-UhT^=jJE-0;BJ%X8 zP=KHTMT_&nm&-}IU{p0Z4s^6OPQBDXwFuAhof*S1YP++|y{QM>zIdPAkQMq~Jx2y- zeus(1B;zM0xIQ$?nZXgf`l8pdj|E|?v&m+@(KFgvi*xl!9!<|tO=<{+f2otx_|PdZ zTy&{^i@D2BsFYGby1&c(HskdP#%gC#6l*LawK04o9Z_&6bhvW*8ufCcx1oxN>83#t zs!27P4tJ23UIWrqyC+%-?^m5qda1$Cf8a2R5;V}tnn*-I6r8#W&)&_WeL`}dalUbZyO$m^bLuKV zJxlG+Sh0uo7>qGk=^d%7u+;v-i^b=xtS_@0cKP`81J1aJVu46nqP_u?>;ONuzVl}F z6~on0HuDWqS1Cl!S+UV0`L9Y$iT7)Zyj^|GfGtOJY@Bh+vBv-IMBu*M;Mw(nUYf1mwVr!%exEC{Jfmo(_?Z*)S<2?C6WXaE2J07*qo IM6N<$g2QncmH+?% delta 517 zcmV+g0{Z>-1daqDiBL{Q4GJ0x0000DNk~Le0000P0000K2nGNE0C;zny^$dme+P6) zO+^RZ2n`J=1auO;0{{R4ut`KgR5;76l(9=3K@`Tn_h$Caji)FINyMZ%^uQukDeNLz z3L%jsT116_g<>K0`cH^|K)}i_U7Bb>6tS|fxtJ&%D1sp_7r9GzcV3!!DDKEQ>ziVj z`DWga`QGs8)u-VF0xb!o1rEW)e=uSaHO2ZQHqi?vqD5B#04o3hjENr?@-53OBCW^} zdDUdq1cG{48)9UP>1T6zS$t#FBNK5Z2!T*)@58&&1e(2Od)=}?MtjEb=s_29oWt{n z1NRRZD@|amG}%}e+j^~M^=*k(20wzC0MNDldR#+y;pw%#uEG;HNQd7Ef5j@*%Y5y- z*%g~OwS69YZV-V<4H1DG#M}W=4FgArq=y850=L4?ewhM@Zq_OeF;aYux4rK{|9@Vk zdSr(X2!dooe}`4;#kKM(&T40v>7NIIu>W(~hn)P0mCV6ske5h+_gWb00000NkvXX Hu0mjfKZD~e From 8d5e4389eb31edc31ada7346057437814e537391 Mon Sep 17 00:00:00 2001 From: Serg Date: Wed, 20 Aug 2014 09:59:56 +0700 Subject: [PATCH 073/149] added easy installation on OS X --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9609fee0c..26822dd3a 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,14 @@ Then run the script bootstrap.sh (for Linux and Mac) or bootsrap.bat (for Window And finally run the commands "qmake" and "make" to start building qTox. -

OSX Install Guide

+

OSX Easy Install

+ +Since https://github.com/ReDetection/homebrew-qtox you can easily install qtox with homebrew +```bash +brew install --HEAD ReDetection/qtox/qtox +``` + +

OSX Full Install Guide

This guide is intended for people who wish to use an existing or new ProjectTox-Core installation separate to the bundled installation with qTox, if you do not wish to use a separate installation you can skip to the section titled 'Final Steps'. From 11c6dd7becc282828f3665aa64e85ed8a811ba52 Mon Sep 17 00:00:00 2001 From: apprb Date: Fri, 22 Aug 2014 22:19:16 +0700 Subject: [PATCH 074/149] sort the friendlist by contact Status --- main.cpp | 1 - qtox.pro | 6 ++-- widget/friendlistwidget.cpp | 66 +++++++++++++++++++++++++++++++++++++ widget/friendlistwidget.h | 44 +++++++++++++++++++++++++ widget/friendwidget.cpp | 5 +++ widget/friendwidget.h | 1 + widget/widget.cpp | 20 +++++------ widget/widget.h | 2 ++ 8 files changed, 132 insertions(+), 13 deletions(-) create mode 100644 widget/friendlistwidget.cpp create mode 100644 widget/friendlistwidget.h diff --git a/main.cpp b/main.cpp index f61cbadf4..d2d34b138 100644 --- a/main.cpp +++ b/main.cpp @@ -58,7 +58,6 @@ int main(int argc, char *argv[]) * Most cameras use YUYV, implement YUYV -> YUV240 * Sending large files (~380MB) "restarts" after ~10MB. Goes back to 0%, consumes twice as much ram (reloads the file?) * => Don't load the whole file at once, load small chunks (25MB?) when needed, then free them and load the next - * Sort the friend list by status, online first then busy then offline * Don't do anything if a friend is disconnected, don't print to the chat * Changing online/away/busy/offline by clicking the bubble * /me action messages diff --git a/qtox.pro b/qtox.pro index c975ceea5..84ec1e54e 100644 --- a/qtox.pro +++ b/qtox.pro @@ -89,7 +89,8 @@ HEADERS += widget/form/addfriendform.h \ widget/emoticonswidget.h \ style.h \ widget/adjustingscrollarea.h \ - widget/croppinglabel.h + widget/croppinglabel.h \ + widget/friendlistwidget.h SOURCES += \ widget/form/addfriendform.cpp \ @@ -126,4 +127,5 @@ SOURCES += \ widget/emoticonswidget.cpp \ style.cpp \ widget/adjustingscrollarea.cpp \ - widget/croppinglabel.cpp + widget/croppinglabel.cpp \ + widget/friendlistwidget.cpp diff --git a/widget/friendlistwidget.cpp b/widget/friendlistwidget.cpp new file mode 100644 index 000000000..1792e00c5 --- /dev/null +++ b/widget/friendlistwidget.cpp @@ -0,0 +1,66 @@ +/* + Copyright (C) 2014 by Project Tox + + 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. +*/ +#include "friendlistwidget.h" + +FriendListWidget::FriendListWidget(QWidget *parent) : + QWidget(parent) +{ + mainLayout = new QGridLayout(); + setLayout(mainLayout); + setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + layout()->setSpacing(0); + layout()->setMargin(0); + + groupLayout = new QVBoxLayout(); + groupLayout->setSpacing(0); + groupLayout->setMargin(0); + + for (Status s : {Status::Online, Status::Away, Status::Busy, Status::Offline}) + { + QLayout *l = new QVBoxLayout(); + l->setSpacing(0); + l->setMargin(0); + + layouts[static_cast(s)] = l; + } + + mainLayout->addLayout(layouts[static_cast(Status::Online)], 0, 0); + mainLayout->addLayout(groupLayout, 1, 0); + mainLayout->addLayout(layouts[static_cast(Status::Away)], 2, 0); + mainLayout->addLayout(layouts[static_cast(Status::Busy)], 3, 0); + mainLayout->addLayout(layouts[static_cast(Status::Offline)], 4, 0); +} + +QLayout* FriendListWidget::getGroupLayout() +{ + return groupLayout; +} + +QLayout* FriendListWidget::getFriendLayout(Status s) +{ + auto res = layouts.find(static_cast(s)); + if (res != layouts.end()) + return res.value(); + + qDebug() << "Friend Status: " << static_cast(s) << " not found!"; + return layouts[static_cast(Status::Online)]; +} + +void FriendListWidget::moveWidget(QWidget *w, Status s) +{ + mainLayout->removeWidget(w); + getFriendLayout(s)->addWidget(w); +} diff --git a/widget/friendlistwidget.h b/widget/friendlistwidget.h new file mode 100644 index 000000000..02baa3f94 --- /dev/null +++ b/widget/friendlistwidget.h @@ -0,0 +1,44 @@ +/* + Copyright (C) 2014 by Project Tox + + 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. +*/ + +#ifndef FRIENDLISTWIDGET_H +#define FRIENDLISTWIDGET_H + +#include +#include +#include "core.h" + +class FriendListWidget : public QWidget +{ + Q_OBJECT +public: + explicit FriendListWidget(QWidget *parent = 0); + + QLayout* getGroupLayout(); + QLayout* getFriendLayout(Status s); + void moveWidget(QWidget *w, Status s); + +signals: + +public slots: + +private: + QHash layouts; + QLayout *groupLayout; + QGridLayout *mainLayout; +}; + +#endif // FRIENDLISTWIDGET_H diff --git a/widget/friendwidget.cpp b/widget/friendwidget.cpp index 84866e755..4840ed4a7 100644 --- a/widget/friendwidget.cpp +++ b/widget/friendwidget.cpp @@ -198,3 +198,8 @@ void FriendWidget::setAsInactiveChatroom() this->setPalette(pal3); avatar.setPixmap(QPixmap(":img/contact.png")); } + +int FriendWidget::isActive() +{ + return isActiveWidget; +} diff --git a/widget/friendwidget.h b/widget/friendwidget.h index 3fa37649a..71050d985 100644 --- a/widget/friendwidget.h +++ b/widget/friendwidget.h @@ -36,6 +36,7 @@ public: void leaveEvent(QEvent* event); void setAsActiveChatroom(); void setAsInactiveChatroom(); + int isActive(); signals: void friendWidgetClicked(FriendWidget* widget); diff --git a/widget/widget.cpp b/widget/widget.cpp index 1b102ef9b..2feb16d99 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -112,12 +112,8 @@ Widget::Widget(QWidget *parent) ui->mainHead->layout()->setMargin(0); ui->mainHead->layout()->setSpacing(0); - QWidget* friendListWidget = new QWidget(); - friendListWidget->setLayout(new QVBoxLayout()); - friendListWidget->layout()->setSpacing(0); - friendListWidget->layout()->setMargin(0); - friendListWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); - ui->friendList->setWidget(friendListWidget); + contactListWidget = new FriendListWidget(); + ui->friendList->setWidget(contactListWidget); ui->friendList->setLayoutDirection(Qt::RightToLeft); // delay setting username and message until Core inits @@ -414,8 +410,7 @@ void Widget::addFriend(int friendId, const QString &userId) { qDebug() << "Adding friend with id "+userId; Friend* newfriend = FriendList::addFriend(friendId, userId); - QWidget* widget = ui->friendList->widget(); - QLayout* layout = widget->layout(); + QLayout* layout = contactListWidget->getFriendLayout(Status::Offline); layout->addWidget(newfriend->widget); connect(newfriend->widget, SIGNAL(friendWidgetClicked(FriendWidget*)), this, SLOT(onFriendWidgetClicked(FriendWidget*))); connect(newfriend->widget, SIGNAL(removeFriend(int)), this, SLOT(removeFriend(int))); @@ -451,8 +446,14 @@ void Widget::onFriendStatusChanged(int friendId, Status status) if (!f) return; + contactListWidget->moveWidget(f->widget, status); + f->friendStatus = status; updateFriendStatusLights(friendId); + + // Workaround widget style after returning to list + if (f->widget->isActive()) + f->widget->setAsActiveChatroom(); } void Widget::onFriendStatusMessageChanged(int friendId, const QString& message) @@ -716,8 +717,7 @@ Group *Widget::createGroup(int groupId) QString groupName = QString("Groupchat #%1").arg(groupId); Group* newgroup = GroupList::addGroup(groupId, groupName); - QWidget* widget = ui->friendList->widget(); - QLayout* layout = widget->layout(); + QLayout* layout = contactListWidget->getGroupLayout(); layout->addWidget(newgroup->widget); if (!Settings::getInstance().getUseNativeDecoration()) newgroup->widget->statusPic.setPixmap(QPixmap(":img/status/dot_groupchat.png")); diff --git a/widget/widget.h b/widget/widget.h index a31e8e6f2..4b95fd800 100644 --- a/widget/widget.h +++ b/widget/widget.h @@ -27,6 +27,7 @@ #include "widget/form/settingsform.h" #include "widget/form/filesform.h" #include "camera.h" +#include "friendlistwidget.h" #define PIXELS_TO_ACT 7 @@ -143,6 +144,7 @@ private: static Widget* instance; FriendWidget* activeFriendWidget; GroupWidget* activeGroupWidget; + FriendListWidget* contactListWidget; int isFriendWidgetActive, isGroupWidgetActive; SelfCamView* camview; Camera* camera; From 07639865c93749eaa26231a388e65fccbb74a055 Mon Sep 17 00:00:00 2001 From: Ansa89 Date: Tue, 26 Aug 2014 14:13:04 +0200 Subject: [PATCH 075/149] Italian translation: update --- translations/it.qm | Bin 6228 -> 6234 bytes translations/it.ts | 8 ++++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/translations/it.qm b/translations/it.qm index 6577e1330a01501ebeca838e932bd1e1aea44a6b..b4f0e97a46ab9c29558276d37fd43d4b2fd0329d 100644 GIT binary patch delta 431 zcmX9)ODIH982+xg$2D{BJu^cLX1vC8iYSI=B^x3(9?6E}kugLb3-Val5H+UpwwQ&n zKr%HG3mYP77D^;hEEFqQu#h6ZoXvOsbH4xk{{Oo!xGR{?s62z@>H?yz$U063;>;-e z5dqya%7(pwxP+?WMZnO9_3vv!AABtgi0O&Yceeq?WKE^{i}=r;UX!g_T$x?~)X{(B z_u`s^YJHx#;})p-RopW-k=c)D*W_@plBx|L_KcNwWdMT0=43x0_c6D7hDfVyd-jC> ztJ%JvoHdt`uEZk}8}odd(#9nr{?F+`(q%3Kk>P*j6H@qPipF~I+J%%!yY^;l6OdN5 zkLm}YjOad>iU5`*+ph>U%}Pa11F`+eVB-@lk)XU~ACe_k+XMZ?zf*@o9#R+7bL$mZ zpAx=DEd00Gz>Fc})2Q2+?c? delta 421 zcmX9)T_}T57=Awcj?eae-|-idO_=|ysSUZ3n`yh8Bq@@gHbZLuE|lVis9E!`xUgLy zZDqMpn%u12NJesja^Xq}7fX>>&c%7&bI$WV&v~Ew+GOo=xjhES;{tMws5~zN^7CN* z5dqySn#TixxCTf4Dv;&I_IHwS6T96E$Q?+_9P9>spmgFEHyP40oK%@XWSiGQj z8#@V-v*s$@Qy3$$3IDggbW#!u{+!~Hu3{ZXPy8dFk`ga-^sT! ChatForm - + Send a file Invia un file - - + + Save chat log Salva il log della chat @@ -137,7 +137,7 @@ Transfered Files "Headline" of the window - Files inviati + Files Trasferiti
From 444972f214f50a9c3f2fbbb72f131cb59c6622ec Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Thu, 28 Aug 2014 12:12:56 +0200 Subject: [PATCH 076/149] Fix fileTransferFinsished not emitted on sender --- core.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core.cpp b/core.cpp index a9475071b..1b7f9f088 100644 --- a/core.cpp +++ b/core.cpp @@ -970,7 +970,7 @@ void Core::sendAllFileData(Core *core, ToxFile* file) { if (file->status == ToxFile::PAUSED) { - QThread::sleep(5); + QThread::sleep(1); continue; } else if (file->status == ToxFile::STOPPED) @@ -990,7 +990,7 @@ void Core::sendAllFileData(Core *core, ToxFile* file) removeFileFromQueue(true, file->friendId, file->fileNum); return; } - qDebug() << "chunkSize: " << chunkSize; + //qDebug() << "chunkSize: " << chunkSize; chunkSize = std::min(chunkSize, file->filesize); uint8_t* data = new uint8_t[chunkSize]; file->file->seek(file->bytesSent); @@ -1023,6 +1023,7 @@ void Core::sendAllFileData(Core *core, ToxFile* file) } qDebug("Core::fileHeartbeat: Transfer finished"); tox_file_send_control(core->tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_FINISHED, nullptr, 0); + emit core->fileTransferFinished(*file); } void Core::onAvInvite(void* _toxav, int32_t call_index, void* core) From c657296535573df4e797da18f7cea308397d7815 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Thu, 28 Aug 2014 12:52:04 +0200 Subject: [PATCH 077/149] Fix #152 and fix #131 We weren't reopening the audio input on subsequent calls --- core.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core.cpp b/core.cpp index 1b7f9f088..6e60004c9 100644 --- a/core.cpp +++ b/core.cpp @@ -1359,13 +1359,18 @@ void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled if (!QAudioDeviceInfo::defaultInputDevice().isFormatSupported(format)) { calls[callId].audioInput = nullptr; - qWarning() << "Default input format not supported, cannot record audio"; + qWarning() << "Core: Default input format not supported, cannot record audio"; } else if (calls[callId].audioInput==nullptr) { + qDebug() << "Core: Starting new audio input"; calls[callId].audioInput = new QAudioInput(format); calls[callId].audioInputDevice = calls[callId].audioInput->start(); } + else if (calls[callId].audioInput->state() == QAudio::StoppedState) + { + calls[callId].audioInputDevice = calls[callId].audioInput->start(); + } // Go calls[callId].active = true; From 8602327d16ff818882d11db55cdd37114ac6aeb1 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Thu, 28 Aug 2014 13:09:26 +0200 Subject: [PATCH 078/149] Term deadlocked threads on exit To prevent deadlocking the whole thing when we really just want to exit Qt w/ pulseaudio can deadlock internally on call start if it fails to connect to the PA context. Awesome. --- widget/widget.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/widget/widget.cpp b/widget/widget.cpp index 2feb16d99..9f56f21f7 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -219,7 +219,9 @@ Widget::~Widget() core->saveConfiguration(); instance = nullptr; coreThread->exit(); - coreThread->wait(); + coreThread->wait(500); // In case of deadlock (can happen with QtAudio/PA bugs) + if (!coreThread->isFinished()) + coreThread->terminate(); delete core; delete camview; From 287d50eea47af8d3cd4e6971bbd44d1ee99b0869 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Thu, 28 Aug 2014 14:30:38 +0200 Subject: [PATCH 079/149] Split core into core and coreav --- core.cpp | 504 ---------------------------------------------------- coreav.cpp | 512 +++++++++++++++++++++++++++++++++++++++++++++++++++++ qtox.pro | 3 +- 3 files changed, 514 insertions(+), 505 deletions(-) create mode 100644 coreav.cpp diff --git a/core.cpp b/core.cpp index 6e60004c9..7ad6d0a3c 100644 --- a/core.cpp +++ b/core.cpp @@ -34,10 +34,6 @@ const QString Core::CONFIG_FILE_NAME = "data"; QList Core::fileSendQueue; QList Core::fileRecvQueue; -ToxCall Core::calls[TOXAV_MAX_CALLS]; -const int Core::videobufsize{TOXAV_MAX_VIDEO_WIDTH * TOXAV_MAX_VIDEO_HEIGHT * 4}; -uint8_t* Core::videobuf; -int Core::videoBusyness; Core::Core(Camera* cam, QThread *coreThread) : tox(nullptr), camera(cam) @@ -1026,488 +1022,6 @@ void Core::sendAllFileData(Core *core, ToxFile* file) emit core->fileTransferFinished(*file); } -void Core::onAvInvite(void* _toxav, int32_t call_index, void* core) -{ - ToxAv* toxav = static_cast(_toxav); - - int friendId = toxav_get_peer_id(toxav, call_index, 0); - if (friendId < 0) - { - qWarning() << "Core: Received invalid AV invite"; - return; - } - - ToxAvCSettings* transSettings = new ToxAvCSettings; - int err = toxav_get_peer_csettings(toxav, call_index, 0, transSettings); - if (err != ErrorNone) - { - qWarning() << "Core::onAvInvite: error getting call type"; - delete transSettings; - return; - } - - if (transSettings->call_type == TypeVideo) - { - qDebug() << QString("Core: AV invite from %1 with video").arg(friendId); - emit static_cast(core)->avInvite(friendId, call_index, true); - } - else - { - qDebug() << QString("Core: AV invite from %1 without video").arg(friendId); - emit static_cast(core)->avInvite(friendId, call_index, false); - } - - delete transSettings; -} - -void Core::onAvStart(void* _toxav, int32_t call_index, void* core) -{ - ToxAv* toxav = static_cast(_toxav); - - int friendId = toxav_get_peer_id(toxav, call_index, 0); - if (friendId < 0) - { - qWarning() << "Core: Received invalid AV start"; - return; - } - - ToxAvCSettings* transSettings = new ToxAvCSettings; - int err = toxav_get_peer_csettings(toxav, call_index, 0, transSettings); - if (err != ErrorNone) - { - qWarning() << "Core::onAvStart: error getting call type"; - delete transSettings; - return; - } - - if (transSettings->call_type == TypeVideo) - { - qDebug() << QString("Core: AV start from %1 with video").arg(friendId); - prepareCall(friendId, call_index, toxav, true); - emit static_cast(core)->avStart(friendId, call_index, true); - } - else - { - qDebug() << QString("Core: AV start from %1 without video").arg(friendId); - prepareCall(friendId, call_index, toxav, false); - emit static_cast(core)->avStart(friendId, call_index, false); - } - - delete transSettings; -} - -void Core::onAvCancel(void* _toxav, int32_t call_index, void* core) -{ - ToxAv* toxav = static_cast(_toxav); - - int friendId = toxav_get_peer_id(toxav, call_index, 0); - if (friendId < 0) - { - qWarning() << "Core: Received invalid AV cancel"; - return; - } - qDebug() << QString("Core: AV cancel from %1").arg(friendId); - - emit static_cast(core)->avCancel(friendId, call_index); -} - -void Core::onAvReject(void*, int32_t, void*) -{ - qDebug() << "Core: AV reject"; -} - -void Core::onAvEnd(void* _toxav, int32_t call_index, void* core) -{ - ToxAv* toxav = static_cast(_toxav); - - int friendId = toxav_get_peer_id(toxav, call_index, 0); - if (friendId < 0) - { - qWarning() << "Core: Received invalid AV end"; - return; - } - qDebug() << QString("Core: AV end from %1").arg(friendId); - - cleanupCall(call_index); - - emit static_cast(core)->avEnd(friendId, call_index); -} - -void Core::onAvRinging(void* _toxav, int32_t call_index, void* core) -{ - ToxAv* toxav = static_cast(_toxav); - - int friendId = toxav_get_peer_id(toxav, call_index, 0); - if (friendId < 0) - { - qWarning() << "Core: Received invalid AV ringing"; - return; - } - - if (calls[call_index].videoEnabled) - { - qDebug() << QString("Core: AV ringing with %1 with video").arg(friendId); - emit static_cast(core)->avRinging(friendId, call_index, true); - } - else - { - qDebug() << QString("Core: AV ringing with %1 without video").arg(friendId); - emit static_cast(core)->avRinging(friendId, call_index, false); - } -} - -void Core::onAvStarting(void* _toxav, int32_t call_index, void* core) -{ - ToxAv* toxav = static_cast(_toxav); - - int friendId = toxav_get_peer_id(toxav, call_index, 0); - if (friendId < 0) - { - qWarning() << "Core: Received invalid AV starting"; - return; - } - - ToxAvCSettings* transSettings = new ToxAvCSettings; - int err = toxav_get_peer_csettings(toxav, call_index, 0, transSettings); - if (err != ErrorNone) - { - qWarning() << "Core::onAvStarting: error getting call type"; - delete transSettings; - return; - } - - if (transSettings->call_type == TypeVideo) - { - qDebug() << QString("Core: AV starting from %1 with video").arg(friendId); - prepareCall(friendId, call_index, toxav, true); - emit static_cast(core)->avStarting(friendId, call_index, true); - } - else - { - qDebug() << QString("Core: AV starting from %1 without video").arg(friendId); - prepareCall(friendId, call_index, toxav, false); - emit static_cast(core)->avStarting(friendId, call_index, false); - } - - delete transSettings; -} - -void Core::onAvEnding(void* _toxav, int32_t call_index, void* core) -{ - ToxAv* toxav = static_cast(_toxav); - - int friendId = toxav_get_peer_id(toxav, call_index, 0); - if (friendId < 0) - { - qWarning() << "Core: Received invalid AV ending"; - return; - } - qDebug() << QString("Core: AV ending from %1").arg(friendId); - - cleanupCall(call_index); - - emit static_cast(core)->avEnding(friendId, call_index); -} - -void Core::onAvRequestTimeout(void* _toxav, int32_t call_index, void* core) -{ - ToxAv* toxav = static_cast(_toxav); - - int friendId = toxav_get_peer_id(toxav, call_index, 0); - if (friendId < 0) - { - qWarning() << "Core: Received invalid AV request timeout"; - return; - } - qDebug() << QString("Core: AV request timeout with %1").arg(friendId); - - cleanupCall(call_index); - - emit static_cast(core)->avRequestTimeout(friendId, call_index); -} - -void Core::onAvPeerTimeout(void* _toxav, int32_t call_index, void* core) -{ - ToxAv* toxav = static_cast(_toxav); - - int friendId = toxav_get_peer_id(toxav, call_index, 0); - if (friendId < 0) - { - qWarning() << "Core: Received invalid AV peer timeout"; - return; - } - qDebug() << QString("Core: AV peer timeout with %1").arg(friendId); - - cleanupCall(call_index); - - emit static_cast(core)->avPeerTimeout(friendId, call_index); -} - -void Core::onAvMediaChange(void*, int32_t, void*) -{ - // HALP, PLS COMPLETE MEH - qWarning() << "If you see this, please complain on GitHub about seeing me! (Don't forget to say what caused me!)"; -} - -void Core::answerCall(int callId) -{ - int friendId = toxav_get_peer_id(toxav, callId, 0); - if (friendId < 0) - { - qWarning() << "Core: Received invalid AV answer peer ID"; - return; - } - - ToxAvCSettings* transSettings = new ToxAvCSettings; - int err = toxav_get_peer_csettings(toxav, callId, 0, transSettings); - if (err != ErrorNone) - { - qWarning() << "Core::answerCall: error getting call settings"; - delete transSettings; - return; - } - - if (transSettings->call_type == TypeVideo) - { - qDebug() << QString("Core: answering call %1 with video").arg(callId); - toxav_answer(toxav, callId, transSettings); - } - else - { - qDebug() << QString("Core: answering call %1 without video").arg(callId); - toxav_answer(toxav, callId, transSettings); - } - - delete transSettings; -} - -void Core::hangupCall(int callId) -{ - qDebug() << QString("Core: hanging up call %1").arg(callId); - calls[callId].active = false; - toxav_hangup(toxav, callId); -} - -void Core::startCall(int friendId, bool video) -{ - int callId; - ToxAvCSettings cSettings = av_DefaultSettings; - cSettings.max_video_width = TOXAV_MAX_VIDEO_WIDTH; - cSettings.max_video_height = TOXAV_MAX_VIDEO_HEIGHT; - if (video) - { - qDebug() << QString("Core: Starting new call with %1 with video").arg(friendId); - cSettings.call_type = TypeVideo; - toxav_call(toxav, &callId, friendId, &cSettings, TOXAV_RINGING_TIME); - calls[callId].videoEnabled=true; - } - else - { - qDebug() << QString("Core: Starting new call with %1 without video").arg(friendId); - cSettings.call_type = TypeAudio; - toxav_call(toxav, &callId, friendId, &cSettings, TOXAV_RINGING_TIME); - calls[callId].videoEnabled=false; - } -} - -void Core::cancelCall(int callId, int friendId) -{ - qDebug() << QString("Core: Cancelling call with %1").arg(friendId); - calls[callId].active = false; - toxav_cancel(toxav, callId, friendId, 0); -} - -void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled) -{ - qDebug() << QString("Core: preparing call %1").arg(callId); - calls[callId].callId = callId; - calls[callId].friendId = friendId; - // the following three lines are also now redundant from startCall, but are - // necessary there for outbound and here for inbound - calls[callId].codecSettings = av_DefaultSettings; - calls[callId].codecSettings.max_video_width = TOXAV_MAX_VIDEO_WIDTH; - calls[callId].codecSettings.max_video_height = TOXAV_MAX_VIDEO_HEIGHT; - calls[callId].videoEnabled = videoEnabled; - toxav_prepare_transmission(toxav, callId, av_jbufdc, av_VADd, videoEnabled); - - // Prepare output - QAudioFormat format; - format.setSampleRate(calls[callId].codecSettings.audio_sample_rate); - format.setChannelCount(calls[callId].codecSettings.audio_channels); - format.setSampleSize(16); - format.setCodec("audio/pcm"); - format.setByteOrder(QAudioFormat::LittleEndian); - format.setSampleType(QAudioFormat::SignedInt); - if (!QAudioDeviceInfo::defaultOutputDevice().isFormatSupported(format)) - { - calls[callId].audioOutput = nullptr; - qWarning() << "Core: Raw audio format not supported by output backend, cannot play audio."; - } - else if (calls[callId].audioOutput==nullptr) - { - calls[callId].audioOutput = new QAudioOutput(format); - calls[callId].audioOutput->setBufferSize(1900*30); // Make this bigger to get less underflows, but more latency - calls[callId].audioOutput->start(&calls[callId].audioBuffer); - int error = calls[callId].audioOutput->error(); - if (error != QAudio::NoError) - { - qWarning() << QString("Core: Error %1 when starting audio output").arg(error); - } - } - - // Start input - if (!QAudioDeviceInfo::defaultInputDevice().isFormatSupported(format)) - { - calls[callId].audioInput = nullptr; - qWarning() << "Core: Default input format not supported, cannot record audio"; - } - else if (calls[callId].audioInput==nullptr) - { - qDebug() << "Core: Starting new audio input"; - calls[callId].audioInput = new QAudioInput(format); - calls[callId].audioInputDevice = calls[callId].audioInput->start(); - } - else if (calls[callId].audioInput->state() == QAudio::StoppedState) - { - calls[callId].audioInputDevice = calls[callId].audioInput->start(); - } - - // Go - calls[callId].active = true; - - if (calls[callId].audioInput != nullptr) - { - calls[callId].sendAudioTimer->setInterval(2); - calls[callId].sendAudioTimer->setSingleShot(true); - connect(calls[callId].sendAudioTimer, &QTimer::timeout, [=](){sendCallAudio(callId,toxav);}); - calls[callId].sendAudioTimer->start(); - } - - if (calls[callId].videoEnabled) - { - calls[callId].sendVideoTimer->setInterval(50); - calls[callId].sendVideoTimer->setSingleShot(true); - calls[callId].sendVideoTimer->start(); - - Widget::getInstance()->getCamera()->suscribe(); - } - else if (calls[callId].audioInput == nullptr && calls[callId].audioOutput == nullptr) - { - qWarning() << "Audio only call can neither play nor record audio, killing call"; - toxav_hangup(toxav, callId); - } -} - -void Core::cleanupCall(int callId) -{ - qDebug() << QString("Core: cleaning up call %1").arg(callId); - calls[callId].active = false; - disconnect(calls[callId].sendAudioTimer,0,0,0); - calls[callId].sendAudioTimer->stop(); - calls[callId].sendVideoTimer->stop(); - if (calls[callId].audioOutput != nullptr) - { - calls[callId].audioOutput->stop(); - } - if (calls[callId].audioInput != nullptr) - { - calls[callId].audioInput->stop(); - } - if (calls[callId].videoEnabled) - Widget::getInstance()->getCamera()->unsuscribe(); - calls[callId].audioBuffer.clear(); -} - -void Core::playCallAudio(ToxAv*, int32_t callId, int16_t *data, int length, void *user_data) -{ - Q_UNUSED(user_data); - - if (!calls[callId].active || calls[callId].audioOutput == nullptr) - return; - calls[callId].audioBuffer.write((char*)data, length*2); - int state = calls[callId].audioOutput->state(); - if (state != QAudio::ActiveState) - { - qDebug() << QString("Core: Audio state is %1").arg(state); - calls[callId].audioOutput->start(&calls[callId].audioBuffer); - } - int error = calls[callId].audioOutput->error(); - if (error != QAudio::NoError) - qWarning() << QString("Core::playCallAudio: Error: %1").arg(error); -} - -void Core::sendCallAudio(int callId, ToxAv* toxav) -{ - if (!calls[callId].active || calls[callId].audioInput == nullptr) - return; - int framesize = (calls[callId].codecSettings.audio_frame_duration * calls[callId].codecSettings.audio_sample_rate) / 1000; - uint8_t buf[framesize*2], dest[framesize*2]; - int bytesReady = calls[callId].audioInput->bytesReady(); - if (bytesReady >= framesize*2) - { - calls[callId].audioInputDevice->read((char*)buf, framesize*2); - int result = toxav_prepare_audio_frame(toxav, callId, dest, framesize*2, (int16_t*)buf, framesize); - if (result < 0) - { - qWarning() << QString("Core: Unable to prepare audio frame, error %1").arg(result); - calls[callId].sendAudioTimer->start(); - return; - } - result = toxav_send_audio(toxav, callId, dest, result); - if (result < 0) - { - qWarning() << QString("Core: Unable to send audio frame, error %1").arg(result); - calls[callId].sendAudioTimer->start(); - return; - } - calls[callId].sendAudioTimer->start(); - } - else - calls[callId].sendAudioTimer->start(); -} - -void Core::playCallVideo(ToxAv*, int32_t callId, vpx_image_t* img, void *user_data) -{ - Q_UNUSED(user_data); - - if (!calls[callId].active || !calls[callId].videoEnabled) - return; - - if (videoBusyness >= 1) - qWarning() << "Core: playCallVideo: Busy, dropping current frame"; - else - emit Widget::getInstance()->getCore()->videoFrameReceived(img); - vpx_img_free(img); -} - -void Core::sendCallVideo(int callId) -{ - if (!calls[callId].active || !calls[callId].videoEnabled) - return; - - vpx_image frame = camera->getLastVPXImage(); - if (frame.w && frame.h) - { - int result; - if((result = toxav_prepare_video_frame(toxav, callId, videobuf, videobufsize, &frame)) < 0) - { - qDebug() << QString("Core: toxav_prepare_video_frame: error %1").arg(result); - vpx_img_free(&frame); - calls[callId].sendVideoTimer->start(); - return; - } - - if((result = toxav_send_video(toxav, callId, (uint8_t*)videobuf, result)) < 0) - qDebug() << QString("Core: toxav_send_video error: %1").arg(result); - - vpx_img_free(&frame); - } - else - qDebug("Core::sendCallVideo: Invalid frame (bad camera ?)"); - - calls[callId].sendVideoTimer->start(); -} - void Core::groupInviteFriend(int friendId, int groupId) { tox_invite_friend(tox, friendId, groupId); @@ -1517,21 +1031,3 @@ void Core::createGroup() { emit emptyGroupCreated(tox_add_groupchat(tox)); } - -void Core::increaseVideoBusyness() -{ - videoBusyness++; -} - -void Core::decreaseVideoBusyness() -{ - videoBusyness--; -} - -void Core::micMuteToggle(int callId) -{ - if (calls[callId].audioInput->state() == QAudio::ActiveState) - calls[callId].audioInput->suspend(); - else - calls[callId].audioInput->start(); -} diff --git a/coreav.cpp b/coreav.cpp new file mode 100644 index 000000000..99be2a286 --- /dev/null +++ b/coreav.cpp @@ -0,0 +1,512 @@ +#include "core.h" +#include "widget/widget.h" + +#include +#include + +ToxCall Core::calls[TOXAV_MAX_CALLS]; +const int Core::videobufsize{TOXAV_MAX_VIDEO_WIDTH * TOXAV_MAX_VIDEO_HEIGHT * 4}; +uint8_t* Core::videobuf; +int Core::videoBusyness; + +void Core::onAvMediaChange(void*, int32_t, void*) +{ + // HALP, PLS COMPLETE MEH + qWarning() << "If you see this, please complain on GitHub about seeing me! (Don't forget to say what caused me!)"; +} + +void Core::answerCall(int callId) +{ + int friendId = toxav_get_peer_id(toxav, callId, 0); + if (friendId < 0) + { + qWarning() << "Core: Received invalid AV answer peer ID"; + return; + } + + ToxAvCSettings* transSettings = new ToxAvCSettings; + int err = toxav_get_peer_csettings(toxav, callId, 0, transSettings); + if (err != ErrorNone) + { + qWarning() << "Core::answerCall: error getting call settings"; + delete transSettings; + return; + } + + if (transSettings->call_type == TypeVideo) + { + qDebug() << QString("Core: answering call %1 with video").arg(callId); + toxav_answer(toxav, callId, transSettings); + } + else + { + qDebug() << QString("Core: answering call %1 without video").arg(callId); + toxav_answer(toxav, callId, transSettings); + } + + delete transSettings; +} + +void Core::hangupCall(int callId) +{ + qDebug() << QString("Core: hanging up call %1").arg(callId); + calls[callId].active = false; + toxav_hangup(toxav, callId); +} + +void Core::startCall(int friendId, bool video) +{ + int callId; + ToxAvCSettings cSettings = av_DefaultSettings; + cSettings.max_video_width = TOXAV_MAX_VIDEO_WIDTH; + cSettings.max_video_height = TOXAV_MAX_VIDEO_HEIGHT; + if (video) + { + qDebug() << QString("Core: Starting new call with %1 with video").arg(friendId); + cSettings.call_type = TypeVideo; + toxav_call(toxav, &callId, friendId, &cSettings, TOXAV_RINGING_TIME); + calls[callId].videoEnabled=true; + } + else + { + qDebug() << QString("Core: Starting new call with %1 without video").arg(friendId); + cSettings.call_type = TypeAudio; + toxav_call(toxav, &callId, friendId, &cSettings, TOXAV_RINGING_TIME); + calls[callId].videoEnabled=false; + } +} + +void Core::cancelCall(int callId, int friendId) +{ + qDebug() << QString("Core: Cancelling call with %1").arg(friendId); + calls[callId].active = false; + toxav_cancel(toxav, callId, friendId, 0); +} + +void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled) +{ + qDebug() << QString("Core: preparing call %1").arg(callId); + calls[callId].callId = callId; + calls[callId].friendId = friendId; + // the following three lines are also now redundant from startCall, but are + // necessary there for outbound and here for inbound + calls[callId].codecSettings = av_DefaultSettings; + calls[callId].codecSettings.max_video_width = TOXAV_MAX_VIDEO_WIDTH; + calls[callId].codecSettings.max_video_height = TOXAV_MAX_VIDEO_HEIGHT; + calls[callId].videoEnabled = videoEnabled; + toxav_prepare_transmission(toxav, callId, av_jbufdc, av_VADd, videoEnabled); + + // Prepare output + QAudioFormat format; + format.setSampleRate(calls[callId].codecSettings.audio_sample_rate); + format.setChannelCount(calls[callId].codecSettings.audio_channels); + format.setSampleSize(16); + format.setCodec("audio/pcm"); + format.setByteOrder(QAudioFormat::LittleEndian); + format.setSampleType(QAudioFormat::SignedInt); + if (!QAudioDeviceInfo::defaultOutputDevice().isFormatSupported(format)) + { + calls[callId].audioOutput = nullptr; + qWarning() << "Core: Raw audio format not supported by output backend, cannot play audio."; + } + else if (calls[callId].audioOutput==nullptr) + { + calls[callId].audioOutput = new QAudioOutput(format); + calls[callId].audioOutput->setBufferSize(1900*30); // Make this bigger to get less underflows, but more latency + calls[callId].audioOutput->start(&calls[callId].audioBuffer); + int error = calls[callId].audioOutput->error(); + if (error != QAudio::NoError) + { + qWarning() << QString("Core: Error %1 when starting audio output").arg(error); + } + } + + // Start input + if (!QAudioDeviceInfo::defaultInputDevice().isFormatSupported(format)) + { + calls[callId].audioInput = nullptr; + qWarning() << "Core: Default input format not supported, cannot record audio"; + } + else if (calls[callId].audioInput==nullptr) + { + qDebug() << "Core: Starting new audio input"; + calls[callId].audioInput = new QAudioInput(format); + calls[callId].audioInputDevice = calls[callId].audioInput->start(); + } + else if (calls[callId].audioInput->state() == QAudio::StoppedState) + { + calls[callId].audioInputDevice = calls[callId].audioInput->start(); + } + + // Go + calls[callId].active = true; + + if (calls[callId].audioInput != nullptr) + { + calls[callId].sendAudioTimer->setInterval(2); + calls[callId].sendAudioTimer->setSingleShot(true); + connect(calls[callId].sendAudioTimer, &QTimer::timeout, [=](){sendCallAudio(callId,toxav);}); + calls[callId].sendAudioTimer->start(); + } + + if (calls[callId].videoEnabled) + { + calls[callId].sendVideoTimer->setInterval(50); + calls[callId].sendVideoTimer->setSingleShot(true); + calls[callId].sendVideoTimer->start(); + + Widget::getInstance()->getCamera()->suscribe(); + } + else if (calls[callId].audioInput == nullptr && calls[callId].audioOutput == nullptr) + { + qWarning() << "Audio only call can neither play nor record audio, killing call"; + toxav_hangup(toxav, callId); + } +} + +void Core::cleanupCall(int callId) +{ + qDebug() << QString("Core: cleaning up call %1").arg(callId); + calls[callId].active = false; + disconnect(calls[callId].sendAudioTimer,0,0,0); + calls[callId].sendAudioTimer->stop(); + calls[callId].sendVideoTimer->stop(); + if (calls[callId].audioOutput != nullptr) + { + calls[callId].audioOutput->stop(); + } + if (calls[callId].audioInput != nullptr) + { + calls[callId].audioInput->stop(); + } + if (calls[callId].videoEnabled) + Widget::getInstance()->getCamera()->unsuscribe(); + calls[callId].audioBuffer.clear(); +} + +void Core::playCallAudio(ToxAv*, int32_t callId, int16_t *data, int length, void *user_data) +{ + Q_UNUSED(user_data); + + if (!calls[callId].active || calls[callId].audioOutput == nullptr) + return; + calls[callId].audioBuffer.write((char*)data, length*2); + int state = calls[callId].audioOutput->state(); + if (state != QAudio::ActiveState) + { + qDebug() << QString("Core: Audio state is %1").arg(state); + calls[callId].audioOutput->start(&calls[callId].audioBuffer); + } + int error = calls[callId].audioOutput->error(); + if (error != QAudio::NoError) + qWarning() << QString("Core::playCallAudio: Error: %1").arg(error); +} + +void Core::sendCallAudio(int callId, ToxAv* toxav) +{ + if (!calls[callId].active || calls[callId].audioInput == nullptr) + return; + int framesize = (calls[callId].codecSettings.audio_frame_duration * calls[callId].codecSettings.audio_sample_rate) / 1000; + uint8_t buf[framesize*2], dest[framesize*2]; + int bytesReady = calls[callId].audioInput->bytesReady(); + if (bytesReady >= framesize*2) + { + calls[callId].audioInputDevice->read((char*)buf, framesize*2); + int result = toxav_prepare_audio_frame(toxav, callId, dest, framesize*2, (int16_t*)buf, framesize); + if (result < 0) + { + qWarning() << QString("Core: Unable to prepare audio frame, error %1").arg(result); + calls[callId].sendAudioTimer->start(); + return; + } + result = toxav_send_audio(toxav, callId, dest, result); + if (result < 0) + { + qWarning() << QString("Core: Unable to send audio frame, error %1").arg(result); + calls[callId].sendAudioTimer->start(); + return; + } + calls[callId].sendAudioTimer->start(); + } + else + calls[callId].sendAudioTimer->start(); +} + +void Core::playCallVideo(ToxAv*, int32_t callId, vpx_image_t* img, void *user_data) +{ + Q_UNUSED(user_data); + + if (!calls[callId].active || !calls[callId].videoEnabled) + return; + + if (videoBusyness >= 1) + qWarning() << "Core: playCallVideo: Busy, dropping current frame"; + else + emit Widget::getInstance()->getCore()->videoFrameReceived(img); + vpx_img_free(img); +} + +void Core::sendCallVideo(int callId) +{ + if (!calls[callId].active || !calls[callId].videoEnabled) + return; + + vpx_image frame = camera->getLastVPXImage(); + if (frame.w && frame.h) + { + int result; + if((result = toxav_prepare_video_frame(toxav, callId, videobuf, videobufsize, &frame)) < 0) + { + qDebug() << QString("Core: toxav_prepare_video_frame: error %1").arg(result); + vpx_img_free(&frame); + calls[callId].sendVideoTimer->start(); + return; + } + + if((result = toxav_send_video(toxav, callId, (uint8_t*)videobuf, result)) < 0) + qDebug() << QString("Core: toxav_send_video error: %1").arg(result); + + vpx_img_free(&frame); + } + else + qDebug("Core::sendCallVideo: Invalid frame (bad camera ?)"); + + calls[callId].sendVideoTimer->start(); +} + + +void Core::increaseVideoBusyness() +{ + videoBusyness++; +} + +void Core::decreaseVideoBusyness() +{ + videoBusyness--; +} + +void Core::micMuteToggle(int callId) +{ + if (calls[callId].audioInput->state() == QAudio::ActiveState) + calls[callId].audioInput->suspend(); + else + calls[callId].audioInput->start(); +} + +void Core::onAvCancel(void* _toxav, int32_t call_index, void* core) +{ + ToxAv* toxav = static_cast(_toxav); + + int friendId = toxav_get_peer_id(toxav, call_index, 0); + if (friendId < 0) + { + qWarning() << "Core: Received invalid AV cancel"; + return; + } + qDebug() << QString("Core: AV cancel from %1").arg(friendId); + + emit static_cast(core)->avCancel(friendId, call_index); +} + +void Core::onAvReject(void*, int32_t, void*) +{ + qDebug() << "Core: AV reject"; +} + +void Core::onAvEnd(void* _toxav, int32_t call_index, void* core) +{ + ToxAv* toxav = static_cast(_toxav); + + int friendId = toxav_get_peer_id(toxav, call_index, 0); + if (friendId < 0) + { + qWarning() << "Core: Received invalid AV end"; + return; + } + qDebug() << QString("Core: AV end from %1").arg(friendId); + + cleanupCall(call_index); + + emit static_cast(core)->avEnd(friendId, call_index); +} + +void Core::onAvRinging(void* _toxav, int32_t call_index, void* core) +{ + ToxAv* toxav = static_cast(_toxav); + + int friendId = toxav_get_peer_id(toxav, call_index, 0); + if (friendId < 0) + { + qWarning() << "Core: Received invalid AV ringing"; + return; + } + + if (calls[call_index].videoEnabled) + { + qDebug() << QString("Core: AV ringing with %1 with video").arg(friendId); + emit static_cast(core)->avRinging(friendId, call_index, true); + } + else + { + qDebug() << QString("Core: AV ringing with %1 without video").arg(friendId); + emit static_cast(core)->avRinging(friendId, call_index, false); + } +} + +void Core::onAvStarting(void* _toxav, int32_t call_index, void* core) +{ + ToxAv* toxav = static_cast(_toxav); + + int friendId = toxav_get_peer_id(toxav, call_index, 0); + if (friendId < 0) + { + qWarning() << "Core: Received invalid AV starting"; + return; + } + + ToxAvCSettings* transSettings = new ToxAvCSettings; + int err = toxav_get_peer_csettings(toxav, call_index, 0, transSettings); + if (err != ErrorNone) + { + qWarning() << "Core::onAvStarting: error getting call type"; + delete transSettings; + return; + } + + if (transSettings->call_type == TypeVideo) + { + qDebug() << QString("Core: AV starting from %1 with video").arg(friendId); + prepareCall(friendId, call_index, toxav, true); + emit static_cast(core)->avStarting(friendId, call_index, true); + } + else + { + qDebug() << QString("Core: AV starting from %1 without video").arg(friendId); + prepareCall(friendId, call_index, toxav, false); + emit static_cast(core)->avStarting(friendId, call_index, false); + } + + delete transSettings; +} + +void Core::onAvEnding(void* _toxav, int32_t call_index, void* core) +{ + ToxAv* toxav = static_cast(_toxav); + + int friendId = toxav_get_peer_id(toxav, call_index, 0); + if (friendId < 0) + { + qWarning() << "Core: Received invalid AV ending"; + return; + } + qDebug() << QString("Core: AV ending from %1").arg(friendId); + + cleanupCall(call_index); + + emit static_cast(core)->avEnding(friendId, call_index); +} + +void Core::onAvRequestTimeout(void* _toxav, int32_t call_index, void* core) +{ + ToxAv* toxav = static_cast(_toxav); + + int friendId = toxav_get_peer_id(toxav, call_index, 0); + if (friendId < 0) + { + qWarning() << "Core: Received invalid AV request timeout"; + return; + } + qDebug() << QString("Core: AV request timeout with %1").arg(friendId); + + cleanupCall(call_index); + + emit static_cast(core)->avRequestTimeout(friendId, call_index); +} + +void Core::onAvPeerTimeout(void* _toxav, int32_t call_index, void* core) +{ + ToxAv* toxav = static_cast(_toxav); + + int friendId = toxav_get_peer_id(toxav, call_index, 0); + if (friendId < 0) + { + qWarning() << "Core: Received invalid AV peer timeout"; + return; + } + qDebug() << QString("Core: AV peer timeout with %1").arg(friendId); + + cleanupCall(call_index); + + emit static_cast(core)->avPeerTimeout(friendId, call_index); +} + + +void Core::onAvInvite(void* _toxav, int32_t call_index, void* core) +{ + ToxAv* toxav = static_cast(_toxav); + + int friendId = toxav_get_peer_id(toxav, call_index, 0); + if (friendId < 0) + { + qWarning() << "Core: Received invalid AV invite"; + return; + } + + ToxAvCSettings* transSettings = new ToxAvCSettings; + int err = toxav_get_peer_csettings(toxav, call_index, 0, transSettings); + if (err != ErrorNone) + { + qWarning() << "Core::onAvInvite: error getting call type"; + delete transSettings; + return; + } + + if (transSettings->call_type == TypeVideo) + { + qDebug() << QString("Core: AV invite from %1 with video").arg(friendId); + emit static_cast(core)->avInvite(friendId, call_index, true); + } + else + { + qDebug() << QString("Core: AV invite from %1 without video").arg(friendId); + emit static_cast(core)->avInvite(friendId, call_index, false); + } + + delete transSettings; +} + +void Core::onAvStart(void* _toxav, int32_t call_index, void* core) +{ + ToxAv* toxav = static_cast(_toxav); + + int friendId = toxav_get_peer_id(toxav, call_index, 0); + if (friendId < 0) + { + qWarning() << "Core: Received invalid AV start"; + return; + } + + ToxAvCSettings* transSettings = new ToxAvCSettings; + int err = toxav_get_peer_csettings(toxav, call_index, 0, transSettings); + if (err != ErrorNone) + { + qWarning() << "Core::onAvStart: error getting call type"; + delete transSettings; + return; + } + + if (transSettings->call_type == TypeVideo) + { + qDebug() << QString("Core: AV start from %1 with video").arg(friendId); + prepareCall(friendId, call_index, toxav, true); + emit static_cast(core)->avStart(friendId, call_index, true); + } + else + { + qDebug() << QString("Core: AV start from %1 without video").arg(friendId); + prepareCall(friendId, call_index, toxav, false); + emit static_cast(core)->avStart(friendId, call_index, false); + } + + delete transSettings; +} diff --git a/qtox.pro b/qtox.pro index 84ec1e54e..f52023936 100644 --- a/qtox.pro +++ b/qtox.pro @@ -128,4 +128,5 @@ SOURCES += \ style.cpp \ widget/adjustingscrollarea.cpp \ widget/croppinglabel.cpp \ - widget/friendlistwidget.cpp + widget/friendlistwidget.cpp \ + coreav.cpp From 1c44f7fdf474299c070a48446fab635707567561 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Thu, 28 Aug 2014 15:46:11 +0200 Subject: [PATCH 080/149] OpenAL init and output No cleanup yet! --- core.h | 11 ++- coreav.cpp | 241 ++++++++++++++++++++++++++++++++--------------------- qtox.pro | 4 +- 3 files changed, 157 insertions(+), 99 deletions(-) diff --git a/core.h b/core.h index b07f9a60e..d80c00935 100644 --- a/core.h +++ b/core.h @@ -22,6 +22,9 @@ #include #include +#include +#include + #include #include #include @@ -106,6 +109,9 @@ public: int friendId; bool videoEnabled; bool active; + ALCdevice* alOutDev, *alInDev; + ALCcontext* alContext; + ALuint alSource; }; class Core : public QObject @@ -268,8 +274,9 @@ private: static void prepareCall(int friendId, int callId, ToxAv *toxav, bool videoEnabled); static void cleanupCall(int callId); - static void playCallAudio(ToxAv *toxav, int32_t callId, int16_t *data, int length, void *user_data); // Callback + static void playCallAudio(ToxAv *toxav, int32_t callId, int16_t *data, int samples, void *user_data); // Callback static void sendCallAudio(int callId, ToxAv* toxav); + static void playAudioBuffer(int callId, int16_t *data, int samples); static void playCallVideo(ToxAv* toxav, int32_t callId, vpx_image_t* img, void *user_data); void sendCallVideo(int callId); @@ -278,8 +285,8 @@ private: void loadConfiguration(); void loadFriends(); - static void sendAllFileData(Core* core, ToxFile* file); + static void sendAllFileData(Core* core, ToxFile* file); static void removeFileFromQueue(bool sendQueue, int friendId, int fileId); void checkLastOnline(int friendId); diff --git a/coreav.cpp b/coreav.cpp index 99be2a286..be380c47e 100644 --- a/coreav.cpp +++ b/coreav.cpp @@ -1,14 +1,110 @@ #include "core.h" #include "widget/widget.h" -#include -#include - ToxCall Core::calls[TOXAV_MAX_CALLS]; const int Core::videobufsize{TOXAV_MAX_VIDEO_WIDTH * TOXAV_MAX_VIDEO_HEIGHT * 4}; uint8_t* Core::videobuf; int Core::videoBusyness; +void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled) +{ + qDebug() << QString("Core: preparing call %1").arg(callId); + calls[callId].callId = callId; + calls[callId].friendId = friendId; + // the following three lines are also now redundant from startCall, but are + // necessary there for outbound and here for inbound + calls[callId].codecSettings = av_DefaultSettings; + calls[callId].codecSettings.max_video_width = TOXAV_MAX_VIDEO_WIDTH; + calls[callId].codecSettings.max_video_height = TOXAV_MAX_VIDEO_HEIGHT; + calls[callId].videoEnabled = videoEnabled; + toxav_prepare_transmission(toxav, callId, av_jbufdc, av_VADd, videoEnabled); + + // Audio output + calls[callId].alOutDev = alcOpenDevice(nullptr); + if (!calls[callId].alOutDev) + { + qWarning() << "Coreav: Cannot open output audio device, hanging up call"; + toxav_hangup(toxav, callId); + return; + } + calls[callId].alContext=alcCreateContext(calls[callId].alOutDev,nullptr); + if (!alcMakeContextCurrent(calls[callId].alContext)) + { + qWarning() << "Coreav: Cannot create output audio context, hanging up call"; + alcCloseDevice(calls[callId].alOutDev); + toxav_hangup(toxav, callId); + return; + } + alGenSources(1, &calls[callId].alSource); + + // Prepare output + QAudioFormat format; + format.setSampleRate(calls[callId].codecSettings.audio_sample_rate); + format.setChannelCount(calls[callId].codecSettings.audio_channels); + format.setSampleSize(16); + format.setCodec("audio/pcm"); + format.setByteOrder(QAudioFormat::LittleEndian); + format.setSampleType(QAudioFormat::SignedInt); + if (!QAudioDeviceInfo::defaultOutputDevice().isFormatSupported(format)) + { + calls[callId].audioOutput = nullptr; + qWarning() << "Core: Raw audio format not supported by output backend, cannot play audio."; + } + else if (calls[callId].audioOutput==nullptr) + { + calls[callId].audioOutput = new QAudioOutput(format); + calls[callId].audioOutput->setBufferSize(1900*30); // Make this bigger to get less underflows, but more latency + calls[callId].audioOutput->start(&calls[callId].audioBuffer); + int error = calls[callId].audioOutput->error(); + if (error != QAudio::NoError) + { + qWarning() << QString("Core: Error %1 when starting audio output").arg(error); + } + } + + // Start input + if (!QAudioDeviceInfo::defaultInputDevice().isFormatSupported(format)) + { + calls[callId].audioInput = nullptr; + qWarning() << "Core: Default input format not supported, cannot record audio"; + } + else if (calls[callId].audioInput==nullptr) + { + qDebug() << "Core: Starting new audio input"; + calls[callId].audioInput = new QAudioInput(format); + calls[callId].audioInputDevice = calls[callId].audioInput->start(); + } + else if (calls[callId].audioInput->state() == QAudio::StoppedState) + { + calls[callId].audioInputDevice = calls[callId].audioInput->start(); + } + + // Go + calls[callId].active = true; + + if (calls[callId].audioInput != nullptr) + { + calls[callId].sendAudioTimer->setInterval(2); + calls[callId].sendAudioTimer->setSingleShot(true); + connect(calls[callId].sendAudioTimer, &QTimer::timeout, [=](){sendCallAudio(callId,toxav);}); + calls[callId].sendAudioTimer->start(); + } + + if (calls[callId].videoEnabled) + { + calls[callId].sendVideoTimer->setInterval(50); + calls[callId].sendVideoTimer->setSingleShot(true); + calls[callId].sendVideoTimer->start(); + + Widget::getInstance()->getCamera()->suscribe(); + } + else if (calls[callId].audioInput == nullptr && calls[callId].audioOutput == nullptr) + { + qWarning() << "Audio only call can neither play nor record audio, killing call"; + toxav_hangup(toxav, callId); + } +} + void Core::onAvMediaChange(void*, int32_t, void*) { // HALP, PLS COMPLETE MEH @@ -83,87 +179,6 @@ void Core::cancelCall(int callId, int friendId) toxav_cancel(toxav, callId, friendId, 0); } -void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled) -{ - qDebug() << QString("Core: preparing call %1").arg(callId); - calls[callId].callId = callId; - calls[callId].friendId = friendId; - // the following three lines are also now redundant from startCall, but are - // necessary there for outbound and here for inbound - calls[callId].codecSettings = av_DefaultSettings; - calls[callId].codecSettings.max_video_width = TOXAV_MAX_VIDEO_WIDTH; - calls[callId].codecSettings.max_video_height = TOXAV_MAX_VIDEO_HEIGHT; - calls[callId].videoEnabled = videoEnabled; - toxav_prepare_transmission(toxav, callId, av_jbufdc, av_VADd, videoEnabled); - - // Prepare output - QAudioFormat format; - format.setSampleRate(calls[callId].codecSettings.audio_sample_rate); - format.setChannelCount(calls[callId].codecSettings.audio_channels); - format.setSampleSize(16); - format.setCodec("audio/pcm"); - format.setByteOrder(QAudioFormat::LittleEndian); - format.setSampleType(QAudioFormat::SignedInt); - if (!QAudioDeviceInfo::defaultOutputDevice().isFormatSupported(format)) - { - calls[callId].audioOutput = nullptr; - qWarning() << "Core: Raw audio format not supported by output backend, cannot play audio."; - } - else if (calls[callId].audioOutput==nullptr) - { - calls[callId].audioOutput = new QAudioOutput(format); - calls[callId].audioOutput->setBufferSize(1900*30); // Make this bigger to get less underflows, but more latency - calls[callId].audioOutput->start(&calls[callId].audioBuffer); - int error = calls[callId].audioOutput->error(); - if (error != QAudio::NoError) - { - qWarning() << QString("Core: Error %1 when starting audio output").arg(error); - } - } - - // Start input - if (!QAudioDeviceInfo::defaultInputDevice().isFormatSupported(format)) - { - calls[callId].audioInput = nullptr; - qWarning() << "Core: Default input format not supported, cannot record audio"; - } - else if (calls[callId].audioInput==nullptr) - { - qDebug() << "Core: Starting new audio input"; - calls[callId].audioInput = new QAudioInput(format); - calls[callId].audioInputDevice = calls[callId].audioInput->start(); - } - else if (calls[callId].audioInput->state() == QAudio::StoppedState) - { - calls[callId].audioInputDevice = calls[callId].audioInput->start(); - } - - // Go - calls[callId].active = true; - - if (calls[callId].audioInput != nullptr) - { - calls[callId].sendAudioTimer->setInterval(2); - calls[callId].sendAudioTimer->setSingleShot(true); - connect(calls[callId].sendAudioTimer, &QTimer::timeout, [=](){sendCallAudio(callId,toxav);}); - calls[callId].sendAudioTimer->start(); - } - - if (calls[callId].videoEnabled) - { - calls[callId].sendVideoTimer->setInterval(50); - calls[callId].sendVideoTimer->setSingleShot(true); - calls[callId].sendVideoTimer->start(); - - Widget::getInstance()->getCamera()->suscribe(); - } - else if (calls[callId].audioInput == nullptr && calls[callId].audioOutput == nullptr) - { - qWarning() << "Audio only call can neither play nor record audio, killing call"; - toxav_hangup(toxav, callId); - } -} - void Core::cleanupCall(int callId) { qDebug() << QString("Core: cleaning up call %1").arg(callId); @@ -184,22 +199,14 @@ void Core::cleanupCall(int callId) calls[callId].audioBuffer.clear(); } -void Core::playCallAudio(ToxAv*, int32_t callId, int16_t *data, int length, void *user_data) +void Core::playCallAudio(ToxAv*, int32_t callId, int16_t *data, int samples, void *user_data) { Q_UNUSED(user_data); if (!calls[callId].active || calls[callId].audioOutput == nullptr) return; - calls[callId].audioBuffer.write((char*)data, length*2); - int state = calls[callId].audioOutput->state(); - if (state != QAudio::ActiveState) - { - qDebug() << QString("Core: Audio state is %1").arg(state); - calls[callId].audioOutput->start(&calls[callId].audioBuffer); - } - int error = calls[callId].audioOutput->error(); - if (error != QAudio::NoError) - qWarning() << QString("Core::playCallAudio: Error: %1").arg(error); + + playAudioBuffer(callId, data, samples); } void Core::sendCallAudio(int callId, ToxAv* toxav) @@ -510,3 +517,47 @@ void Core::onAvStart(void* _toxav, int32_t call_index, void* core) delete transSettings; } + +void Core::playAudioBuffer(int callId, int16_t *data, int samples) +{ + unsigned channels = calls[callId].codecSettings.audio_channels; + if(!channels || channels > 2) { + qWarning() << "Core::playAudioBuffer: trying to play on "< Date: Thu, 28 Aug 2014 15:53:58 +0200 Subject: [PATCH 081/149] Remove Qt audio output code --- core.h | 1 - coreav.cpp | 32 ++++++-------------------------- 2 files changed, 6 insertions(+), 27 deletions(-) diff --git a/core.h b/core.h index d80c00935..454be391e 100644 --- a/core.h +++ b/core.h @@ -100,7 +100,6 @@ struct ToxCall { public: AudioBuffer audioBuffer; - QAudioOutput* audioOutput; QAudioInput* audioInput; QIODevice* audioInputDevice; ToxAvCSettings codecSettings; diff --git a/coreav.cpp b/coreav.cpp index be380c47e..628442eaa 100644 --- a/coreav.cpp +++ b/coreav.cpp @@ -37,7 +37,7 @@ void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled } alGenSources(1, &calls[callId].alSource); - // Prepare output + // Start input QAudioFormat format; format.setSampleRate(calls[callId].codecSettings.audio_sample_rate); format.setChannelCount(calls[callId].codecSettings.audio_channels); @@ -45,24 +45,6 @@ void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleType(QAudioFormat::SignedInt); - if (!QAudioDeviceInfo::defaultOutputDevice().isFormatSupported(format)) - { - calls[callId].audioOutput = nullptr; - qWarning() << "Core: Raw audio format not supported by output backend, cannot play audio."; - } - else if (calls[callId].audioOutput==nullptr) - { - calls[callId].audioOutput = new QAudioOutput(format); - calls[callId].audioOutput->setBufferSize(1900*30); // Make this bigger to get less underflows, but more latency - calls[callId].audioOutput->start(&calls[callId].audioBuffer); - int error = calls[callId].audioOutput->error(); - if (error != QAudio::NoError) - { - qWarning() << QString("Core: Error %1 when starting audio output").arg(error); - } - } - - // Start input if (!QAudioDeviceInfo::defaultInputDevice().isFormatSupported(format)) { calls[callId].audioInput = nullptr; @@ -98,10 +80,11 @@ void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled Widget::getInstance()->getCamera()->suscribe(); } - else if (calls[callId].audioInput == nullptr && calls[callId].audioOutput == nullptr) + else if (calls[callId].audioInput == nullptr) { - qWarning() << "Audio only call can neither play nor record audio, killing call"; + qWarning() << "Audio only call can not record audio, killing call"; toxav_hangup(toxav, callId); + return; } } @@ -186,10 +169,6 @@ void Core::cleanupCall(int callId) disconnect(calls[callId].sendAudioTimer,0,0,0); calls[callId].sendAudioTimer->stop(); calls[callId].sendVideoTimer->stop(); - if (calls[callId].audioOutput != nullptr) - { - calls[callId].audioOutput->stop(); - } if (calls[callId].audioInput != nullptr) { calls[callId].audioInput->stop(); @@ -203,7 +182,7 @@ void Core::playCallAudio(ToxAv*, int32_t callId, int16_t *data, int samples, voi { Q_UNUSED(user_data); - if (!calls[callId].active || calls[callId].audioOutput == nullptr) + if (!calls[callId].active) return; playAudioBuffer(callId, data, samples); @@ -518,6 +497,7 @@ void Core::onAvStart(void* _toxav, int32_t call_index, void* core) delete transSettings; } +// This function's logic was shamelessly stolen from uTox void Core::playAudioBuffer(int callId, int16_t *data, int samples) { unsigned channels = calls[callId].codecSettings.audio_channels; From 28b1678a889b7bafb01a0d1e6aa0832390e5d648 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Thu, 28 Aug 2014 15:58:05 +0200 Subject: [PATCH 082/149] Remove all AudioBuffer code --- audiobuffer.cpp | 84 ------------------------------------------------- audiobuffer.h | 42 ------------------------- core.cpp | 1 - core.h | 3 -- coreav.cpp | 3 -- qtox.pro | 2 -- 6 files changed, 135 deletions(-) delete mode 100644 audiobuffer.cpp delete mode 100644 audiobuffer.h diff --git a/audiobuffer.cpp b/audiobuffer.cpp deleted file mode 100644 index 9ca0960bb..000000000 --- a/audiobuffer.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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. -*/ - -#include "audiobuffer.h" - -AudioBuffer::AudioBuffer() : - QIODevice(0) -{ - open(QIODevice::ReadWrite); -} - -AudioBuffer::~AudioBuffer() -{ - close(); -} - -qint64 AudioBuffer::readData(char *data, qint64 len) -{ - qint64 total; - bufferMutex.lock(); - try { - total = qMin((qint64)buffer.size(), len); - memcpy(data, buffer.constData(), total); - buffer = buffer.mid(total); - } - catch (...) - { - bufferMutex.unlock(); - return 0; - } - bufferMutex.unlock(); - return total; -} - -qint64 AudioBuffer::writeData(const char* data, qint64 len) -{ - bufferMutex.lock(); - try { - buffer.append(data, len); - } - catch (...) - { - bufferMutex.unlock(); - return 0; - } - bufferMutex.unlock(); - return len; -} - -qint64 AudioBuffer::bytesAvailable() const -{ - bufferMutex.lock(); - long long size = buffer.size() + QIODevice::bytesAvailable(); - bufferMutex.unlock(); - return size; -} - -qint64 AudioBuffer::bufferSize() const -{ - bufferMutex.lock(); - long long size = buffer.size(); - bufferMutex.unlock(); - return size; -} - -void AudioBuffer::clear() -{ - bufferMutex.lock(); - buffer.clear(); - bufferMutex.unlock(); -} diff --git a/audiobuffer.h b/audiobuffer.h deleted file mode 100644 index e94b70447..000000000 --- a/audiobuffer.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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. -*/ - -#ifndef AUDIOBUFFER_H -#define AUDIOBUFFER_H - -#include -#include -#include - -class AudioBuffer : public QIODevice -{ - Q_OBJECT -public: - explicit AudioBuffer(); - ~AudioBuffer(); - - qint64 readData(char *data, qint64 maxlen); - qint64 writeData(const char *data, qint64 len); - qint64 bytesAvailable() const; - qint64 bufferSize() const; - void clear(); - -private: - QByteArray buffer; - mutable QMutex bufferMutex; -}; - -#endif // AUDIOBUFFER_H diff --git a/core.cpp b/core.cpp index 7ad6d0a3c..5c4b16537 100644 --- a/core.cpp +++ b/core.cpp @@ -60,7 +60,6 @@ Core::Core(Camera* cam, QThread *coreThread) : { calls[i].sendAudioTimer = new QTimer(); calls[i].sendVideoTimer = new QTimer(); - calls[i].audioBuffer.moveToThread(coreThread); calls[i].sendAudioTimer->moveToThread(coreThread); calls[i].sendVideoTimer->moveToThread(coreThread); connect(calls[i].sendVideoTimer, &QTimer::timeout, [this,i](){sendCallVideo(i);}); diff --git a/core.h b/core.h index 454be391e..3a44d8f3c 100644 --- a/core.h +++ b/core.h @@ -17,8 +17,6 @@ #ifndef CORE_HPP #define CORE_HPP -#include "audiobuffer.h" - #include #include @@ -99,7 +97,6 @@ struct ToxFile struct ToxCall { public: - AudioBuffer audioBuffer; QAudioInput* audioInput; QIODevice* audioInputDevice; ToxAvCSettings codecSettings; diff --git a/coreav.cpp b/coreav.cpp index 628442eaa..550383273 100644 --- a/coreav.cpp +++ b/coreav.cpp @@ -170,12 +170,9 @@ void Core::cleanupCall(int callId) calls[callId].sendAudioTimer->stop(); calls[callId].sendVideoTimer->stop(); if (calls[callId].audioInput != nullptr) - { calls[callId].audioInput->stop(); - } if (calls[callId].videoEnabled) Widget::getInstance()->getCamera()->unsuscribe(); - calls[callId].audioBuffer.clear(); } void Core::playCallAudio(ToxAv*, int32_t callId, int16_t *data, int samples, void *user_data) diff --git a/qtox.pro b/qtox.pro index fdc562a09..544a4d815 100644 --- a/qtox.pro +++ b/qtox.pro @@ -79,7 +79,6 @@ HEADERS += widget/form/addfriendform.h \ friendlist.h \ cdata.h \ cstring.h \ - audiobuffer.h \ widget/selfcamview.h \ widget/videosurface.h \ widget/camera.h \ @@ -117,7 +116,6 @@ SOURCES += \ settings.cpp \ cdata.cpp \ cstring.cpp \ - audiobuffer.cpp \ widget/selfcamview.cpp \ widget/videosurface.cpp \ widget/camera.cpp \ From 92ff16ffb65e88c58f820590fcc5d3a4db139852 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Thu, 28 Aug 2014 16:02:32 +0200 Subject: [PATCH 083/149] Add OpenAL cleanup --- coreav.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/coreav.cpp b/coreav.cpp index 550383273..93c7e7f18 100644 --- a/coreav.cpp +++ b/coreav.cpp @@ -173,6 +173,9 @@ void Core::cleanupCall(int callId) calls[callId].audioInput->stop(); if (calls[callId].videoEnabled) Widget::getInstance()->getCamera()->unsuscribe(); + alcMakeContextCurrent(nullptr); + alcDestroyContext(calls[callId].alContext); + alcCloseDevice(calls[callId].alOutDev); } void Core::playCallAudio(ToxAv*, int32_t callId, int16_t *data, int samples, void *user_data) From 5adce652ca867f159610599bc1dd98ee7293141e Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Thu, 28 Aug 2014 17:13:26 +0200 Subject: [PATCH 084/149] OpenAL input --- coreav.cpp | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/coreav.cpp b/coreav.cpp index 93c7e7f18..eaad3b67c 100644 --- a/coreav.cpp +++ b/coreav.cpp @@ -37,6 +37,16 @@ void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled } alGenSources(1, &calls[callId].alSource); + // Audio Input + calls[callId].alInDev = alcCaptureOpenDevice(NULL,av_DefaultSettings.audio_sample_rate, AL_FORMAT_MONO16, (av_DefaultSettings.audio_frame_duration * av_DefaultSettings.audio_sample_rate * 4) / 1000); + if (!calls[callId].alInDev) + { + qWarning() << "Coreav: Cannot open input audio device, hanging up call"; + toxav_hangup(toxav, callId); + return; + } + alcCaptureStart(calls[callId].alInDev); + // Start input QAudioFormat format; format.setSampleRate(calls[callId].codecSettings.audio_sample_rate); @@ -190,10 +200,37 @@ void Core::playCallAudio(ToxAv*, int32_t callId, int16_t *data, int samples, voi void Core::sendCallAudio(int callId, ToxAv* toxav) { - if (!calls[callId].active || calls[callId].audioInput == nullptr) + if (!calls[callId].active) return; + int framesize = (calls[callId].codecSettings.audio_frame_duration * calls[callId].codecSettings.audio_sample_rate) / 1000; uint8_t buf[framesize*2], dest[framesize*2]; + + bool frame = false; + ALint samples; + alcGetIntegerv(calls[callId].alInDev, ALC_CAPTURE_SAMPLES, sizeof(samples), &samples); + if(samples >= framesize) + { + alcCaptureSamples(calls[callId].alInDev, buf, framesize); + frame = 1; + } + + if(frame) + { + int r; + if((r = toxav_prepare_audio_frame(toxav, callId, dest, framesize*2, (int16_t*)buf, framesize)) < 0) + { + qDebug() << "Core: toxav_prepare_audio_frame error"; + calls[callId].sendAudioTimer->start(); + return; + } + + if((r = toxav_send_audio(toxav, callId, dest, r)) < 0) + qDebug() << "Core: toxav_send_audio error"; + } + calls[callId].sendAudioTimer->start(); + + /* int bytesReady = calls[callId].audioInput->bytesReady(); if (bytesReady >= framesize*2) { @@ -216,6 +253,7 @@ void Core::sendCallAudio(int callId, ToxAv* toxav) } else calls[callId].sendAudioTimer->start(); + */ } void Core::playCallVideo(ToxAv*, int32_t callId, vpx_image_t* img, void *user_data) From d49e1042fa6c04eff47c17da1cee4691f70ac689 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Thu, 28 Aug 2014 17:32:12 +0200 Subject: [PATCH 085/149] OpenAL input cleanup --- coreav.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/coreav.cpp b/coreav.cpp index eaad3b67c..e8c8399af 100644 --- a/coreav.cpp +++ b/coreav.cpp @@ -186,6 +186,8 @@ void Core::cleanupCall(int callId) alcMakeContextCurrent(nullptr); alcDestroyContext(calls[callId].alContext); alcCloseDevice(calls[callId].alOutDev); + alcCaptureStop(calls[callId].alInDev); + alcCaptureCloseDevice(calls[callId].alInDev); } void Core::playCallAudio(ToxAv*, int32_t callId, int16_t *data, int samples, void *user_data) From 34b87064082e0b4c413aa47a1b6be914f25cfc53 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Thu, 28 Aug 2014 17:46:45 +0200 Subject: [PATCH 086/149] Remove Qt audio input code --- core.h | 3 +- coreav.cpp | 83 ++++++++---------------------------------------------- 2 files changed, 13 insertions(+), 73 deletions(-) diff --git a/core.h b/core.h index 3a44d8f3c..dd32bc0c2 100644 --- a/core.h +++ b/core.h @@ -97,14 +97,13 @@ struct ToxFile struct ToxCall { public: - QAudioInput* audioInput; - QIODevice* audioInputDevice; ToxAvCSettings codecSettings; QTimer *sendAudioTimer, *sendVideoTimer; int callId; int friendId; bool videoEnabled; bool active; + bool muteMic; ALCdevice* alOutDev, *alInDev; ALCcontext* alContext; ALuint alSource; diff --git a/coreav.cpp b/coreav.cpp index e8c8399af..0daa8c09e 100644 --- a/coreav.cpp +++ b/coreav.cpp @@ -11,6 +11,7 @@ void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled qDebug() << QString("Core: preparing call %1").arg(callId); calls[callId].callId = callId; calls[callId].friendId = friendId; + calls[callId].muteMic = false; // the following three lines are also now redundant from startCall, but are // necessary there for outbound and here for inbound calls[callId].codecSettings = av_DefaultSettings; @@ -47,55 +48,19 @@ void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled } alcCaptureStart(calls[callId].alInDev); - // Start input - QAudioFormat format; - format.setSampleRate(calls[callId].codecSettings.audio_sample_rate); - format.setChannelCount(calls[callId].codecSettings.audio_channels); - format.setSampleSize(16); - format.setCodec("audio/pcm"); - format.setByteOrder(QAudioFormat::LittleEndian); - format.setSampleType(QAudioFormat::SignedInt); - if (!QAudioDeviceInfo::defaultInputDevice().isFormatSupported(format)) - { - calls[callId].audioInput = nullptr; - qWarning() << "Core: Default input format not supported, cannot record audio"; - } - else if (calls[callId].audioInput==nullptr) - { - qDebug() << "Core: Starting new audio input"; - calls[callId].audioInput = new QAudioInput(format); - calls[callId].audioInputDevice = calls[callId].audioInput->start(); - } - else if (calls[callId].audioInput->state() == QAudio::StoppedState) - { - calls[callId].audioInputDevice = calls[callId].audioInput->start(); - } - // Go calls[callId].active = true; - - if (calls[callId].audioInput != nullptr) - { - calls[callId].sendAudioTimer->setInterval(2); - calls[callId].sendAudioTimer->setSingleShot(true); - connect(calls[callId].sendAudioTimer, &QTimer::timeout, [=](){sendCallAudio(callId,toxav);}); - calls[callId].sendAudioTimer->start(); - } - + calls[callId].sendAudioTimer->setInterval(5); + calls[callId].sendAudioTimer->setSingleShot(true); + connect(calls[callId].sendAudioTimer, &QTimer::timeout, [=](){sendCallAudio(callId,toxav);}); + calls[callId].sendAudioTimer->start(); if (calls[callId].videoEnabled) { calls[callId].sendVideoTimer->setInterval(50); calls[callId].sendVideoTimer->setSingleShot(true); calls[callId].sendVideoTimer->start(); - Widget::getInstance()->getCamera()->suscribe(); } - else if (calls[callId].audioInput == nullptr) - { - qWarning() << "Audio only call can not record audio, killing call"; - toxav_hangup(toxav, callId); - return; - } } void Core::onAvMediaChange(void*, int32_t, void*) @@ -179,8 +144,6 @@ void Core::cleanupCall(int callId) disconnect(calls[callId].sendAudioTimer,0,0,0); calls[callId].sendAudioTimer->stop(); calls[callId].sendVideoTimer->stop(); - if (calls[callId].audioInput != nullptr) - calls[callId].audioInput->stop(); if (calls[callId].videoEnabled) Widget::getInstance()->getCamera()->unsuscribe(); alcMakeContextCurrent(nullptr); @@ -205,6 +168,12 @@ void Core::sendCallAudio(int callId, ToxAv* toxav) if (!calls[callId].active) return; + if (calls[callId].muteMic) + { + calls[callId].sendAudioTimer->start(); + return; + } + int framesize = (calls[callId].codecSettings.audio_frame_duration * calls[callId].codecSettings.audio_sample_rate) / 1000; uint8_t buf[framesize*2], dest[framesize*2]; @@ -231,31 +200,6 @@ void Core::sendCallAudio(int callId, ToxAv* toxav) qDebug() << "Core: toxav_send_audio error"; } calls[callId].sendAudioTimer->start(); - - /* - int bytesReady = calls[callId].audioInput->bytesReady(); - if (bytesReady >= framesize*2) - { - calls[callId].audioInputDevice->read((char*)buf, framesize*2); - int result = toxav_prepare_audio_frame(toxav, callId, dest, framesize*2, (int16_t*)buf, framesize); - if (result < 0) - { - qWarning() << QString("Core: Unable to prepare audio frame, error %1").arg(result); - calls[callId].sendAudioTimer->start(); - return; - } - result = toxav_send_audio(toxav, callId, dest, result); - if (result < 0) - { - qWarning() << QString("Core: Unable to send audio frame, error %1").arg(result); - calls[callId].sendAudioTimer->start(); - return; - } - calls[callId].sendAudioTimer->start(); - } - else - calls[callId].sendAudioTimer->start(); - */ } void Core::playCallVideo(ToxAv*, int32_t callId, vpx_image_t* img, void *user_data) @@ -313,10 +257,7 @@ void Core::decreaseVideoBusyness() void Core::micMuteToggle(int callId) { - if (calls[callId].audioInput->state() == QAudio::ActiveState) - calls[callId].audioInput->suspend(); - else - calls[callId].audioInput->start(); + calls[callId].muteMic = !calls[callId].muteMic; } void Core::onAvCancel(void* _toxav, int32_t call_index, void* core) From af9c370169ee36900eae605863929a303e75f88e Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Thu, 28 Aug 2014 19:06:51 +0200 Subject: [PATCH 087/149] Forbid sending sequential files They aren't seekable, and tend to be infinitely big.. --- widget/form/chatform.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index cbb245afb..f11936b12 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -29,6 +29,7 @@ #include #include #include +#include ChatForm::ChatForm(Friend* chatFriend) : f(chatFriend), curRow{0}, lockSliderToBottom{true} @@ -286,6 +287,12 @@ void ChatForm::onAttachClicked() QFile file(path); if (!file.exists() || !file.open(QIODevice::ReadOnly)) return; + if (file.isSequential()) + { + QMessageBox::critical(0, "Bad Idea", "You're trying to send a special (sequential) file, that's not going to work!"); + return; + file.close(); + } long long filesize = file.size(); file.close(); QFileInfo fi(path); From 74e9d7a4f5a25c747e20fd4e891d2667e89cb1e6 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Thu, 28 Aug 2014 19:21:48 +0200 Subject: [PATCH 088/149] Fix division by 0 when receiving from empty files Like /dev/zero. --- widget/filetransfertwidget.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/widget/filetransfertwidget.cpp b/widget/filetransfertwidget.cpp index 36027257f..b72d54e1a 100644 --- a/widget/filetransfertwidget.cpp +++ b/widget/filetransfertwidget.cpp @@ -171,10 +171,15 @@ void FileTransfertWidget::onFileTransferInfo(int FriendId, int FileNum, int64_t etaTime = etaTime.addSecs(etaSecs); eta->setText(etaTime.toString("mm:ss")); if (!Filesize) + { progress->setValue(0); + qDebug() << QString("FT: received %1 bytes of an empty file, stop sending sequential devices, zetok!").arg(BytesSent); + } else + { progress->setValue(BytesSent*100/Filesize); - qDebug() << QString("FT: received %1/%2 bytes, progress is %3%").arg(BytesSent).arg(Filesize).arg(BytesSent*100/Filesize); + qDebug() << QString("FT: received %1/%2 bytes, progress is %3%").arg(BytesSent).arg(Filesize).arg(BytesSent*100/Filesize); + } lastUpdate = newtime; lastBytesSent = BytesSent; } From 56edd76df9233e42ea80e752865f199c441f6bd6 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Thu, 28 Aug 2014 20:20:28 +0200 Subject: [PATCH 089/149] Fix use after free on file received --- core.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core.cpp b/core.cpp index 5c4b16537..2c908d663 100644 --- a/core.cpp +++ b/core.cpp @@ -337,9 +337,9 @@ void Core::onFileControlCallback(Tox* tox, int32_t friendnumber, uint8_t receive .arg(file->fileNum).arg(file->friendId); file->status = ToxFile::STOPPED; emit static_cast(core)->fileTransferFinished(*file); - removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum); // confirm receive is complete tox_file_send_control(tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_FINISHED, nullptr, 0); + removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum); } else { From a75d1c5c6e81caf9515012e203c1c5cad440c311 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Thu, 28 Aug 2014 20:52:26 +0200 Subject: [PATCH 090/149] Don't call tox_do from FT functions --- core.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core.cpp b/core.cpp index 2c908d663..8481988c9 100644 --- a/core.cpp +++ b/core.cpp @@ -1007,7 +1007,7 @@ void Core::sendAllFileData(Core *core, ToxFile* file) if (tox_file_send_data(core->tox, file->friendId, file->fileNum, data, readSize) == -1) { //qWarning("Core::fileHeartbeat: Error sending data chunk"); - core->process(); + //core->process(); delete[] data; QThread::msleep(5); continue; From 3fc37d2d4cd63672f18b1f59ffbfce09aab0f7ae Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Thu, 28 Aug 2014 21:56:55 +0200 Subject: [PATCH 091/149] Move file transfer in the core thread Toxcore is not thread safe --- core.cpp | 137 ++++++++++++++++++++++++++++++------------------------- core.h | 4 +- 2 files changed, 78 insertions(+), 63 deletions(-) diff --git a/core.cpp b/core.cpp index 8481988c9..ae1190dee 100644 --- a/core.cpp +++ b/core.cpp @@ -21,6 +21,7 @@ #include "widget/widget.h" #include +#include #include #include @@ -45,8 +46,6 @@ Core::Core(Camera* cam, QThread *coreThread) : toxTimer->setSingleShot(true); //saveTimer = new QTimer(this); //saveTimer->start(TOX_SAVE_INTERVAL); - //fileTimer = new QTimer(this); - //fileTimer->start(TOX_FILE_INTERVAL); bootstrapTimer = new QTimer(this); bootstrapTimer->start(TOX_BOOTSTRAP_INTERVAL); connect(toxTimer, &QTimer::timeout, this, &Core::process); @@ -304,7 +303,10 @@ void Core::onFileControlCallback(Tox* tox, int32_t friendnumber, uint8_t receive file->status = ToxFile::TRANSMITTING; emit static_cast(core)->fileTransferAccepted(*file); qDebug() << "Core: File control callback, file accepted"; - file->sendFuture = QtConcurrent::run(sendAllFileData, static_cast(core), file); + file->sendTimer = new QTimer(static_cast(core)); + connect(file->sendTimer, &QTimer::timeout, std::bind(sendAllFileData,static_cast(core), file)); + file->sendTimer->setSingleShot(true); + file->sendTimer->start(TOX_FILE_INTERVAL); } else if (receive_send == 1 && control_type == TOX_FILECONTROL_KILL) { @@ -312,7 +314,7 @@ void Core::onFileControlCallback(Tox* tox, int32_t friendnumber, uint8_t receive .arg(file->fileNum).arg(file->friendId); file->status = ToxFile::STOPPED; emit static_cast(core)->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); - file->sendFuture.waitForFinished(); // Wait for sendAllFileData to return before deleting the ToxFile + while (file->sendTimer) QThread::msleep(1); // Wait for sendAllFileData to return before deleting the ToxFile removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum); } else if (receive_send == 1 && control_type == TOX_FILECONTROL_FINISHED) @@ -532,7 +534,7 @@ void Core::cancelFileSend(int friendId, int fileNum) file->status = ToxFile::STOPPED; emit fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); tox_file_send_control(tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0); - file->sendFuture.waitForFinished(); // Wait until sendAllFileData returns before deleting + while (file->sendTimer) QThread::msleep(1); // Wait until sendAllFileData returns before deleting removeFileFromQueue(true, friendId, fileNum); } @@ -961,64 +963,77 @@ void Core::removeFileFromQueue(bool sendQueue, int friendId, int fileId) void Core::sendAllFileData(Core *core, ToxFile* file) { - while (file->bytesSent < file->filesize) + if (file->status == ToxFile::PAUSED) { - if (file->status == ToxFile::PAUSED) - { - QThread::sleep(1); - continue; - } - else if (file->status == ToxFile::STOPPED) - { - qWarning("Core::sendAllFileData: File is stopped"); - return; - } - emit core->fileTransferInfo(file->friendId, file->fileNum, file->filesize, file->bytesSent, ToxFile::SENDING); - qApp->processEvents(); - long long chunkSize = tox_file_data_size(core->tox, file->friendId); - if (chunkSize == -1) - { - qWarning("Core::fileHeartbeat: Error getting preffered chunk size, aborting file send"); - file->status = ToxFile::STOPPED; - emit core->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); - tox_file_send_control(core->tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0); - removeFileFromQueue(true, file->friendId, file->fileNum); - return; - } - //qDebug() << "chunkSize: " << chunkSize; - chunkSize = std::min(chunkSize, file->filesize); - uint8_t* data = new uint8_t[chunkSize]; - file->file->seek(file->bytesSent); - int readSize = file->file->read((char*)data, chunkSize); - if (readSize == -1) - { - qWarning() << QString("Core::sendAllFileData: Error reading from file: %1").arg(file->file->errorString()); - delete[] data; - QThread::msleep(5); - continue; - } - else if (readSize == 0) - { - qWarning() << QString("Core::sendAllFileData: Nothing to read from file: %1").arg(file->file->errorString()); - delete[] data; - QThread::msleep(5); - continue; - } - if (tox_file_send_data(core->tox, file->friendId, file->fileNum, data, readSize) == -1) - { - //qWarning("Core::fileHeartbeat: Error sending data chunk"); - //core->process(); - delete[] data; - QThread::msleep(5); - continue; - } - delete[] data; - file->bytesSent += readSize; - //qDebug() << QString("Core::fileHeartbeat: sent %1/%2 bytes").arg(file->bytesSent).arg(file->fileData.size()); + file->sendTimer->start(TOX_FILE_INTERVAL); + return; + } + else if (file->status == ToxFile::STOPPED) + { + qWarning("Core::sendAllFileData: File is stopped"); + file->sendTimer->disconnect(); + delete file->sendTimer; + file->sendTimer = nullptr; + return; + } + emit core->fileTransferInfo(file->friendId, file->fileNum, file->filesize, file->bytesSent, ToxFile::SENDING); + qApp->processEvents(); + long long chunkSize = tox_file_data_size(core->tox, file->friendId); + if (chunkSize == -1) + { + qWarning("Core::fileHeartbeat: Error getting preffered chunk size, aborting file send"); + file->status = ToxFile::STOPPED; + emit core->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); + tox_file_send_control(core->tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0); + removeFileFromQueue(true, file->friendId, file->fileNum); + return; + } + //qDebug() << "chunkSize: " << chunkSize; + chunkSize = std::min(chunkSize, file->filesize); + uint8_t* data = new uint8_t[chunkSize]; + file->file->seek(file->bytesSent); + int readSize = file->file->read((char*)data, chunkSize); + if (readSize == -1) + { + qWarning() << QString("Core::sendAllFileData: Error reading from file: %1").arg(file->file->errorString()); + delete[] data; + file->sendTimer->start(TOX_FILE_INTERVAL); + return; + } + else if (readSize == 0) + { + qWarning() << QString("Core::sendAllFileData: Nothing to read from file: %1").arg(file->file->errorString()); + delete[] data; + file->sendTimer->start(TOX_FILE_INTERVAL); + return; + } + if (tox_file_send_data(core->tox, file->friendId, file->fileNum, data, readSize) == -1) + { + //qWarning("Core::fileHeartbeat: Error sending data chunk"); + //core->process(); + delete[] data; + QThread::msleep(1); + file->sendTimer->start(TOX_FILE_INTERVAL); + return; + } + delete[] data; + file->bytesSent += readSize; + //qDebug() << QString("Core::fileHeartbeat: sent %1/%2 bytes").arg(file->bytesSent).arg(file->fileData.size()); + + if (file->bytesSent < file->filesize) + { + file->sendTimer->start(TOX_FILE_INTERVAL); + return; + } + else + { + qDebug("Core: File transfer finished"); + file->sendTimer->disconnect(); + delete file->sendTimer; + file->sendTimer = nullptr; + tox_file_send_control(core->tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_FINISHED, nullptr, 0); + emit core->fileTransferFinished(*file); } - qDebug("Core::fileHeartbeat: Transfer finished"); - tox_file_send_control(core->tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_FINISHED, nullptr, 0); - emit core->fileTransferFinished(*file); } void Core::groupInviteFriend(int friendId, int groupId) diff --git a/core.h b/core.h index dd32bc0c2..794d866c7 100644 --- a/core.h +++ b/core.h @@ -39,7 +39,7 @@ #define TOXAV_MAX_CALLS 16 #define GROUPCHAT_MAX_SIZE 32 #define TOX_SAVE_INTERVAL 30*1000 -#define TOX_FILE_INTERVAL 20 +#define TOX_FILE_INTERVAL 1 #define TOX_BOOTSTRAP_INTERVAL 10*1000 #define TOXAV_RINGING_TIME 15 @@ -91,7 +91,7 @@ struct ToxFile long long filesize; FileStatus status; FileDirection direction; - QFuture sendFuture; + QTimer* sendTimer; }; struct ToxCall From 5fba31927fb27bdfd2b6482ed170f2c2b33b0062 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Thu, 28 Aug 2014 23:06:53 +0200 Subject: [PATCH 092/149] Fix bad audio quality --- core.h | 2 +- coreav.cpp | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/core.h b/core.h index 794d866c7..fe2a332a7 100644 --- a/core.h +++ b/core.h @@ -271,7 +271,7 @@ private: static void cleanupCall(int callId); static void playCallAudio(ToxAv *toxav, int32_t callId, int16_t *data, int samples, void *user_data); // Callback static void sendCallAudio(int callId, ToxAv* toxav); - static void playAudioBuffer(int callId, int16_t *data, int samples); + static void playAudioBuffer(int callId, int16_t *data, int samples, unsigned channels, int sampleRate); static void playCallVideo(ToxAv* toxav, int32_t callId, vpx_image_t* img, void *user_data); void sendCallVideo(int callId); diff --git a/coreav.cpp b/coreav.cpp index 0daa8c09e..24281d8de 100644 --- a/coreav.cpp +++ b/coreav.cpp @@ -153,14 +153,17 @@ void Core::cleanupCall(int callId) alcCaptureCloseDevice(calls[callId].alInDev); } -void Core::playCallAudio(ToxAv*, int32_t callId, int16_t *data, int samples, void *user_data) +void Core::playCallAudio(ToxAv* toxav, int32_t callId, int16_t *data, int samples, void *user_data) { Q_UNUSED(user_data); if (!calls[callId].active) return; - playAudioBuffer(callId, data, samples); + ToxAvCSettings dest; + if(toxav_get_peer_csettings(toxav, callId, 0, &dest) == 0) + playAudioBuffer(callId, data, samples, dest.audio_channels, dest.audio_sample_rate); + //playAudioBuffer(callId, data, samples, 1, av_DefaultSettings.audio_sample_rate); } void Core::sendCallAudio(int callId, ToxAv* toxav) @@ -479,10 +482,10 @@ void Core::onAvStart(void* _toxav, int32_t call_index, void* core) } // This function's logic was shamelessly stolen from uTox -void Core::playAudioBuffer(int callId, int16_t *data, int samples) +void Core::playAudioBuffer(int callId, int16_t *data, int samples, unsigned channels, int sampleRate) { - unsigned channels = calls[callId].codecSettings.audio_channels; - if(!channels || channels > 2) { + if(!channels || channels > 2) + { qWarning() << "Core::playAudioBuffer: trying to play on "< Date: Thu, 28 Aug 2014 23:11:33 +0200 Subject: [PATCH 093/149] Remove some debug output --- coreav.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/coreav.cpp b/coreav.cpp index 24281d8de..f64a90ae0 100644 --- a/coreav.cpp +++ b/coreav.cpp @@ -163,7 +163,6 @@ void Core::playCallAudio(ToxAv* toxav, int32_t callId, int16_t *data, int sample ToxAvCSettings dest; if(toxav_get_peer_csettings(toxav, callId, 0, &dest) == 0) playAudioBuffer(callId, data, samples, dest.audio_channels, dest.audio_sample_rate); - //playAudioBuffer(callId, data, samples, 1, av_DefaultSettings.audio_sample_rate); } void Core::sendCallAudio(int callId, ToxAv* toxav) @@ -509,7 +508,7 @@ void Core::playAudioBuffer(int callId, int16_t *data, int samples, unsigned chan } else { - qDebug() << "Core: Dropped audio frame" << sampleRate << ", " << channels<<", "< Date: Fri, 29 Aug 2014 11:56:42 +0200 Subject: [PATCH 094/149] Fix #215, update translations --- translations/de.ts | 205 +++++++++++++++++++++++++++++++++------------ translations/fr.ts | 205 +++++++++++++++++++++++++++++++++------------ translations/it.ts | 23 ++--- translations/ru.ts | 174 ++++++++++++++++++++++++++------------ widget/widget.cpp | 6 +- 5 files changed, 442 insertions(+), 171 deletions(-) diff --git a/translations/de.ts b/translations/de.ts index 63b4dada9..ab61ba9ad 100644 --- a/translations/de.ts +++ b/translations/de.ts @@ -1,75 +1,75 @@ - + AddFriendForm - + Add Friends Freunde hinzufügen - + Tox ID Tox ID of the person you're sending a friend request to Tox ID - + Message The message you send in friend requests Nachricht - + Send friend request Freundschaftseinladung versenden - + Tox me maybe? Default message in friend requests if the field is left blank. Write something appropriate! Lass uns Toxen! - + Please fill in a valid Tox ID Tox ID of the friend you're sending a friend request to Bitte gib eine gültige Tox ID ein - + This address does not exist The DNS gives the Tox ID associated to toxme.se addresses - + Error while looking up DNS The DNS gives the Tox ID associated to toxme.se addresses Fehler beim Auflösen des DNS - + Unexpected number of text records Error with the DNS Unererwartete Anzahl von Texteinträgen - + Unexpected number of values in text record Error with the DNS Unerwartete Anzahl von Werten innerhalb des Texteintrages - + The DNS lookup does not contain any Tox ID Error with the DNS Der DNS Eintrag enthält keine gültige TOX ID - - + + The DNS lookup does not contain a valid Tox ID Error with the DNS Der DNS Eintrag enthält keine gültige TOX ID @@ -78,12 +78,12 @@ Camera - + Camera eror Kamerafehler - + Camera format %1 not supported, can't use the camera Kameraformat %1 wird nicht unterstützt. Die Kamera kann nicht verwendet werden @@ -91,13 +91,13 @@ ChatForm - + Send a file Datei versenden - - + + Save chat log Chatverlauf speichern @@ -113,11 +113,42 @@ FileTransfertWidget - + Save a file Title of the file saving dialog Datei speichern + + + Location not writable + Title of permissions popup + + + + + You do not have permission to write that location. Choose another, or cancel the save dialog. + text of permissions popup + + + + + FilesForm + + + Transfered Files + "Headline" of the window + + + + + Downloads + + + + + Uploads + + FriendRequestDialog @@ -158,19 +189,19 @@ FriendWidget - + Copy friend ID Menu to copy the Tox ID of that friend Tox ID kopieren - + Invite in group Menu to invite a friend in a groupchat In Gruppe einladen - + Remove friend Menu to remove the friend from our friendlist Freund entfernen @@ -179,23 +210,23 @@ GroupChatForm - + %1 users in chat Number of users in chat %1 Personen im Chat - + <Unknown> <Unbekannt> - + %1 users in chat %1 Personen im Chat - + Save chat log Chatverlauf speichern @@ -203,28 +234,76 @@ GroupWidget - - + + %1 users in chat %1 Personen im Chat - - + + 0 users in chat 0 Personen im Chat - + Quit group Menu to quit a groupchat Gruppe verlassen + + MainWindow + + + qTox + + + + + Your name + Dein Name + + + + Your status + Dein Status + + + + Add friends + + + + + Create a group chat + + + + + View completed file transfers + + + + + Change your settings + + + + + Close + Schließen + + + + Ctrl+Q + Strg+Q + + SelfCamView - + Tox video test Title of the window to test the video/webcam Tox Video testen @@ -233,83 +312,105 @@ SettingsForm - + User Settings "Headline" of the window Einstellungen - + Name Username/nick Benutzername - + Status Status message Status - + + (click here to copy) + Click on this text to copy TID to clipboard + + + + Test video Text on a button to test the video/webcam Video testen - + Enable IPv6 (recommended) Text on a checkbox to enable IPv6 IPv6 aktivieren (empfohlen) - + Use translations Text on a checkbox to enable translations + + + Make Tox portable + Text on a checkbox to make qTox a portable application + + + + + Save settings to the working directory instead of the usual conf dir + describes makeToxPortable checkbox + + + + + Smiley Pack + Text on smiley pack label + + Widget - Tox - Tox + Tox - Your name - Dein Name + Dein Name - Your status - Dein Status + Dein Status - Close - Schließen + Schließen - Ctrl+Q - Strg+Q + Strg+Q + Online Button to set your status to 'Online' - Online + Online + Away Button to set your status to 'Away' - Abwesend + Abwesend + Busy Button to set your status to 'Busy' - Beschäftigt + Beschäftigt diff --git a/translations/fr.ts b/translations/fr.ts index 3851b7684..435d022c7 100644 --- a/translations/fr.ts +++ b/translations/fr.ts @@ -1,75 +1,75 @@ - + AddFriendForm - + Add Friends Ajouter des amis - + Tox ID Tox ID of the person you're sending a friend request to ID Tox - + Message The message you send in friend requests Message - + Send friend request Envoyer la demande d'ami - + Tox me maybe? Default message in friend requests if the field is left blank. Write something appropriate! Je souhaiterais vous ajouter à mes contacts - + Please fill in a valid Tox ID Tox ID of the friend you're sending a friend request to Merci de remplir un ID Tox valide - + This address does not exist The DNS gives the Tox ID associated to toxme.se addresses - + Error while looking up DNS The DNS gives the Tox ID associated to toxme.se addresses Erreur en consultant le serveur DNS - + Unexpected number of text records Error with the DNS Nombre d'entrées texte innatendu - + Unexpected number of values in text record Error with the DNS Nombre d'entrées numériques dans l'entrée texte innatendu - + The DNS lookup does not contain any Tox ID Error with the DNS La réponse DNS ne contient aucun ID Tox - - + + The DNS lookup does not contain a valid Tox ID Error with the DNS La réponse DNS ne contient pas d'ID Tox valide @@ -78,12 +78,12 @@ Camera - + Camera eror Erreur de caméra - + Camera format %1 not supported, can't use the camera Format %1 de la caméra non supporté, impossible de l'utiliser @@ -91,13 +91,13 @@ ChatForm - + Send a file Envoyer un fichier - - + + Save chat log Sauvegarder l'historique de conversation @@ -113,11 +113,42 @@ FileTransfertWidget - + Save a file Title of the file saving dialog Sauvegarder un fichier + + + Location not writable + Title of permissions popup + + + + + You do not have permission to write that location. Choose another, or cancel the save dialog. + text of permissions popup + + + + + FilesForm + + + Transfered Files + "Headline" of the window + + + + + Downloads + + + + + Uploads + + FriendRequestDialog @@ -158,19 +189,19 @@ FriendWidget - + Copy friend ID Menu to copy the Tox ID of that friend Copier l'ID ami - + Invite in group Menu to invite a friend in a groupchat Inviter dans un groupe - + Remove friend Menu to remove the friend from our friendlist Supprimer ami @@ -179,23 +210,23 @@ GroupChatForm - + %1 users in chat Number of users in chat %1 personnes - + <Unknown> <Inconnu> - + %1 users in chat %1 personnes - + Save chat log Sauvegarder l'historique de conversation @@ -203,28 +234,76 @@ GroupWidget - - + + %1 users in chat %1 personnes - - + + 0 users in chat 0 personnes - + Quit group Menu to quit a groupchat Quitter le groupe + + MainWindow + + + qTox + + + + + Your name + Votre nom + + + + Your status + Votre status + + + + Add friends + + + + + Create a group chat + + + + + View completed file transfers + + + + + Change your settings + + + + + Close + Fermer + + + + Ctrl+Q + Ctrl+Q + + SelfCamView - + Tox video test Title of the window to test the video/webcam Test vidéo Tox @@ -233,83 +312,105 @@ SettingsForm - + User Settings "Headline" of the window Configuration - + Name Username/nick Nom - + Status Status message Status - + + (click here to copy) + Click on this text to copy TID to clipboard + + + + Test video Text on a button to test the video/webcam Tester la vidéo - + Enable IPv6 (recommended) Text on a checkbox to enable IPv6 Activer IPv6 (recommandé) - + Use translations Text on a checkbox to enable translations + + + Make Tox portable + Text on a checkbox to make qTox a portable application + + + + + Save settings to the working directory instead of the usual conf dir + describes makeToxPortable checkbox + + + + + Smiley Pack + Text on smiley pack label + + Widget - Tox - Tox + Tox - Your name - Votre nom + Votre nom - Your status - Votre status + Votre status - Close - Fermer + Fermer - Ctrl+Q - Ctrl+Q + Ctrl+Q + Online Button to set your status to 'Online' - Connecté + Connecté + Away Button to set your status to 'Away' - Indisponnible + Indisponnible + Busy Button to set your status to 'Busy' - Occupé + Occupé diff --git a/translations/it.ts b/translations/it.ts index cee16d3aa..fd79fa84f 100644 --- a/translations/it.ts +++ b/translations/it.ts @@ -1,6 +1,6 @@ - + AddFriendForm @@ -91,13 +91,13 @@ ChatForm - + Send a file Invia un file - - + + Save chat log Salva il log della chat @@ -113,19 +113,19 @@ FileTransfertWidget - + Save a file Title of the file saving dialog Salva file - + Location not writable Title of permissions popup Errore - + You do not have permission to write that location. Choose another, or cancel the save dialog. text of permissions popup Non hai sufficienti permessi per scrivere in questa locazione. Scegli un'altra posizione, o annulla il salvataggio. @@ -419,19 +419,22 @@ Ctrl+Q + Online Button to set your status to 'Online' - Online + Online + Away Button to set your status to 'Away' - Assente + Assente + Busy Button to set your status to 'Busy' - Occupato + Occupato diff --git a/translations/ru.ts b/translations/ru.ts index 2ce21d900..1e2118770 100644 --- a/translations/ru.ts +++ b/translations/ru.ts @@ -27,51 +27,51 @@ Отправить запрос на добавление в друзья - + Tox me maybe? Default message in friend requests if the field is left blank. Write something appropriate! Вот таким нехитрым и незамысловатым образом решаются сложные переводчиские проблемы Добавь меня, а? - + Please fill in a valid Tox ID Tox ID of the friend you're sending a friend request to Пожалуйста, введите корректный Tox ID - + This address does not exist The DNS gives the Tox ID associated to toxme.se addresses Нет такого адреса - + Error while looking up DNS The DNS gives the Tox ID associated to toxme.se addresses Ошибка при просмотре DNS - + Unexpected number of text records Error with the DNS Непредвиденное количество текстовых записей - + Unexpected number of values in text record Error with the DNS Непредвиденное количество значений в текстовой записи - + The DNS lookup does not contain any Tox ID Error with the DNS В ответе DNS ни одного Tox ID - - + + The DNS lookup does not contain a valid Tox ID Error with the DNS Ответ DNS не содержит корректных Tox ID @@ -93,13 +93,13 @@ ChatForm - + Send a file Отправить файл - - + + Save chat log Сохранить лог чата @@ -115,11 +115,23 @@ FileTransfertWidget - + Save a file Title of the file saving dialog Сохранить файл + + + Location not writable + Title of permissions popup + + + + + You do not have permission to write that location. Choose another, or cancel the save dialog. + text of permissions popup + + FilesForm @@ -130,12 +142,12 @@ Переданные файлы - + Downloads Загрузки - + Uploads Выгрузки @@ -181,19 +193,19 @@ FriendWidget - + Copy friend ID Menu to copy the Tox ID of that friend Копировать ID друга - + Invite in group Menu to invite a friend in a groupchat Пригласить в группу - + Remove friend Menu to remove the friend from our friendlist Удалить друга @@ -202,23 +214,23 @@ GroupChatForm - + %1 users in chat Number of users in chat %1 пользователей в чате - + <Unknown> <Неизвестно> - + %1 users in chat %1 пользователей в чате - + Save chat log Сохранить лог чата @@ -226,24 +238,72 @@ GroupWidget - + Quit group Menu to quit a groupchat Покинуть группу - + %1 users in chat %1 пользователей в чате - + 0 users in chat Ни одного пользователя в чате + + MainWindow + + + qTox + + + + + Your name + Ваше имя + + + + Your status + Ваш статус + + + + Add friends + Добавить друзей + + + + Create a group chat + Создать групповой чат + + + + View completed file transfers + + + + + Change your settings + Изменить ваши настройки + + + + Close + Закрыть + + + + Ctrl+Q + Ctrl+Q + + SelfCamView @@ -256,117 +316,123 @@ SettingsForm - + User Settings "Headline" of the window Пользовательские настройки - + Name Username/nick Имя - + Status Status message Статус - + (click here to copy) Click on this text to copy TID to clipboard (нажмите здесь чтобы скопировать) - + Test video Text on a button to test the video/webcam Проверить видео - + Enable IPv6 (recommended) Text on a checkbox to enable IPv6 Включить IPv6 (рекомендуется) - + Use translations Text on a checkbox to enable translations Так гораздо понятнее, чем «использовать переводы» Русскоязычный интерфейс - + Make Tox portable Text on a checkbox to make qTox a portable application Портативный режим + + + Save settings to the working directory instead of the usual conf dir + describes makeToxPortable checkbox + + + + + Smiley Pack + Text on smiley pack label + + Widget - Tox - Tox + Tox - Your name - Ваше имя + Ваше имя - Your status - Ваш статус + Ваш статус - Add friends - Добавить друзей + Добавить друзей - Create a group chat - Создать групповой чат + Создать групповой чат - (button inactive currently) - (кнопка на данный момент неактивна) + (кнопка на данный момент неактивна) - Change your settings - Изменить ваши настройки + Изменить ваши настройки - Close - Закрыть + Закрыть - Ctrl+Q - Ctrl+Q + Ctrl+Q + Online Button to set your status to 'Online' - В сети + В сети + Away Button to set your status to 'Away' Вероятно, это не столь долгое путешествие - Отошёл + Отошёл + Busy Button to set your status to 'Busy' - Занят + Занят diff --git a/widget/widget.cpp b/widget/widget.cpp index 9f56f21f7..8c74be7a6 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -125,11 +125,11 @@ Widget::Widget(QWidget *parent) ui->statusButton->setStyleSheet(Style::get(":/ui/statusButton/statusButton.css")); QMenu *statusButtonMenu = new QMenu(ui->statusButton); - QAction* setStatusOnline = statusButtonMenu->addAction(tr("Online","Button to set your status to 'Online'")); + QAction* setStatusOnline = statusButtonMenu->addAction(Widget::tr("Online","Button to set your status to 'Online'")); setStatusOnline->setIcon(QIcon(":ui/statusButton/dot_online.png")); - QAction* setStatusAway = statusButtonMenu->addAction(tr("Away","Button to set your status to 'Away'")); + QAction* setStatusAway = statusButtonMenu->addAction(Widget::tr("Away","Button to set your status to 'Away'")); setStatusAway->setIcon(QIcon(":ui/statusButton/dot_idle.png")); - QAction* setStatusBusy = statusButtonMenu->addAction(tr("Busy","Button to set your status to 'Busy'")); + QAction* setStatusBusy = statusButtonMenu->addAction(Widget::tr("Busy","Button to set your status to 'Busy'")); setStatusBusy->setIcon(QIcon(":ui/statusButton/dot_busy.png")); ui->statusButton->setMenu(statusButtonMenu); From c56a62fd74b87927a169ad39c143a3f395774ee0 Mon Sep 17 00:00:00 2001 From: Ansa89 Date: Fri, 29 Aug 2014 12:00:41 +0200 Subject: [PATCH 095/149] Italian translation: update --- translations/it.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translations/it.ts b/translations/it.ts index d0d8f8265..51662fae7 100644 --- a/translations/it.ts +++ b/translations/it.ts @@ -1,6 +1,6 @@ - + AddFriendForm From c22c87477854e0a19a14b6dc59e237ec294cb6c6 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Fri, 29 Aug 2014 12:15:20 +0200 Subject: [PATCH 096/149] Fix #214 --- qtox.pro | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qtox.pro b/qtox.pro index 544a4d815..1d0a5591d 100644 --- a/qtox.pro +++ b/qtox.pro @@ -42,6 +42,8 @@ INSTALLS += target INCLUDEPATH += libs/include win32 { LIBS += $$PWD/libs/lib/libtoxav.a $$PWD/libs/lib/libopus.a $$PWD/libs/lib/libvpx.a $$PWD/libs/lib/libopenal32.a $$PWD/libs/lib/libtoxcore.a -lws2_32 $$PWD/libs/lib/libsodium.a -lpthread -liphlpapi +} macx { + LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lsodium -lvpx -framework OpenAL } else { LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lsodium -lvpx -lopenal } From 99a4b03cfdb3bd6b506ff8d673a1583d62e665b0 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Fri, 29 Aug 2014 12:52:09 +0200 Subject: [PATCH 097/149] Fix #211 --- core.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/core.cpp b/core.cpp index ae1190dee..dc64dd7e9 100644 --- a/core.cpp +++ b/core.cpp @@ -340,7 +340,7 @@ void Core::onFileControlCallback(Tox* tox, int32_t friendnumber, uint8_t receive file->status = ToxFile::STOPPED; emit static_cast(core)->fileTransferFinished(*file); // confirm receive is complete - tox_file_send_control(tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_FINISHED, nullptr, 0); + tox_file_send_control(tox, file->friendId, 1, file->fileNum, TOX_FILECONTROL_FINISHED, nullptr, 0); removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum); } else @@ -997,14 +997,20 @@ void Core::sendAllFileData(Core *core, ToxFile* file) { qWarning() << QString("Core::sendAllFileData: Error reading from file: %1").arg(file->file->errorString()); delete[] data; - file->sendTimer->start(TOX_FILE_INTERVAL); + file->status = ToxFile::STOPPED; + emit core->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); + tox_file_send_control(core->tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0); + removeFileFromQueue(true, file->friendId, file->fileNum); return; } else if (readSize == 0) { qWarning() << QString("Core::sendAllFileData: Nothing to read from file: %1").arg(file->file->errorString()); delete[] data; - file->sendTimer->start(TOX_FILE_INTERVAL); + file->status = ToxFile::STOPPED; + emit core->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); + tox_file_send_control(core->tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0); + removeFileFromQueue(true, file->friendId, file->fileNum); return; } if (tox_file_send_data(core->tox, file->friendId, file->fileNum, data, readSize) == -1) @@ -1027,12 +1033,12 @@ void Core::sendAllFileData(Core *core, ToxFile* file) } else { - qDebug("Core: File transfer finished"); + //qDebug("Core: File transfer finished"); file->sendTimer->disconnect(); delete file->sendTimer; file->sendTimer = nullptr; tox_file_send_control(core->tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_FINISHED, nullptr, 0); - emit core->fileTransferFinished(*file); + //emit core->fileTransferFinished(*file); } } From f4b1b64ae6df039f2209e2aa8e62ca1a3c0d253c Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Fri, 29 Aug 2014 13:40:37 +0200 Subject: [PATCH 098/149] Switch self cam view to OpenCV --- qtox.pro | 2 +- widget/camera.cpp | 15 ++++++++++++--- widget/camera.h | 6 +++++- widget/selfcamview.cpp | 22 +++++++++++++++++++--- 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/qtox.pro b/qtox.pro index 1d0a5591d..46ad30c9e 100644 --- a/qtox.pro +++ b/qtox.pro @@ -45,7 +45,7 @@ win32 { } macx { LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lsodium -lvpx -framework OpenAL } else { - LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lsodium -lvpx -lopenal + LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lsodium -lvpx -lopenal -lopencv_core -lopencv_highgui -lopencv_imgproc } #### Static linux build diff --git a/widget/camera.cpp b/widget/camera.cpp index 7b5270bab..c1841f398 100644 --- a/widget/camera.cpp +++ b/widget/camera.cpp @@ -20,6 +20,8 @@ #include #include +using namespace cv; + static inline void fromYCbCrToRGB( uint8_t Y, uint8_t Cb, uint8_t Cr, uint8_t& R, uint8_t& G, uint8_t& B) @@ -75,7 +77,7 @@ void Camera::suscribe() if (refcount <= 0) { refcount = 1; - camera->start(); + cap.open(0); } else refcount++; @@ -87,16 +89,23 @@ void Camera::unsuscribe() if (refcount <= 0) { - camera->stop(); + cap.release(); refcount = 0; } } -QVideoFrame Camera::getLastFrame() +QVideoFrame Camera::getLastVideoFrame() { return lastFrame; } +Mat Camera::getLastFrame() +{ + Mat frame; + cap >> frame; + return frame; +} + bool Camera::start(const QVideoSurfaceFormat &format) { if(supportedFormats.contains(format.pixelFormat())) diff --git a/widget/camera.h b/widget/camera.h index dd085b61b..321778e69 100644 --- a/widget/camera.h +++ b/widget/camera.h @@ -21,6 +21,7 @@ #include #include #include "vpx/vpx_image.h" +#include "opencv2/opencv.hpp" /** * This class is a wrapper to share a camera's captured video frames @@ -39,7 +40,8 @@ public: Camera(); void suscribe(); ///< Call this once before trying to get frames void unsuscribe(); ///< Call this once when you don't need frames anymore - QVideoFrame getLastFrame(); ///< Get the last captured frame + cv::Mat getLastFrame(); ///< Get the last captured frame + QVideoFrame getLastVideoFrame(); ///< Get the last captured frame QImage getLastImage(); ///< Convert the last frame to a QImage (can be expensive !) vpx_image getLastVPXImage(); ///< Convert the last frame to a vpx_image (can be expensive !) bool isFormatSupported(const QVideoSurfaceFormat & format) const; @@ -58,6 +60,8 @@ private: QVideoFrame lastFrame; int frameFormat; QList supportedFormats; + + cv::VideoCapture cap; }; #endif // CAMERA_H diff --git a/widget/selfcamview.cpp b/widget/selfcamview.cpp index d38b773dd..3a453deff 100644 --- a/widget/selfcamview.cpp +++ b/widget/selfcamview.cpp @@ -24,6 +24,8 @@ #include "videosurface.h" #include "widget.h" +using namespace cv; + SelfCamView::SelfCamView(Camera* Cam, QWidget* parent) : QWidget(parent), displayLabel{new QLabel}, mainLayout{new QHBoxLayout()}, cam(Cam) @@ -60,8 +62,22 @@ void SelfCamView::showEvent(QShowEvent* event) event->accept(); } -void SelfCamView::updateDisplay() -{ - displayLabel->setPixmap(QPixmap::fromImage(cam->getLastImage())); +QImage Mat2QImage(const cv::Mat3b &src) { + QImage dest(src.cols, src.rows, QImage::Format_ARGB32); + for (int y = 0; y < src.rows; ++y) { + const cv::Vec3b *srcrow = src[y]; + QRgb *destrow = (QRgb*)dest.scanLine(y); + for (int x = 0; x < src.cols; ++x) { + destrow[x] = qRgba(srcrow[x][2], srcrow[x][1], srcrow[x][0], 255); + } + } + return dest; +} + +void SelfCamView::updateDisplay() +{ + Mat frame = cam->getLastFrame(); + + displayLabel->setPixmap(QPixmap::fromImage(Mat2QImage(frame))); } From 6348976df793af9f5cb7ec157004683e728cf679 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Fri, 29 Aug 2014 14:20:32 +0200 Subject: [PATCH 099/149] Switch network camera to OpenCV --- widget/camera.cpp | 164 ++++++++++------------------------------- widget/camera.h | 1 - widget/selfcamview.cpp | 17 +---- 3 files changed, 41 insertions(+), 141 deletions(-) diff --git a/widget/camera.cpp b/widget/camera.cpp index c1841f398..75ff3b7cd 100644 --- a/widget/camera.cpp +++ b/widget/camera.cpp @@ -94,11 +94,6 @@ void Camera::unsuscribe() } } -QVideoFrame Camera::getLastVideoFrame() -{ - return lastFrame; -} - Mat Camera::getLastFrame() { Mat frame; @@ -174,148 +169,67 @@ bool Camera::isFormatSupported(const QVideoSurfaceFormat& format) const } } - QImage Camera::getLastImage() { - if (!lastFrame.map(QAbstractVideoBuffer::ReadOnly)) + Mat3b src = getLastFrame(); + QImage dest(src.cols, src.rows, QImage::Format_ARGB32); + for (int y = 0; y < src.rows; ++y) { - qWarning() << "Camera::getLastImage: Error maping last frame"; - return QImage(); + const cv::Vec3b *srcrow = src[y]; + QRgb *destrow = (QRgb*)dest.scanLine(y); + for (int x = 0; x < src.cols; ++x) + destrow[x] = qRgba(srcrow[x][2], srcrow[x][1], srcrow[x][0], 255); } - int w = lastFrame.width(), h = lastFrame.height(); - int bpl = lastFrame.bytesPerLine(), cxbpl = bpl/2; - QImage img(w, h, QImage::Format_RGB32); - - if (frameFormat == QVideoFrame::Format_YUV420P) - { - uint8_t* yData = lastFrame.bits(); - uint8_t* uData = yData + (bpl * h); - uint8_t* vData = uData + (bpl * h / 4); - for (int i = 0; i< h; i++) - { - uint32_t* scanline = (uint32_t*)img.scanLine(i); - for (int j=0; j < bpl; j++) - { - uint8_t Y = yData[i*bpl + j]; - uint8_t U = uData[i/2*cxbpl + j/2]; - uint8_t V = vData[i/2*cxbpl + j/2]; - - uint8_t R, G, B; - fromYCbCrToRGB(Y, U, V, R, G, B); - - scanline[j] = (0xFF<<24) + (R<<16) + (G<<8) + B; - } - } - } - else if (frameFormat == QVideoFrame::Format_YV12) - { - uint8_t* yData = lastFrame.bits(); - uint8_t* vData = yData + (bpl * h); - uint8_t* uData = vData + (bpl * h / 4); - for (int i = 0; i< h; i++) - { - uint32_t* scanline = (uint32_t*)img.scanLine(i); - for (int j=0; j < bpl; j++) - { - uint8_t Y = yData[i*bpl + j]; - uint8_t U = uData[i/2*cxbpl + j/2]; - uint8_t V = vData[i/2*cxbpl + j/2]; - - uint8_t R, G, B; - fromYCbCrToRGB(Y, U, V, R, G, B); - - scanline[j] = (0xFF<<24) + (R<<16) + (G<<8) + B; - } - } - } - else if (frameFormat == QVideoFrame::Format_RGB32) - { - memcpy(img.bits(), lastFrame.bits(), bpl*h); - } - - lastFrame.unmap(); - return img; + return dest; } vpx_image Camera::getLastVPXImage() { + Mat3b frame = getLastFrame(); vpx_image img; - img.w = img.h = 0; - if (!lastFrame.isValid()) - return img; - if (!lastFrame.map(QAbstractVideoBuffer::ReadOnly)) - { - qWarning() << "Camera::getLastVPXImage: Error maping last frame"; - return img; - } - int w = lastFrame.width(), h = lastFrame.height(); - int bpl = lastFrame.bytesPerLine(); + int w = frame.size().width, h = frame.size().height; vpx_img_alloc(&img, VPX_IMG_FMT_I420, w, h, 1); // I420 == YUV420P, same as YV12 with U and V switched - if (frameFormat == QVideoFrame::Format_YUV420P) - { - uint8_t* yData = lastFrame.bits(); - uint8_t* uData = yData + (bpl * h); - uint8_t* vData = uData + (bpl * h / 4); - img.planes[VPX_PLANE_Y] = yData; - img.planes[VPX_PLANE_U] = uData; - img.planes[VPX_PLANE_V] = vData; - } - else if (frameFormat == QVideoFrame::Format_YV12) - { - uint8_t* yData = lastFrame.bits(); - uint8_t* uData = yData + (bpl * h); - uint8_t* vData = uData + (bpl * h / 4); - img.planes[VPX_PLANE_Y] = yData; - img.planes[VPX_PLANE_U] = vData; - img.planes[VPX_PLANE_V] = uData; - } - else if (frameFormat == QVideoFrame::Format_RGB32 || frameFormat == QVideoFrame::Format_ARGB32) - { - qWarning() << "Camera::getLastVPXImage: Using experimental RGB32 conversion code"; - uint8_t* rgb = lastFrame.bits(); - size_t i=0, j=0; + qWarning() << "Camera::getLastVPXImage: Using experimental RGB32 conversion code" << w << ","<> 8) + 16; - img.planes[VPX_PLANE_U][j] = ((-38*r + -74*g + 112*b) >> 8) + 128; - img.planes[VPX_PLANE_V][j] = ((112*r + -94*g + -18*b) >> 8) + 128; - i++; - j++; + img.planes[VPX_PLANE_Y][i] = ((66*r + 129*g + 25*b) >> 8) + 16; + img.planes[VPX_PLANE_U][j] = ((-38*r + -74*g + 112*b) >> 8) + 128; + img.planes[VPX_PLANE_V][j] = ((112*r + -94*g + -18*b) >> 8) + 128; + i++; + j++; - r = rgb[4 * i + 1]; - g = rgb[4 * i + 2]; - b = rgb[4 * i + 3]; - - img.planes[VPX_PLANE_Y][i] = ((66*r + 129*g + 25*b) >> 8) + 16; - i++; - } + r = srcrow[x+1][2]; + g = srcrow[x+1][1]; + b = srcrow[x+1][0]; + img.planes[VPX_PLANE_Y][i] = ((66*r + 129*g + 25*b) >> 8) + 16; + i++; } - else + } + else + { + for( int x = 0; x < w; x += 1 ) { - for( int x = 0; x < w; x += 1 ) - { - uint8_t r = rgb[4 * i + 1]; - uint8_t g = rgb[4 * i + 2]; - uint8_t b = rgb[4 * i + 3]; + uint8_t r = srcrow[x][2]; + uint8_t g = srcrow[x][1]; + uint8_t b = srcrow[x][0]; - img.planes[VPX_PLANE_Y][i] = ((66*r + 129*g + 25*b) >> 8) + 16; - i++; - } + img.planes[VPX_PLANE_Y][i] = ((66*r + 129*g + 25*b) >> 8) + 16; + i++; } } } - lastFrame.unmap(); return img; - } diff --git a/widget/camera.h b/widget/camera.h index 321778e69..95ac3e185 100644 --- a/widget/camera.h +++ b/widget/camera.h @@ -41,7 +41,6 @@ public: void suscribe(); ///< Call this once before trying to get frames void unsuscribe(); ///< Call this once when you don't need frames anymore cv::Mat getLastFrame(); ///< Get the last captured frame - QVideoFrame getLastVideoFrame(); ///< Get the last captured frame QImage getLastImage(); ///< Convert the last frame to a QImage (can be expensive !) vpx_image getLastVPXImage(); ///< Convert the last frame to a vpx_image (can be expensive !) bool isFormatSupported(const QVideoSurfaceFormat & format) const; diff --git a/widget/selfcamview.cpp b/widget/selfcamview.cpp index 3a453deff..4f88a4979 100644 --- a/widget/selfcamview.cpp +++ b/widget/selfcamview.cpp @@ -62,22 +62,9 @@ void SelfCamView::showEvent(QShowEvent* event) event->accept(); } -QImage Mat2QImage(const cv::Mat3b &src) { - QImage dest(src.cols, src.rows, QImage::Format_ARGB32); - for (int y = 0; y < src.rows; ++y) { - const cv::Vec3b *srcrow = src[y]; - QRgb *destrow = (QRgb*)dest.scanLine(y); - for (int x = 0; x < src.cols; ++x) { - destrow[x] = qRgba(srcrow[x][2], srcrow[x][1], srcrow[x][0], 255); - } - } - return dest; -} - void SelfCamView::updateDisplay() { - Mat frame = cam->getLastFrame(); - - displayLabel->setPixmap(QPixmap::fromImage(Mat2QImage(frame))); + cam->getLastVPXImage(); + displayLabel->setPixmap(QPixmap::fromImage(cam->getLastImage())); } From 938650fa40b2ccb6dd6f370d74ee64fa0652eb2f Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Fri, 29 Aug 2014 14:33:19 +0200 Subject: [PATCH 100/149] Color compatibility with uTox --- widget/camera.cpp | 6 +++--- widget/netcamview.cpp | 4 ++-- widget/selfcamview.cpp | 1 - 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/widget/camera.cpp b/widget/camera.cpp index 75ff3b7cd..0c0588b10 100644 --- a/widget/camera.cpp +++ b/widget/camera.cpp @@ -190,7 +190,7 @@ vpx_image Camera::getLastVPXImage() int w = frame.size().width, h = frame.size().height; vpx_img_alloc(&img, VPX_IMG_FMT_I420, w, h, 1); // I420 == YUV420P, same as YV12 with U and V switched - qWarning() << "Camera::getLastVPXImage: Using experimental RGB32 conversion code" << w << ","<> 8) + 16; - img.planes[VPX_PLANE_U][j] = ((-38*r + -74*g + 112*b) >> 8) + 128; - img.planes[VPX_PLANE_V][j] = ((112*r + -94*g + -18*b) >> 8) + 128; + img.planes[VPX_PLANE_V][j] = ((-38*r + -74*g + 112*b) >> 8) + 128; + img.planes[VPX_PLANE_U][j] = ((112*r + -94*g + -18*b) >> 8) + 128; i++; j++; diff --git a/widget/netcamview.cpp b/widget/netcamview.cpp index dd7454972..cd9e78fda 100644 --- a/widget/netcamview.cpp +++ b/widget/netcamview.cpp @@ -89,8 +89,8 @@ QImage NetCamView::convert(vpx_image& frame) QImage img(w, h, QImage::Format_RGB32); uint8_t* yData = frame.planes[VPX_PLANE_Y]; - uint8_t* uData = frame.planes[VPX_PLANE_U]; - uint8_t* vData = frame.planes[VPX_PLANE_V]; + uint8_t* uData = frame.planes[VPX_PLANE_V]; + uint8_t* vData = frame.planes[VPX_PLANE_U]; for (int i = 0; i< h; i++) { uint32_t* scanline = (uint32_t*)img.scanLine(i); diff --git a/widget/selfcamview.cpp b/widget/selfcamview.cpp index 4f88a4979..74cd18a39 100644 --- a/widget/selfcamview.cpp +++ b/widget/selfcamview.cpp @@ -64,7 +64,6 @@ void SelfCamView::showEvent(QShowEvent* event) void SelfCamView::updateDisplay() { - cam->getLastVPXImage(); displayLabel->setPixmap(QPixmap::fromImage(cam->getLastImage())); } From ccdb3b57fd90aff49fae022015ed73134a297636 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Fri, 29 Aug 2014 14:42:38 +0200 Subject: [PATCH 101/149] Remove all Qt video code --- widget/camera.cpp | 124 ++-------------------------------------------- widget/camera.h | 31 ++---------- 2 files changed, 9 insertions(+), 146 deletions(-) diff --git a/widget/camera.cpp b/widget/camera.cpp index 0c0588b10..600376035 100644 --- a/widget/camera.cpp +++ b/widget/camera.cpp @@ -22,54 +22,9 @@ using namespace cv; -static inline void fromYCbCrToRGB( - uint8_t Y, uint8_t Cb, uint8_t Cr, - uint8_t& R, uint8_t& G, uint8_t& B) -{ - int r = Y + ((1436 * (Cr - 128)) >> 10), - g = Y - ((354 * (Cb - 128) + 732 * (Cr - 128)) >> 10), - b = Y + ((1814 * (Cb - 128)) >> 10); - - if(r < 0) { - r = 0; - } else if(r > 255) { - r = 255; - } - - if(g < 0) { - g = 0; - } else if(g > 255) { - g = 255; - } - - if(b < 0) { - b = 0; - } else if(b > 255) { - b = 255; - } - - R = static_cast(r); - G = static_cast(g); - B = static_cast(b); -} - Camera::Camera() - : refcount{0}, camera{new QCamera} + : refcount{0} { - camera->setCaptureMode(QCamera::CaptureVideo); - camera->setViewfinder(this); - -#if 0 // Crashes on Windows - QMediaService *m = camera->service(); - QVideoEncoderSettingsControl *enc = m->requestControl(); - QVideoEncoderSettings sets = enc->videoSettings(); - sets.setResolution(640, 480); - enc->setVideoSettings(sets); -#endif - - connect(camera, SIGNAL(error(QCamera::Error)), this, SLOT(onCameraError(QCamera::Error))); - - supportedFormats << QVideoFrame::Format_YUV420P << QVideoFrame::Format_YV12 << QVideoFrame::Format_RGB32; } void Camera::suscribe() @@ -77,7 +32,7 @@ void Camera::suscribe() if (refcount <= 0) { refcount = 1; - cap.open(0); + cam.open(0); } else refcount++; @@ -89,7 +44,7 @@ void Camera::unsuscribe() if (refcount <= 0) { - cap.release(); + cam.release(); refcount = 0; } } @@ -97,78 +52,10 @@ void Camera::unsuscribe() Mat Camera::getLastFrame() { Mat frame; - cap >> frame; + cam >> frame; return frame; } -bool Camera::start(const QVideoSurfaceFormat &format) -{ - if(supportedFormats.contains(format.pixelFormat())) - { - frameFormat = format.pixelFormat(); - QAbstractVideoSurface::start(format); - return true; - } - else - { - QMessageBox::warning(0, "Camera error", "The camera only supports rare video formats, can't use it"); - return false; - } -} - -bool Camera::present(const QVideoFrame &frame) -{ - QVideoFrame frameMap(frame); // Basically a const_cast because shallow copies - if (!frameMap.map(QAbstractVideoBuffer::ReadOnly)) - { - qWarning() << "Camera::present: Unable to map frame"; - return false; - } - int w = frameMap.width(), h = frameMap.height(); - int bpl = frameMap.bytesPerLine(), size = frameMap.mappedBytes(); - QVideoFrame frameCopy(size, QSize(w, h), bpl, frameMap.pixelFormat()); - frameCopy.map(QAbstractVideoBuffer::WriteOnly); - memcpy(frameCopy.bits(), frameMap.bits(), size); - frameCopy.unmap(); - lastFrame = frameCopy; - frameMap.unmap(); - return true; -} - -QList Camera::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const -{ - if (handleType == QAbstractVideoBuffer::NoHandle) - return supportedFormats; - else - return QList(); -} - -void Camera::onCameraError(QCamera::Error value) -{ - QMessageBox::warning(0,"Camera error",QString("Error %1 : %2") - .arg(value).arg(camera->errorString())); -} - -bool Camera::isFormatSupported(const QVideoSurfaceFormat& format) const -{ - if (format.pixelFormat() == 0) - { - //QMessageBox::warning(0, "Camera eror","The camera's video format is not supported !"); - return QAbstractVideoSurface::isFormatSupported(format); - } - else if(supportedFormats.contains(format.pixelFormat())) - { - return true; - } - else - { - QMessageBox::warning(0, tr("Camera eror"), - tr("Camera format %1 not supported, can't use the camera") - .arg(format.pixelFormat())); - return false; - } -} - QImage Camera::getLastImage() { Mat3b src = getLastFrame(); @@ -190,9 +77,7 @@ vpx_image Camera::getLastVPXImage() int w = frame.size().width, h = frame.size().height; vpx_img_alloc(&img, VPX_IMG_FMT_I420, w, h, 1); // I420 == YUV420P, same as YV12 with U and V switched - //qWarning() << "Camera::getLastVPXImage: Using experimental RGB32 conversion code" << w << ","< -#include -#include +#include #include "vpx/vpx_image.h" #include "opencv2/opencv.hpp" /** * This class is a wrapper to share a camera's captured video frames - * In Qt cameras normally only send their frames to a single output at a time - * So you can't, for example, send the frames over the network - * and output them to a widget on the screen at the same time - * - * Instead this class allows objects to surscribe and unsuscribe, starting - * the camera only when needed, and giving access to the last frame + * It allows objects to suscribe and unsuscribe to the stream, starting + * the camera only when needed, and giving access to the last frames **/ -class Camera : private QAbstractVideoSurface +class Camera { - Q_OBJECT public: Camera(); void suscribe(); ///< Call this once before trying to get frames @@ -43,24 +36,10 @@ public: cv::Mat getLastFrame(); ///< Get the last captured frame QImage getLastImage(); ///< Convert the last frame to a QImage (can be expensive !) vpx_image getLastVPXImage(); ///< Convert the last frame to a vpx_image (can be expensive !) - bool isFormatSupported(const QVideoSurfaceFormat & format) const; - -private slots: - void onCameraError(QCamera::Error value); - -private: - bool start(const QVideoSurfaceFormat &format); - bool present(const QVideoFrame &frame); - QList supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const; private: int refcount; ///< Number of users suscribed to the camera - QCamera *camera; - QVideoFrame lastFrame; - int frameFormat; - QList supportedFormats; - - cv::VideoCapture cap; + cv::VideoCapture cam; ///< OpenCV camera capture opbject }; #endif // CAMERA_H From 84d6c1063e88cd33e8d5978d2dfb91fc278d4de5 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Fri, 29 Aug 2014 15:39:30 +0200 Subject: [PATCH 102/149] Update Mac build config --- qtox.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qtox.pro b/qtox.pro index 46ad30c9e..9a38dccda 100644 --- a/qtox.pro +++ b/qtox.pro @@ -43,7 +43,7 @@ INCLUDEPATH += libs/include win32 { LIBS += $$PWD/libs/lib/libtoxav.a $$PWD/libs/lib/libopus.a $$PWD/libs/lib/libvpx.a $$PWD/libs/lib/libopenal32.a $$PWD/libs/lib/libtoxcore.a -lws2_32 $$PWD/libs/lib/libsodium.a -lpthread -liphlpapi } macx { - LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lsodium -lvpx -framework OpenAL + LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lsodium -lvpx -framework OpenAL -lopencv_core -lopencv_highgui -lopencv_imgproc } else { LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lsodium -lvpx -lopenal -lopencv_core -lopencv_highgui -lopencv_imgproc } From bd1ca80ffdf9c83ff8ca628cda8bb16a209f6c47 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Fri, 29 Aug 2014 18:16:16 +0200 Subject: [PATCH 103/149] Fix #213 --- widget/form/chatform.cpp | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index f11936b12..176585c61 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -411,6 +411,7 @@ void ChatForm::onAvInvite(int FriendId, int CallId, bool video) void ChatForm::onAvStart(int FriendId, int CallId, bool video) { + audioInputFlag = true; if (FriendId != f->friendId) return; callId = CallId; @@ -437,6 +438,7 @@ void ChatForm::onAvStart(int FriendId, int CallId, bool video) void ChatForm::onAvCancel(int FriendId, int) { + audioInputFlag = false; if (FriendId != f->friendId) return; callButton->disconnect(); @@ -452,6 +454,7 @@ void ChatForm::onAvCancel(int FriendId, int) void ChatForm::onAvEnd(int FriendId, int) { + audioInputFlag = false; if (FriendId != f->friendId) return; callButton->disconnect(); @@ -492,6 +495,7 @@ void ChatForm::onAvRinging(int FriendId, int CallId, bool video) void ChatForm::onAvStarting(int FriendId, int, bool video) { + audioInputFlag = true; if (FriendId != f->friendId) return; callButton->disconnect(); @@ -517,6 +521,7 @@ void ChatForm::onAvStarting(int FriendId, int, bool video) void ChatForm::onAvEnding(int FriendId, int) { + audioInputFlag = false; if (FriendId != f->friendId) return; callButton->disconnect(); @@ -534,6 +539,7 @@ void ChatForm::onAvEnding(int FriendId, int) void ChatForm::onAvRequestTimeout(int FriendId, int) { + audioInputFlag = false; if (FriendId != f->friendId) return; callButton->disconnect(); @@ -551,6 +557,7 @@ void ChatForm::onAvRequestTimeout(int FriendId, int) void ChatForm::onAvPeerTimeout(int FriendId, int) { + audioInputFlag = false; if (FriendId != f->friendId) return; callButton->disconnect(); @@ -568,13 +575,13 @@ void ChatForm::onAvPeerTimeout(int FriendId, int) void ChatForm::onAnswerCallTriggered() { - audioInputFlag = !audioInputFlag; + audioInputFlag = true; emit answerCall(callId); } void ChatForm::onHangupCallTriggered() { - audioInputFlag = !audioInputFlag; + audioInputFlag = false; emit hangupCall(callId); micButton->setObjectName("green"); micButton->style()->polish(micButton); @@ -582,7 +589,7 @@ void ChatForm::onHangupCallTriggered() void ChatForm::onCallTriggered() { - audioInputFlag = !audioInputFlag; + audioInputFlag = true; callButton->disconnect(); videoButton->disconnect(); emit startCall(f->friendId); @@ -590,6 +597,7 @@ void ChatForm::onCallTriggered() void ChatForm::onVideoCallTriggered() { + audioInputFlag = true; callButton->disconnect(); videoButton->disconnect(); emit startVideoCall(f->friendId, true); @@ -597,7 +605,7 @@ void ChatForm::onVideoCallTriggered() void ChatForm::onCancelCallTriggered() { - audioInputFlag = !audioInputFlag; + audioInputFlag = false; callButton->disconnect(); videoButton->disconnect(); callButton->setObjectName("green"); @@ -682,18 +690,18 @@ void ChatForm::onEmoteInsertRequested(QString str) void ChatForm::onMicMuteToggle() { - if (audioInputFlag == true) + if (audioInputFlag == true) { - emit micMuteToggle(callId); - if (micButton->objectName() == "red") + emit micMuteToggle(callId); + if (micButton->objectName() == "red") { - micButton->setObjectName("green"); - micButton->style()->polish(micButton); + micButton->setObjectName("green"); + micButton->style()->polish(micButton); } - else + else { - micButton->setObjectName("red"); - micButton->style()->polish(micButton); + micButton->setObjectName("red"); + micButton->style()->polish(micButton); } } } From 3fc9cc0d83ed0f26b374d0b273576c8faec6fe7e Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Fri, 29 Aug 2014 19:20:34 +0200 Subject: [PATCH 104/149] Fix #219, handle av media changes Can now start or stop video on demand of the peer --- core.h | 4 ++-- coreav.cpp | 38 ++++++++++++++++++++++++++++++-------- widget/form/chatform.cpp | 12 ++++++++++++ widget/form/chatform.h | 1 + widget/widget.cpp | 1 + 5 files changed, 46 insertions(+), 10 deletions(-) diff --git a/core.h b/core.h index fe2a332a7..40fe53f0c 100644 --- a/core.h +++ b/core.h @@ -233,7 +233,7 @@ signals: void avEnding(int friendId, int callIndex); void avRequestTimeout(int friendId, int callIndex); void avPeerTimeout(int friendId, int callIndex); - void avMediaChange(int friendId, int callIndex); + void avMediaChange(int friendId, int callIndex, bool videoEnabled); void videoFrameReceived(vpx_image* frame); @@ -265,7 +265,7 @@ private: static void onAvEnding(void* toxav, int32_t call_index, void* core); static void onAvRequestTimeout(void* toxav, int32_t call_index, void* core); static void onAvPeerTimeout(void* toxav, int32_t call_index, void* core); - static void onAvMediaChange(void* toxav, int32_t call_index, void* core); + static void onAvMediaChange(void *toxav, int32_t call_index, void* core); static void prepareCall(int friendId, int callId, ToxAv *toxav, bool videoEnabled); static void cleanupCall(int callId); diff --git a/coreav.cpp b/coreav.cpp index f64a90ae0..e8fc38514 100644 --- a/coreav.cpp +++ b/coreav.cpp @@ -54,19 +54,37 @@ void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled calls[callId].sendAudioTimer->setSingleShot(true); connect(calls[callId].sendAudioTimer, &QTimer::timeout, [=](){sendCallAudio(callId,toxav);}); calls[callId].sendAudioTimer->start(); + calls[callId].sendVideoTimer->setInterval(50); + calls[callId].sendVideoTimer->setSingleShot(true); if (calls[callId].videoEnabled) { - calls[callId].sendVideoTimer->setInterval(50); - calls[callId].sendVideoTimer->setSingleShot(true); calls[callId].sendVideoTimer->start(); Widget::getInstance()->getCamera()->suscribe(); } } -void Core::onAvMediaChange(void*, int32_t, void*) +void Core::onAvMediaChange(void* toxav, int32_t callId, void* core) { - // HALP, PLS COMPLETE MEH - qWarning() << "If you see this, please complain on GitHub about seeing me! (Don't forget to say what caused me!)"; + ToxAvCSettings settings; + toxav_get_peer_csettings((ToxAv*)toxav, callId, 0, &settings); + int friendId = toxav_get_peer_id((ToxAv*)toxav, callId, 0); + + qWarning() << "Core: Received media change from friend "<stop(); + Widget::getInstance()->getCamera()->unsuscribe(); + emit ((Core*)core)->avMediaChange(friendId, callId, false); + } + else + { + Widget::getInstance()->getCamera()->suscribe(); + calls[callId].videoEnabled = true; + calls[callId].sendVideoTimer->start(); + emit ((Core*)core)->avMediaChange(friendId, callId, true); + } } void Core::answerCall(int callId) @@ -241,7 +259,9 @@ void Core::sendCallVideo(int callId) vpx_img_free(&frame); } else + { qDebug("Core::sendCallVideo: Invalid frame (bad camera ?)"); + } calls[callId].sendVideoTimer->start(); } @@ -262,11 +282,11 @@ void Core::micMuteToggle(int callId) calls[callId].muteMic = !calls[callId].muteMic; } -void Core::onAvCancel(void* _toxav, int32_t call_index, void* core) +void Core::onAvCancel(void* _toxav, int32_t callId, void* core) { ToxAv* toxav = static_cast(_toxav); - int friendId = toxav_get_peer_id(toxav, call_index, 0); + int friendId = toxav_get_peer_id(toxav, callId, 0); if (friendId < 0) { qWarning() << "Core: Received invalid AV cancel"; @@ -274,7 +294,9 @@ void Core::onAvCancel(void* _toxav, int32_t call_index, void* core) } qDebug() << QString("Core: AV cancel from %1").arg(friendId); - emit static_cast(core)->avCancel(friendId, call_index); + calls[callId].active = false; + + emit static_cast(core)->avCancel(friendId, callId); } void Core::onAvReject(void*, int32_t, void*) diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index 176585c61..bccff0bc8 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -573,6 +573,18 @@ void ChatForm::onAvPeerTimeout(int FriendId, int) netcam->hide(); } +void ChatForm::onAvMediaChange(int, int, bool video) +{ + if (video) + { + netcam->show(); + } + else + { + netcam->hide(); + } +} + void ChatForm::onAnswerCallTriggered() { audioInputFlag = true; diff --git a/widget/form/chatform.h b/widget/form/chatform.h index d29d9e8f1..dd746d6c1 100644 --- a/widget/form/chatform.h +++ b/widget/form/chatform.h @@ -72,6 +72,7 @@ public slots: void onAvEnding(int FriendId, int CallId); void onAvRequestTimeout(int FriendId, int CallId); void onAvPeerTimeout(int FriendId, int CallId); + void onAvMediaChange(int FriendId, int CallId, bool video); void onMicMuteToggle(); private slots: diff --git a/widget/widget.cpp b/widget/widget.cpp index 8c74be7a6..58a1724dc 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -435,6 +435,7 @@ void Widget::addFriend(int friendId, const QString &userId) connect(core, &Core::avEnding, newfriend->chatForm, &ChatForm::onAvEnding); connect(core, &Core::avRequestTimeout, newfriend->chatForm, &ChatForm::onAvRequestTimeout); connect(core, &Core::avPeerTimeout, newfriend->chatForm, &ChatForm::onAvPeerTimeout); + connect(core, &Core::avMediaChange, newfriend->chatForm, &ChatForm::onAvMediaChange); } void Widget::addFriendFailed(const QString&) From 5b617dd4fbade167d41ce1ffb1366a856e7de806 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Fri, 29 Aug 2014 19:28:22 +0200 Subject: [PATCH 105/149] Always unmute mic when a call ends Since the mute mic button will be disabled --- widget/form/chatform.cpp | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index bccff0bc8..a95f0a076 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -311,6 +311,7 @@ void ChatForm::startFileSend(ToxFile file) { if (file.friendId != f->friendId) return; + QLabel *author = new QLabel(Widget::getInstance()->getUsername()); QLabel *date = new QLabel(QTime::currentTime().toString("hh:mm")); QScrollBar* scroll = chatArea->verticalScrollBar(); @@ -347,6 +348,7 @@ void ChatForm::onFileRecvRequest(ToxFile file) { if (file.friendId != f->friendId) return; + QLabel *author = new QLabel(f->getName()); QLabel *date = new QLabel(QTime::currentTime().toString("hh:mm")); QScrollBar* scroll = chatArea->verticalScrollBar(); @@ -380,6 +382,7 @@ void ChatForm::onAvInvite(int FriendId, int CallId, bool video) { if (FriendId != f->friendId) return; + callId = CallId; callButton->disconnect(); videoButton->disconnect(); @@ -411,9 +414,10 @@ void ChatForm::onAvInvite(int FriendId, int CallId, bool video) void ChatForm::onAvStart(int FriendId, int CallId, bool video) { - audioInputFlag = true; if (FriendId != f->friendId) return; + + audioInputFlag = true; callId = CallId; callButton->disconnect(); videoButton->disconnect(); @@ -438,9 +442,12 @@ void ChatForm::onAvStart(int FriendId, int CallId, bool video) void ChatForm::onAvCancel(int FriendId, int) { - audioInputFlag = false; if (FriendId != f->friendId) return; + + audioInputFlag = false; + micButton->setObjectName("green"); + micButton->style()->polish(micButton); callButton->disconnect(); videoButton->disconnect(); callButton->setObjectName("green"); @@ -454,9 +461,12 @@ void ChatForm::onAvCancel(int FriendId, int) void ChatForm::onAvEnd(int FriendId, int) { - audioInputFlag = false; if (FriendId != f->friendId) return; + + audioInputFlag = false; + micButton->setObjectName("green"); + micButton->style()->polish(micButton); callButton->disconnect(); videoButton->disconnect(); callButton->setObjectName("green"); @@ -472,6 +482,7 @@ void ChatForm::onAvRinging(int FriendId, int CallId, bool video) { if (FriendId != f->friendId) return; + callId = CallId; callButton->disconnect(); videoButton->disconnect(); @@ -495,9 +506,9 @@ void ChatForm::onAvRinging(int FriendId, int CallId, bool video) void ChatForm::onAvStarting(int FriendId, int, bool video) { - audioInputFlag = true; if (FriendId != f->friendId) return; + callButton->disconnect(); videoButton->disconnect(); if (video) @@ -521,9 +532,12 @@ void ChatForm::onAvStarting(int FriendId, int, bool video) void ChatForm::onAvEnding(int FriendId, int) { - audioInputFlag = false; if (FriendId != f->friendId) return; + + audioInputFlag = false; + micButton->setObjectName("green"); + micButton->style()->polish(micButton); callButton->disconnect(); videoButton->disconnect(); callButton->setObjectName("green"); @@ -539,9 +553,12 @@ void ChatForm::onAvEnding(int FriendId, int) void ChatForm::onAvRequestTimeout(int FriendId, int) { - audioInputFlag = false; if (FriendId != f->friendId) return; + + audioInputFlag = false; + micButton->setObjectName("green"); + micButton->style()->polish(micButton); callButton->disconnect(); videoButton->disconnect(); callButton->setObjectName("green"); @@ -557,9 +574,12 @@ void ChatForm::onAvRequestTimeout(int FriendId, int) void ChatForm::onAvPeerTimeout(int FriendId, int) { - audioInputFlag = false; if (FriendId != f->friendId) return; + + audioInputFlag = false; + micButton->setObjectName("green"); + micButton->style()->polish(micButton); callButton->disconnect(); videoButton->disconnect(); callButton->setObjectName("green"); @@ -618,6 +638,8 @@ void ChatForm::onVideoCallTriggered() void ChatForm::onCancelCallTriggered() { audioInputFlag = false; + micButton->setObjectName("green"); + micButton->style()->polish(micButton); callButton->disconnect(); videoButton->disconnect(); callButton->setObjectName("green"); From 35731e1f53f3ddce8f5fbcce636585f24a88739e Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sat, 30 Aug 2014 14:40:41 +0200 Subject: [PATCH 106/149] Use a global AL context, not per-call --- core.cpp | 30 ++++++++++++++++++++++++++++++ core.h | 5 +++-- coreav.cpp | 41 ++++++++--------------------------------- 3 files changed, 41 insertions(+), 35 deletions(-) diff --git a/core.cpp b/core.cpp index dc64dd7e9..4709a3ee8 100644 --- a/core.cpp +++ b/core.cpp @@ -63,6 +63,26 @@ Core::Core(Camera* cam, QThread *coreThread) : calls[i].sendVideoTimer->moveToThread(coreThread); connect(calls[i].sendVideoTimer, &QTimer::timeout, [this,i](){sendCallVideo(i);}); } + + // OpenAL init + alOutDev = alcOpenDevice(nullptr); + if (!alOutDev) + { + qWarning() << "Core: Cannot open output audio device"; + } + else + { + alContext=alcCreateContext(alOutDev,nullptr); + if (!alcMakeContextCurrent(alContext)) + { + qWarning() << "Core: Cannot create output audio context"; + alcCloseDevice(alOutDev); + } + } + alInDev = alcCaptureOpenDevice(NULL,av_DefaultSettings.audio_sample_rate, AL_FORMAT_MONO16, + (av_DefaultSettings.audio_frame_duration * av_DefaultSettings.audio_sample_rate * 4) / 1000); + if (!alInDev) + qWarning() << "Core: Cannot open input audio device"; } Core::~Core() @@ -78,6 +98,16 @@ Core::~Core() delete[] videobuf; videobuf=nullptr; } + + if (alContext) + { + alcMakeContextCurrent(nullptr); + alcDestroyContext(alContext); + } + if (alOutDev) + alcCloseDevice(alOutDev); + if (alInDev) + alcCaptureCloseDevice(alInDev); } void Core::start() diff --git a/core.h b/core.h index 40fe53f0c..32c34c39d 100644 --- a/core.h +++ b/core.h @@ -104,8 +104,6 @@ public: bool videoEnabled; bool active; bool muteMic; - ALCdevice* alOutDev, *alInDev; - ALCcontext* alContext; ALuint alSource; }; @@ -303,6 +301,9 @@ private: static const int videobufsize; static uint8_t* videobuf; static int videoBusyness; // Used to know when to drop frames + + static ALCdevice* alOutDev, *alInDev; + static ALCcontext* alContext; }; #endif // CORE_HPP diff --git a/coreav.cpp b/coreav.cpp index e8fc38514..cb4a518be 100644 --- a/coreav.cpp +++ b/coreav.cpp @@ -6,6 +6,9 @@ const int Core::videobufsize{TOXAV_MAX_VIDEO_WIDTH * TOXAV_MAX_VIDEO_HEIGHT * 4} uint8_t* Core::videobuf; int Core::videoBusyness; +ALCdevice* Core::alOutDev, *Core::alInDev; +ALCcontext* Core::alContext; + void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled) { qDebug() << QString("Core: preparing call %1").arg(callId); @@ -20,33 +23,9 @@ void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled calls[callId].videoEnabled = videoEnabled; toxav_prepare_transmission(toxav, callId, av_jbufdc, av_VADd, videoEnabled); - // Audio output - calls[callId].alOutDev = alcOpenDevice(nullptr); - if (!calls[callId].alOutDev) - { - qWarning() << "Coreav: Cannot open output audio device, hanging up call"; - toxav_hangup(toxav, callId); - return; - } - calls[callId].alContext=alcCreateContext(calls[callId].alOutDev,nullptr); - if (!alcMakeContextCurrent(calls[callId].alContext)) - { - qWarning() << "Coreav: Cannot create output audio context, hanging up call"; - alcCloseDevice(calls[callId].alOutDev); - toxav_hangup(toxav, callId); - return; - } + // Audio alGenSources(1, &calls[callId].alSource); - - // Audio Input - calls[callId].alInDev = alcCaptureOpenDevice(NULL,av_DefaultSettings.audio_sample_rate, AL_FORMAT_MONO16, (av_DefaultSettings.audio_frame_duration * av_DefaultSettings.audio_sample_rate * 4) / 1000); - if (!calls[callId].alInDev) - { - qWarning() << "Coreav: Cannot open input audio device, hanging up call"; - toxav_hangup(toxav, callId); - return; - } - alcCaptureStart(calls[callId].alInDev); + alcCaptureStart(alInDev); // Go calls[callId].active = true; @@ -164,11 +143,7 @@ void Core::cleanupCall(int callId) calls[callId].sendVideoTimer->stop(); if (calls[callId].videoEnabled) Widget::getInstance()->getCamera()->unsuscribe(); - alcMakeContextCurrent(nullptr); - alcDestroyContext(calls[callId].alContext); - alcCloseDevice(calls[callId].alOutDev); - alcCaptureStop(calls[callId].alInDev); - alcCaptureCloseDevice(calls[callId].alInDev); + alcCaptureStop(alInDev); } void Core::playCallAudio(ToxAv* toxav, int32_t callId, int16_t *data, int samples, void *user_data) @@ -199,10 +174,10 @@ void Core::sendCallAudio(int callId, ToxAv* toxav) bool frame = false; ALint samples; - alcGetIntegerv(calls[callId].alInDev, ALC_CAPTURE_SAMPLES, sizeof(samples), &samples); + alcGetIntegerv(alInDev, ALC_CAPTURE_SAMPLES, sizeof(samples), &samples); if(samples >= framesize) { - alcCaptureSamples(calls[callId].alInDev, buf, framesize); + alcCaptureSamples(alInDev, buf, framesize); frame = 1; } From f97729261a3abc27891843d933fc02eb079db391 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sat, 30 Aug 2014 15:15:23 +0200 Subject: [PATCH 107/149] Clean & remove old code and dependencies We don't use QtMultimedia and OpenCV_imgproc anymore Fixes #218 --- core.cpp | 2 + core.h | 6 +-- coreav.cpp | 1 + friendlist.cpp | 1 + qtox.pro | 8 ++- widget/camera.cpp | 3 -- widget/friendlistwidget.cpp | 1 + widget/selfcamview.cpp | 4 -- widget/videosurface.cpp | 103 ------------------------------------ widget/videosurface.h | 42 --------------- widget/widget.cpp | 17 +++++- 11 files changed, 25 insertions(+), 163 deletions(-) delete mode 100644 widget/videosurface.cpp delete mode 100644 widget/videosurface.h diff --git a/core.cpp b/core.cpp index 4709a3ee8..9c76975b0 100644 --- a/core.cpp +++ b/core.cpp @@ -78,6 +78,8 @@ Core::Core(Camera* cam, QThread *coreThread) : qWarning() << "Core: Cannot create output audio context"; alcCloseDevice(alOutDev); } + else + alGenSources(1, &alMainSource); } alInDev = alcCaptureOpenDevice(NULL,av_DefaultSettings.audio_sample_rate, AL_FORMAT_MONO16, (av_DefaultSettings.audio_frame_duration * av_DefaultSettings.audio_sample_rate * 4) / 1000); diff --git a/core.h b/core.h index 32c34c39d..d94f65473 100644 --- a/core.h +++ b/core.h @@ -31,10 +31,6 @@ #include #include #include -#include -#include -#include -#include #define TOXAV_MAX_CALLS 16 #define GROUPCHAT_MAX_SIZE 32 @@ -304,6 +300,8 @@ private: static ALCdevice* alOutDev, *alInDev; static ALCcontext* alContext; +public: + static ALuint alMainSource; }; #endif // CORE_HPP diff --git a/coreav.cpp b/coreav.cpp index cb4a518be..2b18e37d4 100644 --- a/coreav.cpp +++ b/coreav.cpp @@ -8,6 +8,7 @@ int Core::videoBusyness; ALCdevice* Core::alOutDev, *Core::alInDev; ALCcontext* Core::alContext; +ALuint Core::alMainSource; void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled) { diff --git a/friendlist.cpp b/friendlist.cpp index 08ecb903d..6547c408c 100644 --- a/friendlist.cpp +++ b/friendlist.cpp @@ -17,6 +17,7 @@ #include "friend.h" #include "friendlist.h" #include +#include QList FriendList::friendList; diff --git a/qtox.pro b/qtox.pro index 9a38dccda..26cb6e0f1 100644 --- a/qtox.pro +++ b/qtox.pro @@ -20,7 +20,7 @@ # See the COPYING file for more details. -QT += core gui network multimedia multimediawidgets xml +QT += core gui network xml greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = qtox @@ -43,9 +43,9 @@ INCLUDEPATH += libs/include win32 { LIBS += $$PWD/libs/lib/libtoxav.a $$PWD/libs/lib/libopus.a $$PWD/libs/lib/libvpx.a $$PWD/libs/lib/libopenal32.a $$PWD/libs/lib/libtoxcore.a -lws2_32 $$PWD/libs/lib/libsodium.a -lpthread -liphlpapi } macx { - LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lsodium -lvpx -framework OpenAL -lopencv_core -lopencv_highgui -lopencv_imgproc + LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lsodium -lvpx -framework OpenAL -lopencv_core -lopencv_highgui } else { - LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lsodium -lvpx -lopenal -lopencv_core -lopencv_highgui -lopencv_imgproc + LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lsodium -lvpx -lopenal -lopencv_core -lopencv_highgui } #### Static linux build @@ -82,7 +82,6 @@ HEADERS += widget/form/addfriendform.h \ cdata.h \ cstring.h \ widget/selfcamview.h \ - widget/videosurface.h \ widget/camera.h \ widget/netcamview.h \ widget/tool/clickablelabel.h \ @@ -119,7 +118,6 @@ SOURCES += \ cdata.cpp \ cstring.cpp \ widget/selfcamview.cpp \ - widget/videosurface.cpp \ widget/camera.cpp \ widget/netcamview.cpp \ widget/tool/clickablelabel.cpp \ diff --git a/widget/camera.cpp b/widget/camera.cpp index 600376035..e4a6010c7 100644 --- a/widget/camera.cpp +++ b/widget/camera.cpp @@ -15,10 +15,7 @@ */ #include "camera.h" -#include #include -#include -#include using namespace cv; diff --git a/widget/friendlistwidget.cpp b/widget/friendlistwidget.cpp index 1792e00c5..aced0f297 100644 --- a/widget/friendlistwidget.cpp +++ b/widget/friendlistwidget.cpp @@ -14,6 +14,7 @@ See the COPYING file for more details. */ #include "friendlistwidget.h" +#include FriendListWidget::FriendListWidget(QWidget *parent) : QWidget(parent) diff --git a/widget/selfcamview.cpp b/widget/selfcamview.cpp index 74cd18a39..2d46e99bb 100644 --- a/widget/selfcamview.cpp +++ b/widget/selfcamview.cpp @@ -15,13 +15,9 @@ */ #include "selfcamview.h" -#include -#include #include #include -#include -#include "videosurface.h" #include "widget.h" using namespace cv; diff --git a/widget/videosurface.cpp b/widget/videosurface.cpp deleted file mode 100644 index 68ec9ff49..000000000 --- a/widget/videosurface.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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. -*/ - -#include "videosurface.h" -#include "core.h" -#include -#include - -VideoSurface::VideoSurface() - : QAbstractVideoSurface() -{ - vpx_img_alloc(&input, VPX_IMG_FMT_YV12, TOXAV_MAX_VIDEO_WIDTH, TOXAV_MAX_VIDEO_HEIGHT, 1); -} - -bool VideoSurface::start(const QVideoSurfaceFormat &format) -{ - mVideoFormat = format; - //start only if format is UYVY, dont handle other format now - if( format.pixelFormat() == QVideoFrame::Format_YV12 ){ - QAbstractVideoSurface::start(format); - return true; - } else { - return false; - } -} - -bool VideoSurface::present(const QVideoFrame&) -{ - /* - mFrame = frame; - - qDebug() << QString("Video: Frame format is %1").arg(mFrame.pixelFormat()); - - stop(); - - //this is necessary to get valid data from frame - mFrame.map(QAbstractVideoBuffer::ReadOnly); - - uchar* data = new uchar[frame.mappedBytes()]; - memcpy(data, frame.bits(), frame.mappedBytes()); - - input.planes[VPX_PLANE_Y] = data; - input.planes[VPX_PLANE_U] = data + (frame.bytesPerLine() * frame.height()); - input.planes[VPX_PLANE_V] = input.planes[VPX_PLANE_U] + (frame.bytesPerLine()/2 * frame.height()/2); - input.planes[VPX_PLANE_ALPHA] = nullptr; - - //qDebug() << QString("Got %1 bytes, first plane is %2 bytes long") - // .arg(frame.mappedBytes()).arg(frame.bytesPerLine() * frame.height()); - - // Slots MUST be called with a direct or blocking connection, or input may die before they return ! - emit videoFrameReady(input); - - - QImage lastImage( mFrame.size(), QImage::Format_RGB16); - const uchar *src = mFrame.bits(); - uchar *dst = lastImage.bits(); - const int srcLineStep = mFrame.bytesPerLine(); - const int dstLineStep = lastImage.bytesPerLine(); - const int h = mFrame.height(); - const int w = mFrame.width(); - - for (int y=0; y < h; y++) { - //this function you can find in qgraphicsvideoitem_maemo5.cpp, - //link is mentioned above - uyvy422_to_rgb16_line_neon(dst, src, w); - src += srcLineStep; - dst += dstLineStep; - } - - mLastFrame = QPixmap::fromImage(lastImage); - //emit signal, other can handle it and do necessary processing - emit frameUpdated(mLastFrame); - - delete[] data; - mFrame.unmap(); - -*/ - return true; -} - -QList VideoSurface::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const -{ - if (handleType == QAbstractVideoBuffer::NoHandle) { - qDebug() << "Video: No handle"; - return QList() << QVideoFrame::Format_YV12; - } else { - qDebug() << "Video: Handle type is not NoHandle"; - return QList(); - } -} diff --git a/widget/videosurface.h b/widget/videosurface.h deleted file mode 100644 index c93ed2c8f..000000000 --- a/widget/videosurface.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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. -*/ - -#ifndef VIDEOSURFACE_H -#define VIDEOSURFACE_H - -#include -#include -#include "vpx/vpx_image.h" - -class VideoSurface : public QAbstractVideoSurface -{ - Q_OBJECT -public: - VideoSurface(); - bool start(const QVideoSurfaceFormat &format); - bool present(const QVideoFrame &frame); - QList supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const; - -signals: - // Slots MUST be called with a direct or blocking connection, or img may die before they return ! - void videoFrameReady(vpx_image img); - -private: - QVideoSurfaceFormat mVideoFormat; - vpx_image_t input; -}; - -#endif // VIDEOSURFACE_H diff --git a/widget/widget.cpp b/widget/widget.cpp index 58a1724dc..cfba03b09 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -28,7 +28,6 @@ #include "style.h" #include #include -#include #include #include #include @@ -569,7 +568,21 @@ void Widget::updateFriendStatusLights(int friendId) void Widget::newMessageAlert() { QApplication::alert(this); - QSound::play(":audio/notification.wav"); + + static QFile sndFile(":audio/notification.wav"); + static QByteArray sndData; + if (sndData.isEmpty()) + { + sndFile.open(QIODevice::ReadOnly); + sndData = sndFile.readAll(); + sndFile.close(); + } + + ALuint buffer; + alGenBuffers(1, &buffer); + alBufferData(buffer, AL_FORMAT_STEREO16, sndData.data(), sndData.size(), 44100); + alSourcei(core->alMainSource, AL_BUFFER, buffer); + alSourcePlay(core->alMainSource); } void Widget::onFriendRequestReceived(const QString& userId, const QString& message) From 53c07fc4a7ece6c1a01ce4f4c684ac5000fdfe3c Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sat, 30 Aug 2014 22:13:27 +0200 Subject: [PATCH 108/149] Improve DHT bootsraping reliability Don't try to spam boostrap nodes, if we've tried enough nodes and none of them worked, chances are our connection is just a little slow, so wait some more before trying even more nodes or we might never see the end of it. May help with #221 --- core.cpp | 17 ++++++++++++++--- core.h | 2 +- res/settings.ini | 2 +- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/core.cpp b/core.cpp index 9c76975b0..50f274ef8 100644 --- a/core.cpp +++ b/core.cpp @@ -738,14 +738,23 @@ void Core::onFileTransferFinished(ToxFile file) void Core::bootstrapDht() { - qDebug() << "Core: Bootstraping DHT"; const Settings& s = Settings::getInstance(); QList dhtServerList = s.getDhtServerList(); int listSize = dhtServerList.size(); - static int j = qrand() % listSize; + static int j = qrand() % listSize, n=0; + + // We couldn't connect after trying 6 different nodes, let's try something else + if (n>3) + { + qDebug() << "Core: We're having trouble connecting to the DHT, slowing down"; + bootstrapTimer->setInterval(TOX_BOOTSTRAP_INTERVAL*(n-1)); + } + else + qDebug() << "Core: Connecting to the DHT ..."; + int i=0; - while (i<5) + while (i < (2 - (n>3))) { const Settings::DhtServer& dhtServer = dhtServerList[j % listSize]; if (tox_bootstrap_from_address(tox, dhtServer.address.toLatin1().data(), @@ -755,8 +764,10 @@ void Core::bootstrapDht() else qDebug() << "Core: Error bootstraping from "+dhtServer.name; + tox_do(tox); j++; i++; + n++; } } diff --git a/core.h b/core.h index d94f65473..130558df4 100644 --- a/core.h +++ b/core.h @@ -36,7 +36,7 @@ #define GROUPCHAT_MAX_SIZE 32 #define TOX_SAVE_INTERVAL 30*1000 #define TOX_FILE_INTERVAL 1 -#define TOX_BOOTSTRAP_INTERVAL 10*1000 +#define TOX_BOOTSTRAP_INTERVAL 5*1000 #define TOXAV_RINGING_TIME 15 // TODO: Put that in the settings diff --git a/res/settings.ini b/res/settings.ini index 94878406f..2a051ab94 100644 --- a/res/settings.ini +++ b/res/settings.ini @@ -1,5 +1,5 @@ [DHT%20Server] -dhtServerList\size=16 +dhtServerList\size=15 dhtServerList\1\name=stqism dhtServerList\1\userId=951C88B7E75C867418ACDB5D273821372BB5BD652740BCDF623A4FA293E75D2F dhtServerList\1\address=192.254.75.98 From 46fd073ba8c5c8bbcd6c714c27e27ae637e58d1d Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 31 Aug 2014 00:20:38 +0200 Subject: [PATCH 109/149] Link toxcore and toxav statically So we don't have to package them separately, since there are no official Tox debian packages on the main archive --- qtox.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qtox.pro b/qtox.pro index 26cb6e0f1..0325643c4 100644 --- a/qtox.pro +++ b/qtox.pro @@ -45,7 +45,7 @@ win32 { } macx { LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lsodium -lvpx -framework OpenAL -lopencv_core -lopencv_highgui } else { - LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lsodium -lvpx -lopenal -lopencv_core -lopencv_highgui + LIBS += -L$$PWD/libs/lib/ -Wl,-Bstatic -ltoxcore -ltoxav -Wl,-Bdynamic -lopus -lsodium -lvpx -lopenal -lopencv_core -lopencv_highgui } #### Static linux build From 95dedc37598cc31866dad60043e48abff41b11f5 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 31 Aug 2014 00:33:11 +0200 Subject: [PATCH 110/149] Link libsodium So we don't have to package it separately --- qtox.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qtox.pro b/qtox.pro index 0325643c4..f085fa41c 100644 --- a/qtox.pro +++ b/qtox.pro @@ -45,7 +45,7 @@ win32 { } macx { LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lsodium -lvpx -framework OpenAL -lopencv_core -lopencv_highgui } else { - LIBS += -L$$PWD/libs/lib/ -Wl,-Bstatic -ltoxcore -ltoxav -Wl,-Bdynamic -lopus -lsodium -lvpx -lopenal -lopencv_core -lopencv_highgui + LIBS += -L$$PWD/libs/lib/ -Wl,-Bstatic -ltoxcore -ltoxav -lsodium -Wl,-Bdynamic -lopus -lvpx -lopenal -lopencv_core -lopencv_highgui } #### Static linux build From 5751e8e4a1145e91d6172edc335902cbecb2f9c1 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 31 Aug 2014 01:55:45 +0200 Subject: [PATCH 111/149] Update install target --- qtox.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qtox.pro b/qtox.pro index f085fa41c..054710073 100644 --- a/qtox.pro +++ b/qtox.pro @@ -36,7 +36,7 @@ TRANSLATIONS = translations/de.ts \ RESOURCES += res.qrc -target.path = /usr/local/bin +target.path = /usr/bin INSTALLS += target INCLUDEPATH += libs/include From 404b5151d7ddd8e4446dffcf8c35182c25f46c72 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 31 Aug 2014 02:33:45 +0200 Subject: [PATCH 112/149] Add debian packaging metadata --- debian/changelog | 5 +++++ debian/compat | 1 + debian/control | 12 ++++++++++++ debian/copyright | 28 ++++++++++++++++++++++++++++ debian/rules | 6 ++++++ debian/source/format | 1 + 6 files changed, 53 insertions(+) create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/rules create mode 100644 debian/source/format diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 000000000..1b56f518a --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +qtox (1.0-1) UNRELEASED; urgency=medium local package + + * Initial release. + + -- John Smith Sat, 30 Aug 2014 23:27:47 +0200 diff --git a/debian/compat b/debian/compat new file mode 100644 index 000000000..ec635144f --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +9 diff --git a/debian/control b/debian/control new file mode 100644 index 000000000..b69c88fdc --- /dev/null +++ b/debian/control @@ -0,0 +1,12 @@ +Source: qtox +Maintainer: John Smith +Section: misc +Priority: optional +Standards-Version: 3.9.5 +Build-Depends: debhelper (>= 9), qt5-qmake, qt5-default, libopenal-dev, libopencv-dev, cdbs + +Package: qtox +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: Tox client + qTox is a powerful Tox client that follows the Tox design guidelines diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 000000000..6770976a6 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,28 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: qtox +Upstream-Contact: John Smith +Source: https://github.com/tux3/qTox + +Files: * +Copyright: 2014 John Smith +License: GPL-3+ + 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 package; if not, write to the Free + Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301 USA + . + On Debian systems, the full text of the GNU General Public + License version 3 can be found in the file + `/usr/share/common-licenses/GPL-3'. diff --git a/debian/rules b/debian/rules new file mode 100644 index 000000000..59830f609 --- /dev/null +++ b/debian/rules @@ -0,0 +1,6 @@ +#!/usr/bin/make -f + +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/class/qmake.mk + +PREFIX=$(CURDIR)/debian/qtox/usr diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 000000000..163aaf8d8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) From 879da4deaaa4bc3e56f97de4979bd287e117f9bc Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 31 Aug 2014 02:35:35 +0200 Subject: [PATCH 113/149] Update Debian Build-Depends --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index b69c88fdc..943501a77 100644 --- a/debian/control +++ b/debian/control @@ -3,7 +3,7 @@ Maintainer: John Smith Section: misc Priority: optional Standards-Version: 3.9.5 -Build-Depends: debhelper (>= 9), qt5-qmake, qt5-default, libopenal-dev, libopencv-dev, cdbs +Build-Depends: debhelper (>= 9), cdbs, qt5-qmake, qt5-default, libopenal-dev, libopencv-dev, libopus-dev Package: qtox Architecture: any From b99c6035a45b84f6646020b2595b4f2dd6771adb Mon Sep 17 00:00:00 2001 From: ReDetection Date: Sun, 31 Aug 2014 10:37:08 +0700 Subject: [PATCH 114/149] fixed build for OS X --- core.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/core.h b/core.h index 130558df4..28888d66a 100644 --- a/core.h +++ b/core.h @@ -20,8 +20,13 @@ #include #include -#include -#include +#if defined(__APPLE__) && defined(__MACH__) + #include + #include +#else + #include + #include +#endif #include #include From e8757569d8e9368f9cb7747e545203c44cb95b49 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 31 Aug 2014 11:39:29 +0200 Subject: [PATCH 115/149] Default to non-package builds, unless STATICPKG=YES Fixes #226 --- debian/rules | 2 +- qtox.pro | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/debian/rules b/debian/rules index 59830f609..6815966a4 100644 --- a/debian/rules +++ b/debian/rules @@ -3,4 +3,4 @@ include /usr/share/cdbs/1/rules/debhelper.mk include /usr/share/cdbs/1/class/qmake.mk -PREFIX=$(CURDIR)/debian/qtox/usr +QMAKE=qmake STATICPKG=YES diff --git a/qtox.pro b/qtox.pro index 054710073..6060257cc 100644 --- a/qtox.pro +++ b/qtox.pro @@ -36,18 +36,25 @@ TRANSLATIONS = translations/de.ts \ RESOURCES += res.qrc -target.path = /usr/bin -INSTALLS += target - INCLUDEPATH += libs/include + +# Rules for Windows, Mac OSX, and Linux win32 { LIBS += $$PWD/libs/lib/libtoxav.a $$PWD/libs/lib/libopus.a $$PWD/libs/lib/libvpx.a $$PWD/libs/lib/libopenal32.a $$PWD/libs/lib/libtoxcore.a -lws2_32 $$PWD/libs/lib/libsodium.a -lpthread -liphlpapi } macx { LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lsodium -lvpx -framework OpenAL -lopencv_core -lopencv_highgui } else { - LIBS += -L$$PWD/libs/lib/ -Wl,-Bstatic -ltoxcore -ltoxav -lsodium -Wl,-Bdynamic -lopus -lvpx -lopenal -lopencv_core -lopencv_highgui + # If we're building a package, static link libtox[core,av] and libsodium, since they are not provided by any package + contains(STATICPKG, YES) { + target.path = /usr/bin + INSTALLS += target + LIBS += -L$$PWD/libs/lib/ -Wl,-Bstatic -ltoxcore -ltoxav -lsodium -Wl,-Bdynamic -lopus -lvpx -lopenal -lopencv_core -lopencv_highgui + } else { + LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lvpx -lopenal -lopencv_core -lopencv_highgui + } } + #### Static linux build #LIBS += -Wl,-Bstatic -ltoxcore -ltoxav -lsodium -lvpx -lopus \ # -lgstbase-0.10 -lgstreamer-0.10 -lgmodule-2.0 -lgstaudio-0.10 -lxml2 \ From fd0c4fe5667f69153e27d89cb16b4d7e72002b4e Mon Sep 17 00:00:00 2001 From: Serg Date: Sun, 31 Aug 2014 17:09:46 +0700 Subject: [PATCH 116/149] Fixed Jenkins OS X download link someone changed image name --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 26822dd3a..0e4f060b8 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ This client runs on Windows, Linux and Mac natively, but is not build regularly Linux users will have to compile the source code themselves if they want the latest updates.
Windows download
-Mac download
+Mac download
Linux download (12st July 2014 20:30 GMT)
Note that the Linux download has not been tested and may not be up to date.
From 4a66026676a67725b7ed2bae761fa93311c5b3a1 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 31 Aug 2014 12:49:41 +0200 Subject: [PATCH 117/149] Fix #174, was only partially fixed --- widget/filetransfertwidget.cpp | 4 ++-- widget/filetransfertwidget.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/widget/filetransfertwidget.cpp b/widget/filetransfertwidget.cpp index b72d54e1a..8236e0cf0 100644 --- a/widget/filetransfertwidget.cpp +++ b/widget/filetransfertwidget.cpp @@ -138,7 +138,7 @@ FileTransfertWidget::FileTransfertWidget(ToxFile File) buttonLayout->setSpacing(0); } -QString FileTransfertWidget::getHumanReadableSize(int size) +QString FileTransfertWidget::getHumanReadableSize(unsigned long long size) { static const char* suffix[] = {"B","kiB","MiB","GiB","TiB"}; int exp = 0; @@ -161,7 +161,7 @@ void FileTransfertWidget::onFileTransferInfo(int FriendId, int FileNum, int64_t qWarning() << "FileTransfertWidget::onFileTransferInfo: Negative transfer speed !"; diff = 0; } - int rawspeed = diff / timediff; + long rawspeed = diff / timediff; speed->setText(getHumanReadableSize(rawspeed)+"/s"); size->setText(getHumanReadableSize(Filesize)); if (!rawspeed) diff --git a/widget/filetransfertwidget.h b/widget/filetransfertwidget.h index c5933eeb5..699c9d548 100644 --- a/widget/filetransfertwidget.h +++ b/widget/filetransfertwidget.h @@ -49,7 +49,7 @@ private slots: void pauseResumeSend(); private: - QString getHumanReadableSize(int size); + QString getHumanReadableSize(unsigned long long size); private: QLabel *pic, *filename, *size, *speed, *eta; From 0deba0ad2469f787b6acf9fc395e1e0444cd2686 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 31 Aug 2014 13:07:31 +0200 Subject: [PATCH 118/149] Fix #228 --- core.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/core.cpp b/core.cpp index 50f274ef8..8c4d29929 100644 --- a/core.cpp +++ b/core.cpp @@ -346,7 +346,14 @@ void Core::onFileControlCallback(Tox* tox, int32_t friendnumber, uint8_t receive .arg(file->fileNum).arg(file->friendId); file->status = ToxFile::STOPPED; emit static_cast(core)->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); - while (file->sendTimer) QThread::msleep(1); // Wait for sendAllFileData to return before deleting the ToxFile + // Wait for sendAllFileData to return before deleting the ToxFile, we MUST ensure this or we'll use after free + while (file->sendTimer) + { + if (!file->sendTimer->isActive()) // Force it to clean itself up if it isn't already done + sendAllFileData(static_cast(core), file); + QThread::msleep(1); + qApp->processEvents(); + } removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum); } else if (receive_send == 1 && control_type == TOX_FILECONTROL_FINISHED) @@ -496,7 +503,7 @@ void Core::pauseResumeFileSend(int friendId, int fileNum) } if (!file) { - qWarning("Core::cancelFileSend: No such file in queue"); + qWarning("Core::pauseResumeFileSend: No such file in queue"); return; } if (file->status == ToxFile::TRANSMITTING) From 51f397104c9e9aa9c5942ec9c3cb0589b1df3600 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 31 Aug 2014 13:13:46 +0200 Subject: [PATCH 119/149] Improve file transfer speed --- core.cpp | 4 ++-- core.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core.cpp b/core.cpp index 8c4d29929..b71c377e1 100644 --- a/core.cpp +++ b/core.cpp @@ -1015,7 +1015,7 @@ void Core::sendAllFileData(Core *core, ToxFile* file) { if (file->status == ToxFile::PAUSED) { - file->sendTimer->start(TOX_FILE_INTERVAL); + file->sendTimer->start(5+TOX_FILE_INTERVAL); return; } else if (file->status == ToxFile::STOPPED) @@ -1069,7 +1069,7 @@ void Core::sendAllFileData(Core *core, ToxFile* file) //core->process(); delete[] data; QThread::msleep(1); - file->sendTimer->start(TOX_FILE_INTERVAL); + file->sendTimer->start(5+TOX_FILE_INTERVAL); return; } delete[] data; diff --git a/core.h b/core.h index 28888d66a..af5de7c4f 100644 --- a/core.h +++ b/core.h @@ -40,7 +40,7 @@ #define TOXAV_MAX_CALLS 16 #define GROUPCHAT_MAX_SIZE 32 #define TOX_SAVE_INTERVAL 30*1000 -#define TOX_FILE_INTERVAL 1 +#define TOX_FILE_INTERVAL 0 #define TOX_BOOTSTRAP_INTERVAL 5*1000 #define TOXAV_RINGING_TIME 15 From 6668cdc1e7c7256b5ce75f67812d12a6971094eb Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 31 Aug 2014 13:27:42 +0200 Subject: [PATCH 120/149] Never use [-]9.9e[+|-]999 format for human readable numbers --- widget/filetransfertwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget/filetransfertwidget.cpp b/widget/filetransfertwidget.cpp index 8236e0cf0..773900b25 100644 --- a/widget/filetransfertwidget.cpp +++ b/widget/filetransfertwidget.cpp @@ -144,7 +144,7 @@ QString FileTransfertWidget::getHumanReadableSize(unsigned long long size) int exp = 0; if (size) exp = std::min( (int) (log(size) / log(1024)), (int) (sizeof(suffix) / sizeof(suffix[0]) - 1)); - return QString().setNum(size / pow(1024, exp),'g',3).append(suffix[exp]); + return QString().setNum(size / pow(1024, exp),'f',3).append(suffix[exp]); } void FileTransfertWidget::onFileTransferInfo(int FriendId, int FileNum, int64_t Filesize, int64_t BytesSent, ToxFile::FileDirection Direction) From efdc7b3a9c11d969e9e485633ea7c259c5107385 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 31 Aug 2014 13:57:59 +0200 Subject: [PATCH 121/149] Fix uninitialized sendTimer pointer --- core.cpp | 9 ++++++--- core.h | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/core.cpp b/core.cpp index b71c377e1..2a46a4ee8 100644 --- a/core.cpp +++ b/core.cpp @@ -347,12 +347,15 @@ void Core::onFileControlCallback(Tox* tox, int32_t friendnumber, uint8_t receive file->status = ToxFile::STOPPED; emit static_cast(core)->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING); // Wait for sendAllFileData to return before deleting the ToxFile, we MUST ensure this or we'll use after free - while (file->sendTimer) + if (file->sendTimer) { - if (!file->sendTimer->isActive()) // Force it to clean itself up if it isn't already done - sendAllFileData(static_cast(core), file); QThread::msleep(1); qApp->processEvents(); + if (file->sendTimer) + { + delete file->sendTimer; + file->sendTimer = nullptr; + } } removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum); } diff --git a/core.h b/core.h index af5de7c4f..154a18351 100644 --- a/core.h +++ b/core.h @@ -78,7 +78,7 @@ struct ToxFile ToxFile()=default; ToxFile(int FileNum, int FriendId, QByteArray FileName, QString FilePath, FileDirection Direction) : fileNum(FileNum), friendId(FriendId), fileName{FileName}, filePath{FilePath}, file{new QFile(filePath)}, - bytesSent{0}, filesize{0}, status{STOPPED}, direction{Direction} {} + bytesSent{0}, filesize{0}, status{STOPPED}, direction{Direction}, sendTimer{nullptr} {} ~ToxFile(){} void setFilePath(QString path) {filePath=path; file->setFileName(path);} bool open(bool write) {return write?file->open(QIODevice::ReadWrite):file->open(QIODevice::ReadOnly);} From 90d426e347be11208bb3a06d06c71f59ca91a9fa Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 31 Aug 2014 14:53:37 +0200 Subject: [PATCH 122/149] Improve file transfer performance --- core.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core.cpp b/core.cpp index 2a46a4ee8..3c6a3057e 100644 --- a/core.cpp +++ b/core.cpp @@ -1072,7 +1072,7 @@ void Core::sendAllFileData(Core *core, ToxFile* file) //core->process(); delete[] data; QThread::msleep(1); - file->sendTimer->start(5+TOX_FILE_INTERVAL); + file->sendTimer->start(TOX_FILE_INTERVAL); return; } delete[] data; From 7fe938a7ca527a148e2a7824beac8d55c8bedfe2 Mon Sep 17 00:00:00 2001 From: apprb Date: Sat, 30 Aug 2014 15:28:00 +0700 Subject: [PATCH 123/149] filenames and paths processing little fix --- core.cpp | 4 ++-- settings.cpp | 6 +++--- smileypack.cpp | 2 +- widget/filetransfertwidget.cpp | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core.cpp b/core.cpp index 3c6a3057e..658908066 100644 --- a/core.cpp +++ b/core.cpp @@ -811,7 +811,7 @@ void Core::checkConnection() void Core::loadConfiguration() { - QString path = Settings::getSettingsDirPath() + '/' + CONFIG_FILE_NAME; + QString path = QDir(Settings::getSettingsDirPath()).filePath(CONFIG_FILE_NAME); QFile configurationFile(path); @@ -862,7 +862,7 @@ void Core::saveConfiguration() return; } - path += '/' + CONFIG_FILE_NAME; + path = directory.filePath(CONFIG_FILE_NAME); QSaveFile configurationFile(path); if (!configurationFile.open(QIODevice::WriteOnly)) { qCritical() << "File " << path << " cannot be opened"; diff --git a/settings.cpp b/settings.cpp index 1662e44b0..b2193e453 100644 --- a/settings.cpp +++ b/settings.cpp @@ -55,7 +55,7 @@ void Settings::load() if (portableSettings.exists()) makeToxPortable=true; - QString filePath = getSettingsDirPath() + '/' + FILENAME; + QString filePath = QDir(getSettingsDirPath()).filePath(FILENAME); //if no settings file exist -- use the default one QFile file(filePath); @@ -125,7 +125,7 @@ void Settings::load() void Settings::save() { - QString filePath = getSettingsDirPath() + '/' + FILENAME; + QString filePath = QDir(getSettingsDirPath()).filePath(FILENAME); save(filePath); } @@ -194,7 +194,7 @@ QString Settings::getSettingsDirPath() #ifdef Q_OS_WIN return QStandardPaths::writableLocation(QStandardPaths::ConfigLocation); #else - return QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + '/' + "tox" + '/'; + return QDir::cleanPath(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QDir::separator() + "tox"); #endif } diff --git a/smileypack.cpp b/smileypack.cpp index dba5ac0c5..cca56583c 100644 --- a/smileypack.cpp +++ b/smileypack.cpp @@ -163,7 +163,7 @@ QIcon SmileyPack::getAsIcon(const QString &key) void SmileyPack::cacheSmiley(const QString &name) { QSize size(16, 16); // TODO: adapt to text size - QString filename = path % '/' % name; + QString filename = QDir(path).filePath(name); QImage img(filename); if (!img.isNull()) diff --git a/widget/filetransfertwidget.cpp b/widget/filetransfertwidget.cpp index 773900b25..6c0a30ff7 100644 --- a/widget/filetransfertwidget.cpp +++ b/widget/filetransfertwidget.cpp @@ -278,7 +278,7 @@ void FileTransfertWidget::acceptRecvRequest() QString path; while (true) { - path = QFileDialog::getSaveFileName(this,tr("Save a file","Title of the file saving dialog"),QDir::currentPath()+'/'+filename->text()); + path = QFileDialog::getSaveFileName(this, tr("Save a file","Title of the file saving dialog"), QDir::current().filePath(filename->text())); if (path.isEmpty()) return; else From a3785f3c271394f1ec64576c950b94c8c05270f8 Mon Sep 17 00:00:00 2001 From: apprb Date: Sun, 31 Aug 2014 21:19:16 +0700 Subject: [PATCH 124/149] Widget::updateFriendStatusLights moved to FriendWidget --- widget/form/chatform.cpp | 2 +- widget/friendwidget.cpp | 25 +++++++++++++++++++++++++ widget/friendwidget.h | 1 + widget/widget.cpp | 30 ++++-------------------------- widget/widget.h | 1 - 5 files changed, 31 insertions(+), 28 deletions(-) diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index a95f0a076..a819cfd46 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -408,7 +408,7 @@ void ChatForm::onAvInvite(int FriendId, int CallId, bool video) { w->newMessageAlert(); f->hasNewMessages=true; - w->updateFriendStatusLights(f->friendId); + f->widget->updateStatusLight(); } } diff --git a/widget/friendwidget.cpp b/widget/friendwidget.cpp index 4840ed4a7..128f251c8 100644 --- a/widget/friendwidget.cpp +++ b/widget/friendwidget.cpp @@ -19,6 +19,8 @@ #include "grouplist.h" #include "groupwidget.h" #include "widget.h" +#include "friendlist.h" +#include "friend.h" #include #include @@ -203,3 +205,26 @@ int FriendWidget::isActive() { return isActiveWidget; } + +void FriendWidget::updateStatusLight() +{ + Friend* f = FriendList::findFriend(friendId); + Status status = f->friendStatus; + + if (status == Status::Online && f->hasNewMessages == 0) + statusPic.setPixmap(QPixmap(":img/status/dot_online.png")); + else if (status == Status::Online && f->hasNewMessages == 1) + statusPic.setPixmap(QPixmap(":img/status/dot_online_notification.png")); + else if (status == Status::Away && f->hasNewMessages == 0) + statusPic.setPixmap(QPixmap(":img/status/dot_idle.png")); + else if (status == Status::Away && f->hasNewMessages == 1) + statusPic.setPixmap(QPixmap(":img/status/dot_idle_notification.png")); + else if (status == Status::Busy && f->hasNewMessages == 0) + statusPic.setPixmap(QPixmap(":img/status/dot_busy.png")); + else if (status == Status::Busy && f->hasNewMessages == 1) + statusPic.setPixmap(QPixmap(":img/status/dot_busy_notification.png")); + else if (status == Status::Offline && f->hasNewMessages == 0) + statusPic.setPixmap(QPixmap(":img/status/dot_away.png")); + else if (status == Status::Offline && f->hasNewMessages == 1) + statusPic.setPixmap(QPixmap(":img/status/dot_away_notification.png")); +} diff --git a/widget/friendwidget.h b/widget/friendwidget.h index 71050d985..b174c2914 100644 --- a/widget/friendwidget.h +++ b/widget/friendwidget.h @@ -37,6 +37,7 @@ public: void setAsActiveChatroom(); void setAsInactiveChatroom(); int isActive(); + void updateStatusLight(); signals: void friendWidgetClicked(FriendWidget* widget); diff --git a/widget/widget.cpp b/widget/widget.cpp index cfba03b09..8df48f703 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -451,7 +451,7 @@ void Widget::onFriendStatusChanged(int friendId, Status status) contactListWidget->moveWidget(f->widget, status); f->friendStatus = status; - updateFriendStatusLights(friendId); + f->widget->updateStatusLight(); // Workaround widget style after returning to list if (f->widget->isActive()) @@ -514,7 +514,7 @@ void Widget::onFriendWidgetClicked(FriendWidget *widget) if (f->hasNewMessages != 0) f->hasNewMessages = 0; - updateFriendStatusLights(f->friendId); + f->widget->updateStatusLight(); } void Widget::onFriendMessageReceived(int friendId, const QString& message) @@ -540,29 +540,7 @@ void Widget::onFriendMessageReceived(int friendId, const QString& message) newMessageAlert(); } - updateFriendStatusLights(friendId); -} - -void Widget::updateFriendStatusLights(int friendId) -{ - Friend* f = FriendList::findFriend(friendId); - Status status = f->friendStatus; - if (status == Status::Online && f->hasNewMessages == 0) - f->widget->statusPic.setPixmap(QPixmap(":img/status/dot_online.png")); - else if (status == Status::Online && f->hasNewMessages == 1) - f->widget->statusPic.setPixmap(QPixmap(":img/status/dot_online_notification.png")); - else if (status == Status::Away && f->hasNewMessages == 0) - f->widget->statusPic.setPixmap(QPixmap(":img/status/dot_idle.png")); - else if (status == Status::Away && f->hasNewMessages == 1) - f->widget->statusPic.setPixmap(QPixmap(":img/status/dot_idle_notification.png")); - else if (status == Status::Busy && f->hasNewMessages == 0) - f->widget->statusPic.setPixmap(QPixmap(":img/status/dot_busy.png")); - else if (status == Status::Busy && f->hasNewMessages == 1) - f->widget->statusPic.setPixmap(QPixmap(":img/status/dot_busy_notification.png")); - else if (status == Status::Offline && f->hasNewMessages == 0) - f->widget->statusPic.setPixmap(QPixmap(":img/status/dot_away.png")); - else if (status == Status::Offline && f->hasNewMessages == 1) - f->widget->statusPic.setPixmap(QPixmap(":img/status/dot_away_notification.png")); + f->widget->updateStatusLight(); } void Widget::newMessageAlert() @@ -791,7 +769,7 @@ bool Widget::event(QEvent * e) { Friend* f = FriendList::findFriend(activeFriendWidget->friendId); f->hasNewMessages = 0; - updateFriendStatusLights(f->friendId); + f->widget->updateStatusLight(); } else if (isGroupWidgetActive && activeGroupWidget != nullptr) { diff --git a/widget/widget.h b/widget/widget.h index 4b95fd800..e8f5599ea 100644 --- a/widget/widget.h +++ b/widget/widget.h @@ -58,7 +58,6 @@ public: void showTestCamview(); void newMessageAlert(); bool isFriendWidgetCurActiveWidget(Friend* f); - void updateFriendStatusLights(int friendId); ~Widget(); virtual void closeEvent(QCloseEvent *event); From f0c8be43db55e9fa2be2d5230440ef64d7845116 Mon Sep 17 00:00:00 2001 From: apprb Date: Sun, 31 Aug 2014 21:48:15 +0700 Subject: [PATCH 125/149] change status light on incoming file request --- friend.cpp | 2 +- friend.h | 2 +- widget/form/chatform.cpp | 9 ++++++++- widget/friendwidget.cpp | 16 ++++++++-------- widget/widget.cpp | 10 +++++----- 5 files changed, 23 insertions(+), 16 deletions(-) diff --git a/friend.cpp b/friend.cpp index b024d2dda..ec8dd3860 100644 --- a/friend.cpp +++ b/friend.cpp @@ -23,7 +23,7 @@ Friend::Friend(int FriendId, QString UserId) { widget = new FriendWidget(friendId, userId); chatForm = new ChatForm(this); - hasNewMessages = 0; + hasNewEvents = 0; friendStatus = Status::Offline; } diff --git a/friend.h b/friend.h index 8730ae435..8a3a2427a 100644 --- a/friend.h +++ b/friend.h @@ -36,7 +36,7 @@ public: int friendId; QString userId; ChatForm* chatForm; - int hasNewMessages; + int hasNewEvents; Status friendStatus; QPixmap avatar; }; diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index a819cfd46..5757e7444 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -376,6 +376,13 @@ void ChatForm::onFileRecvRequest(ToxFile file) connect(Widget::getInstance()->getCore(), &Core::fileTransferInfo, fileTrans, &FileTransfertWidget::onFileTransferInfo); connect(Widget::getInstance()->getCore(), &Core::fileTransferCancelled, fileTrans, &FileTransfertWidget::onFileTransferCancelled); connect(Widget::getInstance()->getCore(), &Core::fileTransferFinished, fileTrans, &FileTransfertWidget::onFileTransferFinished); + + if (!f->widget->isActive()) + { + f->hasNewEvents = 1; + // FIXME: add sound alert, as for incoming message + } + f->widget->updateStatusLight(); } void ChatForm::onAvInvite(int FriendId, int CallId, bool video) @@ -407,7 +414,7 @@ void ChatForm::onAvInvite(int FriendId, int CallId, bool video) if (!w->isFriendWidgetCurActiveWidget(f)) { w->newMessageAlert(); - f->hasNewMessages=true; + f->hasNewEvents=true; f->widget->updateStatusLight(); } } diff --git a/widget/friendwidget.cpp b/widget/friendwidget.cpp index 128f251c8..d41f3f52c 100644 --- a/widget/friendwidget.cpp +++ b/widget/friendwidget.cpp @@ -211,20 +211,20 @@ void FriendWidget::updateStatusLight() Friend* f = FriendList::findFriend(friendId); Status status = f->friendStatus; - if (status == Status::Online && f->hasNewMessages == 0) + if (status == Status::Online && f->hasNewEvents == 0) statusPic.setPixmap(QPixmap(":img/status/dot_online.png")); - else if (status == Status::Online && f->hasNewMessages == 1) + else if (status == Status::Online && f->hasNewEvents == 1) statusPic.setPixmap(QPixmap(":img/status/dot_online_notification.png")); - else if (status == Status::Away && f->hasNewMessages == 0) + else if (status == Status::Away && f->hasNewEvents == 0) statusPic.setPixmap(QPixmap(":img/status/dot_idle.png")); - else if (status == Status::Away && f->hasNewMessages == 1) + else if (status == Status::Away && f->hasNewEvents == 1) statusPic.setPixmap(QPixmap(":img/status/dot_idle_notification.png")); - else if (status == Status::Busy && f->hasNewMessages == 0) + else if (status == Status::Busy && f->hasNewEvents == 0) statusPic.setPixmap(QPixmap(":img/status/dot_busy.png")); - else if (status == Status::Busy && f->hasNewMessages == 1) + else if (status == Status::Busy && f->hasNewEvents == 1) statusPic.setPixmap(QPixmap(":img/status/dot_busy_notification.png")); - else if (status == Status::Offline && f->hasNewMessages == 0) + else if (status == Status::Offline && f->hasNewEvents == 0) statusPic.setPixmap(QPixmap(":img/status/dot_away.png")); - else if (status == Status::Offline && f->hasNewMessages == 1) + else if (status == Status::Offline && f->hasNewEvents == 1) statusPic.setPixmap(QPixmap(":img/status/dot_away_notification.png")); } diff --git a/widget/widget.cpp b/widget/widget.cpp index 8df48f703..211a36bce 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -511,8 +511,8 @@ void Widget::onFriendWidgetClicked(FriendWidget *widget) isFriendWidgetActive = 1; isGroupWidgetActive = 0; - if (f->hasNewMessages != 0) - f->hasNewMessages = 0; + if (f->hasNewEvents != 0) + f->hasNewEvents = 0; f->widget->updateStatusLight(); } @@ -530,13 +530,13 @@ void Widget::onFriendMessageReceived(int friendId, const QString& message) Friend* f2 = FriendList::findFriend(activeFriendWidget->friendId); if (((f->friendId != f2->friendId) || isFriendWidgetActive == 0) || isWindowMinimized || !isActiveWindow()) { - f->hasNewMessages = 1; + f->hasNewEvents = 1; newMessageAlert(); } } else { - f->hasNewMessages = 1; + f->hasNewEvents = 1; newMessageAlert(); } @@ -768,7 +768,7 @@ bool Widget::event(QEvent * e) if (isFriendWidgetActive && activeFriendWidget != nullptr) { Friend* f = FriendList::findFriend(activeFriendWidget->friendId); - f->hasNewMessages = 0; + f->hasNewEvents = 0; f->widget->updateStatusLight(); } else if (isGroupWidgetActive && activeGroupWidget != nullptr) From 76971f5238cd7843836142006f497222d1f982aa Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 31 Aug 2014 18:29:55 +0200 Subject: [PATCH 126/149] Make notifications consistent Notify of AV and FT requests if we're selected but not active or minimised, and add sound (consistent with how message notifications work) --- widget/form/chatform.cpp | 11 ++++++----- widget/widget.cpp | 5 +++++ widget/widget.h | 1 + 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index 5757e7444..1e3b4cd16 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -377,12 +377,13 @@ void ChatForm::onFileRecvRequest(ToxFile file) connect(Widget::getInstance()->getCore(), &Core::fileTransferCancelled, fileTrans, &FileTransfertWidget::onFileTransferCancelled); connect(Widget::getInstance()->getCore(), &Core::fileTransferFinished, fileTrans, &FileTransfertWidget::onFileTransferFinished); - if (!f->widget->isActive()) + Widget* w = Widget::getInstance(); + if (!w->isFriendWidgetCurActiveWidget(f)|| w->getIsWindowMinimized() || !w->isActiveWindow()) { - f->hasNewEvents = 1; - // FIXME: add sound alert, as for incoming message + w->newMessageAlert(); + f->hasNewEvents=true; + f->widget->updateStatusLight(); } - f->widget->updateStatusLight(); } void ChatForm::onAvInvite(int FriendId, int CallId, bool video) @@ -411,7 +412,7 @@ void ChatForm::onAvInvite(int FriendId, int CallId, bool video) } Widget* w = Widget::getInstance(); - if (!w->isFriendWidgetCurActiveWidget(f)) + if (!w->isFriendWidgetCurActiveWidget(f)|| w->getIsWindowMinimized() || !w->isActiveWindow()) { w->newMessageAlert(); f->hasNewEvents=true; diff --git a/widget/widget.cpp b/widget/widget.cpp index 211a36bce..4c2f95c99 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -1146,3 +1146,8 @@ bool Widget::eventFilter(QObject *, QEvent *event) } return false; } + +bool Widget::getIsWindowMinimized() +{ + return static_cast(isWindowMinimized); +} diff --git a/widget/widget.h b/widget/widget.h index e8f5599ea..bbf66c512 100644 --- a/widget/widget.h +++ b/widget/widget.h @@ -58,6 +58,7 @@ public: void showTestCamview(); void newMessageAlert(); bool isFriendWidgetCurActiveWidget(Friend* f); + bool getIsWindowMinimized(); ~Widget(); virtual void closeEvent(QCloseEvent *event); From fd4c47cba3acd6454471b451d46c4966d88d9150 Mon Sep 17 00:00:00 2001 From: apprb Date: Sun, 31 Aug 2014 23:48:02 +0700 Subject: [PATCH 127/149] Widget code cleanup: removed isFriendWidgetActive and isGroupWidgetActive --- widget/widget.cpp | 26 +++++++++++--------------- widget/widget.h | 1 - 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/widget/widget.cpp b/widget/widget.cpp index 4c2f95c99..11a7fe97a 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -209,8 +209,6 @@ Widget::Widget(QWidget *parent) coreThread->start(); friendForm.show(*ui); - isFriendWidgetActive = 0; - isGroupWidgetActive = 0; } Widget::~Widget() @@ -325,16 +323,16 @@ void Widget::onTransferClicked() { hideMainForms(); filesForm.show(*ui); - isFriendWidgetActive = 0; - isGroupWidgetActive = 0; + activeFriendWidget = nullptr; + activeGroupWidget = nullptr; } void Widget::onSettingsClicked() { hideMainForms(); settingsForm.show(*ui); - isFriendWidgetActive = 0; - isGroupWidgetActive = 0; + activeFriendWidget = nullptr; + activeGroupWidget = nullptr; } void Widget::hideMainForms() @@ -508,8 +506,7 @@ void Widget::onFriendWidgetClicked(FriendWidget *widget) } activeFriendWidget = widget; widget->setAsActiveChatroom(); - isFriendWidgetActive = 1; - isGroupWidgetActive = 0; + activeGroupWidget = nullptr; if (f->hasNewEvents != 0) f->hasNewEvents = 0; @@ -528,7 +525,7 @@ void Widget::onFriendMessageReceived(int friendId, const QString& message) if (activeFriendWidget != nullptr) { Friend* f2 = FriendList::findFriend(activeFriendWidget->friendId); - if (((f->friendId != f2->friendId) || isFriendWidgetActive == 0) || isWindowMinimized || !isActiveWindow()) + if ((f->friendId != f2->friendId) || isWindowMinimized || !isActiveWindow()) { f->hasNewEvents = 1; newMessageAlert(); @@ -612,7 +609,7 @@ void Widget::onGroupMessageReceived(int groupnumber, int friendgroupnumber, cons g->chatForm->addGroupMessage(message, friendgroupnumber); - if ((isGroupWidgetActive != 1 || (activeGroupWidget && g->groupId != activeGroupWidget->groupId)) || isWindowMinimized || !isActiveWindow()) + if (((activeGroupWidget && g->groupId != activeGroupWidget->groupId)) || isWindowMinimized || !isActiveWindow()) { if (message.contains(core->getUsername(), Qt::CaseInsensitive)) { @@ -668,8 +665,7 @@ void Widget::onGroupWidgetClicked(GroupWidget* widget) } activeGroupWidget = widget; widget->setAsActiveChatroom(); - isFriendWidgetActive = 0; - isGroupWidgetActive = 1; + activeFriendWidget = nullptr; if (g->hasNewMessages != 0) { @@ -739,7 +735,7 @@ bool Widget::isFriendWidgetCurActiveWidget(Friend* f) if (activeFriendWidget != nullptr) { Friend* f2 = FriendList::findFriend(activeFriendWidget->friendId); - if ((f->friendId != f2->friendId) || isFriendWidgetActive == 0) + if (f->friendId != f2->friendId) return false; } else @@ -765,13 +761,13 @@ bool Widget::event(QEvent * e) this->style()->polish(this); } isWindowMinimized = 0; - if (isFriendWidgetActive && activeFriendWidget != nullptr) + if (activeFriendWidget != nullptr) { Friend* f = FriendList::findFriend(activeFriendWidget->friendId); f->hasNewEvents = 0; f->widget->updateStatusLight(); } - else if (isGroupWidgetActive && activeGroupWidget != nullptr) + else if (activeGroupWidget != nullptr) { Group* g = GroupList::findGroup(activeGroupWidget->groupId); g->hasNewMessages = 0; diff --git a/widget/widget.h b/widget/widget.h index bbf66c512..ffba4c5ab 100644 --- a/widget/widget.h +++ b/widget/widget.h @@ -145,7 +145,6 @@ private: FriendWidget* activeFriendWidget; GroupWidget* activeGroupWidget; FriendListWidget* contactListWidget; - int isFriendWidgetActive, isGroupWidgetActive; SelfCamView* camview; Camera* camera; bool notify(QObject *receiver, QEvent *event); From 4b570c88f96087e5f7bb3d7be025c266ec07e9e4 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 31 Aug 2014 19:47:09 +0200 Subject: [PATCH 128/149] Debian bash script to build .deb and .rpm qTox packages Just run buildPackages.sh from a Debian box with the qTox build dependencies installed --- tools/buildPackages.sh | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 tools/buildPackages.sh diff --git a/tools/buildPackages.sh b/tools/buildPackages.sh new file mode 100644 index 000000000..03e7415a2 --- /dev/null +++ b/tools/buildPackages.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Config (Update me if needed !) +VERSION_UPSTREAM="1.0" +VERSION_PACKAGE="1" +PACKAGENAME="qtox" +UPSTREAM_GIT_URL="https://github.com/tux3/qtox.git" + +# Make some vars for convenience +VERNAME=$PACKAGENAME"_"$VERSION_UPSTREAM +FULLVERNAME=$VERNAME"-"$VERSION_PACKAGE +ARCHIVENAME=$VERNAME".orig.tar.gz" + +# Get the requried tools if needed +echo "Installing missing tools (if any)..." +apt-get install git debhelper cdbs devscripts alien tar gzip build-essential + +# Cleanup +rm -r $VERNAME 2> /dev/null +rm $ARCHIVENAME 2> /dev/null + +# Fectche sources and layour directories +git clone --depth 1 $UPSTREAM_GIT_URL +mv $PACKAGENAME $VERNAME +tar cz $VERNAME > $ARCHIVENAME + +# Build packages +cd $VERNAME +debuild -us -uc +cd .. +alien ./$FULLVERNAME*.deb -r From 73309d8b907278be98aa2dba6cf956c6780f7755 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 31 Aug 2014 22:26:45 +0200 Subject: [PATCH 129/149] Fix #235, Fix #84 --- core.cpp | 32 ++++++++++++++++++++++++++++++++ core.h | 1 + settings.cpp | 20 ++++++++++++++++++++ settings.h | 12 ++++++------ widget/widget.cpp | 2 +- 5 files changed, 60 insertions(+), 7 deletions(-) diff --git a/core.cpp b/core.cpp index 658908066..d4241f88d 100644 --- a/core.cpp +++ b/core.cpp @@ -437,6 +437,19 @@ void Core::requestFriendship(const QString& friendAddress, const QString& messag if (friendId < 0) { emit failedToAddFriend(userId); } else { + // Update our friendAddresses + bool found=false; + QList& friendAddresses = Settings::getInstance().friendAddresses; + for (QString& addr : friendAddresses) + { + if (addr.toUpper().contains(friendAddress)) + { + addr = friendAddress; + found = true; + } + } + if (!found) + friendAddresses.append(friendAddress); emit friendAdded(friendId, userId); } saveConfiguration(); @@ -878,6 +891,9 @@ void Core::saveConfiguration() configurationFile.commit(); delete[] data; } + + qDebug() << "Core: writing settings"; + Settings::getInstance().save(); } void Core::loadFriends() @@ -1104,3 +1120,19 @@ void Core::createGroup() { emit emptyGroupCreated(tox_add_groupchat(tox)); } + +QString Core::getFriendAddress(int friendNumber) const +{ + // If we don't know the full address of the client, return just the id, otherwise get the full address + uint8_t rawid[TOX_CLIENT_ID_SIZE]; + tox_get_client_id(tox, friendNumber, rawid); + QByteArray data((char*)rawid,TOX_CLIENT_ID_SIZE); + QString id = data.toHex().toUpper(); + + QList& friendAddresses = Settings::getInstance().friendAddresses; + for (QString addr : friendAddresses) + if (addr.toUpper().contains(id)) + return addr; + + return id; +} diff --git a/core.h b/core.h index 154a18351..e22bd183d 100644 --- a/core.h +++ b/core.h @@ -118,6 +118,7 @@ public: int getGroupNumberPeers(int groupId) const; QString getGroupPeerName(int groupId, int peerId) const; QList getGroupPeerNames(int groupId) const; + QString getFriendAddress(int friendNumber) const; int joinGroupchat(int32_t friendnumber, const uint8_t* friend_group_public_key) const; void quitGroupChat(int groupId) const; void dispatchVideoFrame(vpx_image img) const; diff --git a/settings.cpp b/settings.cpp index b2193e453..f499e9e75 100644 --- a/settings.cpp +++ b/settings.cpp @@ -16,6 +16,7 @@ #include "settings.h" #include "smileypack.h" +#include "widget/widget.h" #include #include @@ -79,6 +80,16 @@ void Settings::load() s.endArray(); s.endGroup(); + friendAddresses.clear(); + s.beginGroup("Friends"); + int size = s.beginReadArray("fullAddresses"); + for (int i = 0; i < size; i ++) { + s.setArrayIndex(i); + friendAddresses.append(s.value("addr").toString()); + } + s.endArray(); + s.endGroup(); + s.beginGroup("General"); enableIPv6 = s.value("enableIPv6", true).toBool(); useTranslations = s.value("useTranslations", true).toBool(); @@ -147,6 +158,15 @@ void Settings::save(QString path) s.endArray(); s.endGroup(); + s.beginGroup("Friends"); + s.beginWriteArray("fullAddresses", friendAddresses.size()); + for (int i = 0; i < friendAddresses.size(); i ++) { + s.setArrayIndex(i); + s.setValue("addr", friendAddresses[i]); + } + s.endArray(); + s.endGroup(); + s.beginGroup("General"); s.setValue("enableIPv6", enableIPv6); s.setValue("useTranslations",useTranslations); diff --git a/settings.h b/settings.h index c32203f41..819e89a21 100644 --- a/settings.h +++ b/settings.h @@ -127,16 +127,16 @@ public: QByteArray getSplitterState() const; void setSplitterState(const QByteArray &value); -private: - Settings(); - Settings(Settings &settings) = delete; - Settings& operator=(const Settings&) = delete; - +public: + QList friendAddresses; void save(); void save(QString path); void load(); - +private: + Settings(); + Settings(Settings &settings) = delete; + Settings& operator=(const Settings&) = delete; static const QString FILENAME; diff --git a/widget/widget.cpp b/widget/widget.cpp index 11a7fe97a..851502df0 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -587,7 +587,7 @@ void Widget::copyFriendIdToClipboard(int friendId) if (f != nullptr) { QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(f->userId, QClipboard::Clipboard); + clipboard->setText(core->getFriendAddress(f->friendId), QClipboard::Clipboard); } } From c5c3513ee99e6aea0b7c618833089d20419cca9c Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 31 Aug 2014 22:44:52 +0200 Subject: [PATCH 130/149] Write settings on toggling 'Make Tox Portable' --- settings.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/settings.cpp b/settings.cpp index f499e9e75..92841f4f7 100644 --- a/settings.cpp +++ b/settings.cpp @@ -248,6 +248,8 @@ void Settings::setMakeToxPortable(bool newValue) { makeToxPortable = newValue; save(FILENAME); // Commit to the portable file that we don't want to use it + if (!newValue) // Update the new file right now if not already done + save(); } bool Settings::getUseTranslations() const From 628d9a0aae9f82ff618ba0e2533b1fc1671fb3a5 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 31 Aug 2014 23:06:31 +0200 Subject: [PATCH 131/149] Tweak file transfer speed Hopefully increase stability by replacing a sleep by a longer timer interval --- core.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core.cpp b/core.cpp index d4241f88d..37455d4e3 100644 --- a/core.cpp +++ b/core.cpp @@ -1087,8 +1087,8 @@ void Core::sendAllFileData(Core *core, ToxFile* file) //qWarning("Core::fileHeartbeat: Error sending data chunk"); //core->process(); delete[] data; - QThread::msleep(1); - file->sendTimer->start(TOX_FILE_INTERVAL); + //QThread::msleep(1); + file->sendTimer->start(1+TOX_FILE_INTERVAL); return; } delete[] data; From c54cfd6ff30f5259f13de18c4ab672e3bfc5e818 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Sun, 31 Aug 2014 23:07:07 +0200 Subject: [PATCH 132/149] Reduce precision of human readable, now more readable! --- widget/filetransfertwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget/filetransfertwidget.cpp b/widget/filetransfertwidget.cpp index 6c0a30ff7..41fb4ed56 100644 --- a/widget/filetransfertwidget.cpp +++ b/widget/filetransfertwidget.cpp @@ -144,7 +144,7 @@ QString FileTransfertWidget::getHumanReadableSize(unsigned long long size) int exp = 0; if (size) exp = std::min( (int) (log(size) / log(1024)), (int) (sizeof(suffix) / sizeof(suffix[0]) - 1)); - return QString().setNum(size / pow(1024, exp),'f',3).append(suffix[exp]); + return QString().setNum(size / pow(1024, exp),'f',2).append(suffix[exp]); } void FileTransfertWidget::onFileTransferInfo(int FriendId, int FileNum, int64_t Filesize, int64_t BytesSent, ToxFile::FileDirection Direction) From 0de3ddaacd4a2f9ac74d1ea4940ebce5d112bd14 Mon Sep 17 00:00:00 2001 From: Bill Winslow Date: Mon, 1 Sep 2014 00:25:22 -0500 Subject: [PATCH 133/149] Update bootstrap.sh, match nodes to wiki.tox.im This might help #221 or #237, several of the old list are probably offline --- bootstrap.sh | 8 ++++--- res/settings.ini | 62 +++++++++++++++--------------------------------- 2 files changed, 24 insertions(+), 46 deletions(-) diff --git a/bootstrap.sh b/bootstrap.sh index d14549aa0..2f7067fb6 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -10,8 +10,10 @@ INSTALL_DIR=libs # just for convenience BASE_DIR=${SCRIPT_DIR}/${INSTALL_DIR} +SODIUM_VER=0.7.0 + # directory names of cloned repositories -SODIUM_DIR=libsodium-0.5.0 +SODIUM_DIR=libsodium-$SODIUM_VER TOX_CORE_DIR=libtoxcore-latest # this boolean describes whether the installation of @@ -97,13 +99,13 @@ rm -rf ${BASE_DIR}/${TOX_CORE_DIR} ############### install step ############### -# clone current master of libsodium and switch to version 0.5.0 +# clone current master of libsodium and switch to version $SODIUM_VER # afterwards install libsodium to INSTALL_DIR # skip the installation if TOX_ONLY is true if [[ $TOX_ONLY = "false" ]]; then git clone git://github.com/jedisct1/libsodium.git ${BASE_DIR}/${SODIUM_DIR} pushd ${BASE_DIR}/${SODIUM_DIR} - git checkout tags/0.6.1 + git checkout tags/$SODIUM_VER ./autogen.sh if [[ $GLOBAL = "false" ]]; then diff --git a/res/settings.ini b/res/settings.ini index 2a051ab94..25d126190 100644 --- a/res/settings.ini +++ b/res/settings.ini @@ -1,5 +1,5 @@ [DHT%20Server] -dhtServerList\size=15 +dhtServerList\size=9 dhtServerList\1\name=stqism dhtServerList\1\userId=951C88B7E75C867418ACDB5D273821372BB5BD652740BCDF623A4FA293E75D2F dhtServerList\1\address=192.254.75.98 @@ -12,51 +12,27 @@ dhtServerList\3\name=stal dhtServerList\3\userId=A09162D68618E742FFBCA1C2C70385E6679604B2D80EA6E84AD0996A1AC8A074 dhtServerList\3\address=23.226.230.47 dhtServerList\3\port=33445 -dhtServerList\4\name=ChauffeR -dhtServerList\4\userId=4FD54CFD426A338399767E56FD0F44F5E35FA8C38C8E87C8DC3FEAC0160F8E1 -dhtServerList\4\address=37.187.20.216 +dhtServerList\4\name=aitjcize +dhtServerList\4\userId=7F9C31FE850E97CEFD4C4591DF93FC757C7C12549DDD55F8EEAECC34FE76C029 +dhtServerList\4\address=54.199.139.199 dhtServerList\4\port=33445 -dhtServerList\5\name=aitjcize -dhtServerList\5\userId=7F9C31FE850E97CEFD4C4591DF93FC757C7C12549DDD55F8EEAECC34FE76C029 -dhtServerList\5\address=54.199.139.199 +dhtServerList\5\name=astonex +dhtServerList\5\userId=B98A2CEAA6C6A2FADC2C3632D284318B60FE5375CCB41EFA081AB67F500C1B0B +dhtServerList\5\address=37.59.102.176 dhtServerList\5\port=33445 -dhtServerList\6\name=astonex -dhtServerList\6\userId=7F31BFC93B8E4016A902144D0B110C3EA97CB7D43F1C4D21BCAE998A7C838821 -dhtServerList\6\address=109.169.46.133 +dhtServerList\6\name=nurupo +dhtServerList\6\userId=F404ABAA1C99A9D37D61AB54898F56793E1DEF8BD46B1038B9D822E8460FAB67 +dhtServerList\6\address=192.210.149.121 dhtServerList\6\port=33445 -dhtServerList\7\name=nurupo -dhtServerList\7\userId=F404ABAA1C99A9D37D61AB54898F56793E1DEF8BD46B1038B9D822E8460FAB67 -dhtServerList\7\address=192.210.149.121 +dhtServerList\7\name=mousey +dhtServerList\7\userId=5EB67C51D3FF5A9D528D242B669036ED2A30F8A60E674C45E7D43010CB2E1331 +dhtServerList\7\address=37.187.46.132 dhtServerList\7\port=33445 -dhtServerList\8\name=mousey -dhtServerList\8\userId=5EB67C51D3FF5A9D528D242B669036ED2A30F8A60E674C45E7D43010CB2E1331 -dhtServerList\8\address=37.187.46.132 +dhtServerList\8\name=Proplex +dhtServerList\8\userId=7BE3951B97CA4B9ECDDA768E8C52BA19E9E2690AB584787BF4C90E04DBB75111 +dhtServerList\8\address=107.161.17.51 dhtServerList\8\port=33445 -dhtServerList\9\name=zlacki NL -dhtServerList\9\userId=CC2B02636A2ADBC2871D6EC57C5E9589D4FD5E6F98A14743A4B949914CF26D39 -dhtServerList\9\address=5.39.218.35 +dhtServerList\9\name=SylvieLorxu +dhtServerList\9\userId=4B2C19E924972CB9B57732FB172F8A8604DE13EEDA2A6234E348983344B23057 +dhtServerList\9\address=178.21.112.187 dhtServerList\9\port=33445 -dhtServerList\10\name=zlacki RU #2 -dhtServerList\10\userId=AE27E1E72ADA3DC423C60EEBACA241456174048BE76A283B41AD32D953182D49 -dhtServerList\10\address=193.107.16.73 -dhtServerList\10\port=33445 -dhtServerList\11\name=platos -dhtServerList\11\userId=B24E2FB924AE66D023FE1E42A2EE3B432010206F751A2FFD3E297383ACF1572E -dhtServerList\11\address=66.175.223.88 -dhtServerList\11\port=33445 -dhtServerList\12\name=JmanGuy -dhtServerList\12\userId=20C797E098701A848B07D0384222416B0EFB60D08CECB925B860CAEAAB572067 -dhtServerList\12\address=66.74.15.98 -dhtServerList\12\port=33445 -dhtServerList\13\name=anonymous -dhtServerList\13\userId=5CD7EB176C19A2FD840406CD56177BB8E75587BB366F7BB3004B19E3EDC04143 -dhtServerList\13\address=192.184.81.118 -dhtServerList\13\port=33445 -dhtServerList\14\name=zlacki RU #1 -dhtServerList\14\userId=D59F99384592DE4C8AB9D534D5197DB90F4755CC9E975ED0C565E18468A1445B -dhtServerList\14\address=31.192.105.19 -dhtServerList\14\port=33445 -dhtServerList\15\name=zlacki US -dhtServerList\15\userId=9430A83211A7AD1C294711D069D587028CA0B4782FA43CB9B30008247A43C944 -dhtServerList\15\address=69.42.220.58 -dhtServerList\15\port=33445 From 7c0cdd710f6ffab81a8cf4677bb3fb85867aa1f5 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 1 Sep 2014 11:00:06 +0200 Subject: [PATCH 134/149] editable CroppingLabel --- widget/croppinglabel.cpp | 79 +++++++++++++++++++++++++++++++++++++++- widget/croppinglabel.h | 13 +++++++ 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/widget/croppinglabel.cpp b/widget/croppinglabel.cpp index f69e81c4c..bed2f023e 100644 --- a/widget/croppinglabel.cpp +++ b/widget/croppinglabel.cpp @@ -15,11 +15,36 @@ */ #include "croppinglabel.h" +#include CroppingLabel::CroppingLabel(QWidget* parent) : QLabel(parent) + , blockPaintEvents(false) + , editable(false) + , elideMode(Qt::ElideRight) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + + textEdit = new QLineEdit(this); + textEdit->hide(); + + installEventFilter(this); + textEdit->installEventFilter(this); +} + +void CroppingLabel::setEditable(bool editable) +{ + this->editable = editable; + + if (editable) + setCursor(Qt::PointingHandCursor); + else + unsetCursor(); +} + +void CroppingLabel::setEdlideMode(Qt::TextElideMode elide) +{ + elideMode = elide; } void CroppingLabel::setText(const QString& text) @@ -31,6 +56,8 @@ void CroppingLabel::setText(const QString& text) void CroppingLabel::resizeEvent(QResizeEvent* ev) { setElidedText(); + textEdit->resize(ev->size()); + QLabel::resizeEvent(ev); } @@ -44,9 +71,50 @@ QSize CroppingLabel::minimumSizeHint() const return QSize(fontMetrics().width("..."), QLabel::minimumSizeHint().height()); } +void CroppingLabel::mouseReleaseEvent(QMouseEvent *e) +{ + if (editable) + { + blockPaintEvents = true; + textEdit->show(); + textEdit->setFocus(); + } + + QLabel::mouseReleaseEvent(e); +} + +bool CroppingLabel::eventFilter(QObject *obj, QEvent *e) +{ + // catch paint events if needed + if (obj == this) + { + if (e->type() == QEvent::Paint && blockPaintEvents) + return true; + } + + // events fired by the QLineEdit + if (obj == textEdit) + { + if (e->type() == QEvent::KeyPress) + { + QKeyEvent* keyEvent = static_cast(e); + if (keyEvent->key() == Qt::Key_Return) + hideTextEdit(true); + + if (keyEvent->key() == Qt::Key_Escape) + hideTextEdit(false); + } + + if (e->type() == QEvent::FocusOut) + hideTextEdit(true); + } + + return false; +} + void CroppingLabel::setElidedText() { - QString elidedText = fontMetrics().elidedText(origText, Qt::ElideRight, width()); + QString elidedText = fontMetrics().elidedText(origText, elideMode, width()); if (elidedText != origText) setToolTip(origText); else @@ -54,3 +122,12 @@ void CroppingLabel::setElidedText() QLabel::setText(elidedText); } + +void CroppingLabel::hideTextEdit(bool acceptText) +{ + if (acceptText) + setText(textEdit->text()); + + textEdit->hide(); + blockPaintEvents = false; +} diff --git a/widget/croppinglabel.h b/widget/croppinglabel.h index decc5ad19..25fa34df0 100644 --- a/widget/croppinglabel.h +++ b/widget/croppinglabel.h @@ -18,6 +18,7 @@ #define CROPPINGLABEL_H #include +#include class CroppingLabel : public QLabel { @@ -25,16 +26,28 @@ class CroppingLabel : public QLabel public: explicit CroppingLabel(QWidget *parent = 0); + void setEditable(bool editable); + void setEdlideMode(Qt::TextElideMode elide); + virtual void setText(const QString& text); virtual void resizeEvent(QResizeEvent *ev); virtual QSize sizeHint() const; virtual QSize minimumSizeHint() const; + virtual void mouseReleaseEvent(QMouseEvent *e); + virtual bool eventFilter(QObject *obj, QEvent *e); protected: void setElidedText(); + void acceptText(); + void rejectText(); + void hideTextEdit(bool acceptText); private: QString origText; + QLineEdit* textEdit; + bool blockPaintEvents; + bool editable; + Qt::TextElideMode elideMode; }; #endif // CROPPINGLABEL_H From 26c028f416fc1ee3131de2d05fd08f4c70d275dd Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 1 Sep 2014 11:08:02 +0200 Subject: [PATCH 135/149] removed ClickableLabel, EditableLabelWidget, ElideLabel, EscLineEdit, CopyableElideLabel --- mainwindow.ui | 20 ++--- qtox.pro | 10 --- widget/form/settingsform.h | 3 +- widget/tool/clickablelabel.cpp | 27 ------- widget/tool/clickablelabel.h | 36 --------- widget/tool/copyableelidelabel.cpp | 47 ----------- widget/tool/copyableelidelabel.h | 36 --------- widget/tool/editablelabelwidget.cpp | 117 ---------------------------- widget/tool/editablelabelwidget.h | 66 ---------------- widget/tool/elidelabel.cpp | 82 ------------------- widget/tool/elidelabel.h | 50 ------------ widget/tool/esclineedit.cpp | 34 -------- widget/tool/esclineedit.h | 36 --------- widget/widget.cpp | 7 +- 14 files changed, 16 insertions(+), 555 deletions(-) delete mode 100644 widget/tool/clickablelabel.cpp delete mode 100644 widget/tool/clickablelabel.h delete mode 100644 widget/tool/copyableelidelabel.cpp delete mode 100644 widget/tool/copyableelidelabel.h delete mode 100644 widget/tool/editablelabelwidget.cpp delete mode 100644 widget/tool/editablelabelwidget.h delete mode 100644 widget/tool/elidelabel.cpp delete mode 100644 widget/tool/elidelabel.h delete mode 100644 widget/tool/esclineedit.cpp delete mode 100644 widget/tool/esclineedit.h diff --git a/mainwindow.ui b/mainwindow.ui index 8622e3d68..7f9cd12c5 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -1482,7 +1482,7 @@ QSplitter:handle{ 0 - + true @@ -1920,7 +1920,7 @@ QSplitter:handle{ - + 1 @@ -2092,8 +2092,8 @@ QSplitter:handle{ 0 0 - 335 - 379 + 263 + 373 @@ -3228,7 +3228,7 @@ QSplitter:handle{ 0 0 716 - 24 + 23
@@ -3243,17 +3243,17 @@ QSplitter:handle{ - - EditableLabelWidget - QLabel -
widget/tool/editablelabelwidget.h
-
AdjustingScrollArea QScrollArea
widget/adjustingscrollarea.h
1
+ + CroppingLabel + QLabel +
widget/croppinglabel.h
+
diff --git a/qtox.pro b/qtox.pro index 6060257cc..8f87e7255 100644 --- a/qtox.pro +++ b/qtox.pro @@ -71,10 +71,6 @@ HEADERS += widget/form/addfriendform.h \ widget/form/settingsform.h \ widget/form/filesform.h \ widget/tool/chattextedit.h \ - widget/tool/copyableelidelabel.h \ - widget/tool/editablelabelwidget.h \ - widget/tool/elidelabel.h \ - widget/tool/esclineedit.h \ widget/tool/friendrequestdialog.h \ widget/filetransfertwidget.h \ widget/friendwidget.h \ @@ -91,7 +87,6 @@ HEADERS += widget/form/addfriendform.h \ widget/selfcamview.h \ widget/camera.h \ widget/netcamview.h \ - widget/tool/clickablelabel.h \ smileypack.h \ widget/emoticonswidget.h \ style.h \ @@ -106,10 +101,6 @@ SOURCES += \ widget/form/settingsform.cpp \ widget/form/filesform.cpp \ widget/tool/chattextedit.cpp \ - widget/tool/copyableelidelabel.cpp \ - widget/tool/editablelabelwidget.cpp \ - widget/tool/elidelabel.cpp \ - widget/tool/esclineedit.cpp \ widget/tool/friendrequestdialog.cpp \ widget/filetransfertwidget.cpp \ widget/friendwidget.cpp \ @@ -127,7 +118,6 @@ SOURCES += \ widget/selfcamview.cpp \ widget/camera.cpp \ widget/netcamview.cpp \ - widget/tool/clickablelabel.cpp \ smileypack.cpp \ widget/emoticonswidget.cpp \ style.cpp \ diff --git a/widget/form/settingsform.h b/widget/form/settingsform.h index 0c8f59ee4..83e6800b7 100644 --- a/widget/form/settingsform.h +++ b/widget/form/settingsform.h @@ -27,7 +27,6 @@ #include #include #include -#include "widget/tool/clickablelabel.h" #include "ui_mainwindow.h" #include "widget/selfcamview.h" @@ -54,7 +53,7 @@ private slots: private: QLabel headLabel, nameLabel, statusTextLabel, smileyPackLabel; QTextEdit id; - ClickableLabel idLabel; + QLabel idLabel; QPushButton videoTest; QCheckBox enableIPv6, useTranslations, makeToxPortable; QVBoxLayout layout, headLayout; diff --git a/widget/tool/clickablelabel.cpp b/widget/tool/clickablelabel.cpp deleted file mode 100644 index 9e61becff..000000000 --- a/widget/tool/clickablelabel.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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. -*/ - -#include "clickablelabel.h" - -ClickableLabel::ClickableLabel(QWidget *parent) : - QLabel(parent) -{ -} - -void ClickableLabel::mousePressEvent(QMouseEvent*) -{ - emit clicked(); -} diff --git a/widget/tool/clickablelabel.h b/widget/tool/clickablelabel.h deleted file mode 100644 index db475ee1c..000000000 --- a/widget/tool/clickablelabel.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (C) 2014 by Project Tox - - 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. -*/ - -#ifndef CLICKABLELABEL_H -#define CLICKABLELABEL_H - -#include - -class ClickableLabel : public QLabel -{ - Q_OBJECT -public: - explicit ClickableLabel(QWidget *parent = 0); - -signals: - void clicked(); - -protected: - void mousePressEvent ( QMouseEvent * event ); - -}; - -#endif // CLICKABLELABEL_H diff --git a/widget/tool/copyableelidelabel.cpp b/widget/tool/copyableelidelabel.cpp deleted file mode 100644 index ae05717ca..000000000 --- a/widget/tool/copyableelidelabel.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright (C) 2013 by Maxim Biro - - This file is part of Tox Qt GUI. - - 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 COPYING file for more details. -*/ - -#include "copyableelidelabel.h" - -#include -#include -#include - -CopyableElideLabel::CopyableElideLabel(QWidget* parent) : - ElideLabel(parent) -{ - setContextMenuPolicy(Qt::CustomContextMenu); - connect(this, &CopyableElideLabel::customContextMenuRequested, this, &CopyableElideLabel::showContextMenu); - - actionCopy = new QAction(CopyableElideLabel::tr("Copy"), this); - connect(actionCopy, &QAction::triggered, [this]() { - QApplication::clipboard()->setText(text()); - }); -} - -void CopyableElideLabel::showContextMenu(const QPoint& pos) -{ - if (text().length() == 0) { - return; - } - - QPoint globalPos = mapToGlobal(pos); - - QMenu contextMenu; - contextMenu.addAction(actionCopy); - - contextMenu.exec(globalPos); -} diff --git a/widget/tool/copyableelidelabel.h b/widget/tool/copyableelidelabel.h deleted file mode 100644 index 69bc09382..000000000 --- a/widget/tool/copyableelidelabel.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (C) 2013 by Maxim Biro - - This file is part of Tox Qt GUI. - - 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 COPYING file for more details. -*/ - -#ifndef COPYABLEELIDELABEL_HPP -#define COPYABLEELIDELABEL_HPP - -#include "elidelabel.h" - -class CopyableElideLabel : public ElideLabel -{ - Q_OBJECT -public: - explicit CopyableElideLabel(QWidget* parent = 0); - -private: - QAction* actionCopy; - -private slots: - void showContextMenu(const QPoint& pos); - -}; - -#endif // COPYABLEELIDELABEL_HPP diff --git a/widget/tool/editablelabelwidget.cpp b/widget/tool/editablelabelwidget.cpp deleted file mode 100644 index a9c87f27a..000000000 --- a/widget/tool/editablelabelwidget.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - Copyright (C) 2013 by Maxim Biro - - This file is part of Tox Qt GUI. - - 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 COPYING file for more details. -*/ - -#include "editablelabelwidget.h" - -#include -#include -#include -#include -#include - -ClickableCopyableElideLabel::ClickableCopyableElideLabel(QWidget* parent) : - CopyableElideLabel(parent) -{ -} - -bool ClickableCopyableElideLabel::event(QEvent* event) -{ - if (event->type() == QEvent::MouseButtonRelease) { - QMouseEvent* mouseEvent = static_cast(event); - if (mouseEvent->button() == Qt::LeftButton) { - emit clicked(); - } - } else if (event->type() == QEvent::Enter) { - QApplication::setOverrideCursor(QCursor(Qt::PointingHandCursor)); - } else if (event->type() == QEvent::Leave) { - QApplication::restoreOverrideCursor(); - } - - return CopyableElideLabel::event(event); -} - -EditableLabelWidget::EditableLabelWidget(QWidget* parent) : - QStackedWidget(parent), isSubmitting(false) -{ - label = new ClickableCopyableElideLabel(this); - - connect(label, &ClickableCopyableElideLabel::clicked, this, &EditableLabelWidget::onLabelClicked); - - lineEdit = new EscLineEdit(this); - lineEdit->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); - lineEdit->setMinimumHeight(label->fontMetrics().lineSpacing() + LINE_SPACING_OFFSET); - - // Set dark background for >windows - //QColor toxDarkAsMySoul(28,28,28); - //QPalette darkPal; - //darkPal.setColor(QPalette::Window, toxDarkAsMySoul); - //darkPal.setColor(QPalette::Base, toxDarkAsMySoul); - //lineEdit->setPalette(darkPal); - - connect(lineEdit, &EscLineEdit::editingFinished, this, &EditableLabelWidget::onLabelChangeSubmited); - connect(lineEdit, &EscLineEdit::escPressed, this, &EditableLabelWidget::onLabelChangeCancelled); - - addWidget(label); - addWidget(lineEdit); - - setCurrentWidget(label); -} - -void EditableLabelWidget::setText(const QString& text) -{ - label->setText(text); - lineEdit->setText(text); -} - -QString EditableLabelWidget::text() -{ - return label->text(); -} - -void EditableLabelWidget::onLabelChangeSubmited() -{ - if (isSubmitting) { - return; - } - isSubmitting = true; - - QString oldText = label->text(); - QString newText = lineEdit->text(); - // `lineEdit->clearFocus()` triggers `onLabelChangeSubmited()`, we use `isSubmitting` as a workaround - lineEdit->clearFocus(); - setCurrentWidget(label); - - if (oldText != newText) { - label->setText(newText); - emit textChanged(newText, oldText); - } - - isSubmitting = false; -} - -void EditableLabelWidget::onLabelChangeCancelled() -{ - // order of calls matters, since clearFocus() triggers EditableLabelWidget::onLabelChangeSubmited() - lineEdit->setText(label->text()); - lineEdit->clearFocus(); - setCurrentWidget(label); -} - -void EditableLabelWidget::onLabelClicked() -{ - setCurrentWidget(lineEdit); - lineEdit->setFocus(); -} diff --git a/widget/tool/editablelabelwidget.h b/widget/tool/editablelabelwidget.h deleted file mode 100644 index 17772f8c4..000000000 --- a/widget/tool/editablelabelwidget.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - Copyright (C) 2013 by Maxim Biro - - This file is part of Tox Qt GUI. - - 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 COPYING file for more details. -*/ - -#ifndef EDITABLELABELWIDGET_HPP -#define EDITABLELABELWIDGET_HPP - -#include "copyableelidelabel.h" -#include "esclineedit.h" - -#include -#include - -class ClickableCopyableElideLabel : public CopyableElideLabel -{ - Q_OBJECT -public: - explicit ClickableCopyableElideLabel(QWidget* parent = 0); - -protected: - bool event(QEvent* event) Q_DECL_OVERRIDE; - -signals: - void clicked(); - -}; - -class EditableLabelWidget : public QStackedWidget -{ - Q_OBJECT -public: - explicit EditableLabelWidget(QWidget* parent = 0); - - ClickableCopyableElideLabel* label; - EscLineEdit* lineEdit; - - void setText(const QString& text); - QString text(); - -private: - static const int LINE_SPACING_OFFSET = 2; - bool isSubmitting; - -private slots: - void onLabelChangeSubmited(); - void onLabelChangeCancelled(); - void onLabelClicked(); - -signals: - void textChanged(QString newText, QString oldText); - -}; - -#endif // EDITABLELABELWIDGET_HPP diff --git a/widget/tool/elidelabel.cpp b/widget/tool/elidelabel.cpp deleted file mode 100644 index 239400f49..000000000 --- a/widget/tool/elidelabel.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (C) 2013 by Maxim Biro - - This file is part of Tox Qt GUI. - - 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 COPYING file for more details. -*/ - -#include "elidelabel.h" - -#include -#include - -ElideLabel::ElideLabel(QWidget *parent) : - QLabel(parent), _textElide(false), _textElideMode(Qt::ElideNone), _showToolTipOnElide(false) -{ -} - -void ElideLabel::paintEvent(QPaintEvent *event) -{ - QFrame::paintEvent(event); - QPainter p(this); - QFontMetrics metrics(font()); - if ((metrics.width(text()) > contentsRect().width()) && textElide()) { - QString elidedText = fontMetrics().elidedText(text(), textElideMode(), rect().width()); - p.drawText(rect(), alignment(), elidedText); - } else { - QLabel::paintEvent(event); - } -} - -bool ElideLabel::event(QEvent *event) -{ - if (event->type() == QEvent::ToolTip) { - QFontMetrics metrics(font()); - if ((metrics.width(text()) > contentsRect().width()) && textElide() && showToolTipOnElide()) { - setToolTip(text()); - } else { - setToolTip(""); - } - } - - return QLabel::event(event); -} - -void ElideLabel::setTextElide(bool set) -{ - _textElide = set; -} - -bool ElideLabel::textElide() const -{ - return _textElide; -} - -void ElideLabel::setTextElideMode(Qt::TextElideMode mode) -{ - _textElideMode = mode; -} - -Qt::TextElideMode ElideLabel::textElideMode() const -{ - return _textElideMode; -} - -void ElideLabel::setShowToolTipOnElide(bool show) -{ - _showToolTipOnElide = show; -} - -bool ElideLabel::showToolTipOnElide() -{ - return _showToolTipOnElide; -} diff --git a/widget/tool/elidelabel.h b/widget/tool/elidelabel.h deleted file mode 100644 index 5dd309001..000000000 --- a/widget/tool/elidelabel.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright (C) 2013 by Maxim Biro - - This file is part of Tox Qt GUI. - - 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 COPYING file for more details. -*/ - -#ifndef ELIDELABEL_HPP -#define ELIDELABEL_HPP - -#include - -class ElideLabel : public QLabel -{ - Q_OBJECT -public: - explicit ElideLabel(QWidget *parent = 0); - - void setTextElide(bool set); - bool textElide() const; - - void setTextElideMode(Qt::TextElideMode mode); - Qt::TextElideMode textElideMode() const; - - void setShowToolTipOnElide(bool show); - bool showToolTipOnElide(); - -protected: - void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; - bool event(QEvent *e) Q_DECL_OVERRIDE; - -private: - bool _textElide; - Qt::TextElideMode _textElideMode; - - bool _showToolTipOnElide; - - -}; - -#endif // ELIDELABEL_HPP diff --git a/widget/tool/esclineedit.cpp b/widget/tool/esclineedit.cpp deleted file mode 100644 index 1a6adc373..000000000 --- a/widget/tool/esclineedit.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - Copyright (C) 2013 by Maxim Biro - - This file is part of Tox Qt GUI. - - 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 COPYING file for more details. -*/ - -#include "esclineedit.h" - -#include -#include - -EscLineEdit::EscLineEdit(QWidget* parent) : - QLineEdit(parent) -{ -} - -void EscLineEdit::keyPressEvent(QKeyEvent* event) -{ - if (event->key() == Qt::Key_Escape && event->modifiers() == Qt::NoModifier) { - emit escPressed(); - } else { - QLineEdit::keyPressEvent(event); - } -} diff --git a/widget/tool/esclineedit.h b/widget/tool/esclineedit.h deleted file mode 100644 index 75eac7315..000000000 --- a/widget/tool/esclineedit.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (C) 2013 by Maxim Biro - - This file is part of Tox Qt GUI. - - 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 COPYING file for more details. -*/ - -#ifndef ESCLINEEDIT_HPP -#define ESCLINEEDIT_HPP - -#include - -class EscLineEdit : public QLineEdit -{ - Q_OBJECT -public: - explicit EscLineEdit(QWidget* parent); - -protected: - void keyPressEvent(QKeyEvent* event) Q_DECL_OVERRIDE; - -signals: - void escPressed(); - -}; - -#endif // ESCLINEEDIT_HPP diff --git a/widget/widget.cpp b/widget/widget.cpp index 851502df0..3b46fd62e 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -115,11 +115,14 @@ Widget::Widget(QWidget *parent) ui->friendList->setWidget(contactListWidget); ui->friendList->setLayoutDirection(Qt::RightToLeft); + ui->nameLabel->setEditable(true); + ui->statusLabel->setEditable(true); + // delay setting username and message until Core inits //ui->nameLabel->setText(core->getUsername()); - ui->nameLabel->label->setStyleSheet("QLabel { color : white; font-size: 11pt; font-weight:bold;}"); + ui->nameLabel->setStyleSheet("QLabel { color : white; font-size: 11pt; font-weight:bold;}"); //ui->statusLabel->setText(core->getStatusMessage()); - ui->statusLabel->label->setStyleSheet("QLabel { color : white; font-size: 8pt;}"); + ui->statusLabel->setStyleSheet("QLabel { color : white; font-size: 8pt;}"); ui->statusButton->setStyleSheet(Style::get(":/ui/statusButton/statusButton.css")); From 1cd954ba42b4d91df182246997476c1caf47a249 Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 1 Sep 2014 11:16:41 +0200 Subject: [PATCH 136/149] compatibility with old widgets --- widget/croppinglabel.cpp | 19 ++++++++++++++----- widget/croppinglabel.h | 5 +++++ widget/form/settingsform.h | 3 ++- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/widget/croppinglabel.cpp b/widget/croppinglabel.cpp index bed2f023e..47b324d1e 100644 --- a/widget/croppinglabel.cpp +++ b/widget/croppinglabel.cpp @@ -74,11 +74,9 @@ QSize CroppingLabel::minimumSizeHint() const void CroppingLabel::mouseReleaseEvent(QMouseEvent *e) { if (editable) - { - blockPaintEvents = true; - textEdit->show(); - textEdit->setFocus(); - } + showTextEdit(); + + emit clicked(); QLabel::mouseReleaseEvent(e); } @@ -126,8 +124,19 @@ void CroppingLabel::setElidedText() void CroppingLabel::hideTextEdit(bool acceptText) { if (acceptText) + { + emit textChanged(textEdit->text(), origText); setText(textEdit->text()); + } textEdit->hide(); blockPaintEvents = false; } + +void CroppingLabel::showTextEdit() +{ + blockPaintEvents = true; + textEdit->show(); + textEdit->setFocus(); + textEdit->setText(origText); +} diff --git a/widget/croppinglabel.h b/widget/croppinglabel.h index 25fa34df0..17f5666c0 100644 --- a/widget/croppinglabel.h +++ b/widget/croppinglabel.h @@ -36,11 +36,16 @@ public: virtual void mouseReleaseEvent(QMouseEvent *e); virtual bool eventFilter(QObject *obj, QEvent *e); +signals: + void textChanged(QString newText, QString oldText); + void clicked(); + protected: void setElidedText(); void acceptText(); void rejectText(); void hideTextEdit(bool acceptText); + void showTextEdit(); private: QString origText; diff --git a/widget/form/settingsform.h b/widget/form/settingsform.h index 83e6800b7..81851e8a9 100644 --- a/widget/form/settingsform.h +++ b/widget/form/settingsform.h @@ -29,6 +29,7 @@ #include #include "ui_mainwindow.h" #include "widget/selfcamview.h" +#include "widget/croppinglabel.h" class SettingsForm : public QObject { @@ -53,7 +54,7 @@ private slots: private: QLabel headLabel, nameLabel, statusTextLabel, smileyPackLabel; QTextEdit id; - QLabel idLabel; + CroppingLabel idLabel; QPushButton videoTest; QCheckBox enableIPv6, useTranslations, makeToxPortable; QVBoxLayout layout, headLayout; From 7e6c4f51298e16b7b6179e5ba95f91f227c964bd Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 1 Sep 2014 12:27:41 +0200 Subject: [PATCH 137/149] cleanup --- widget/croppinglabel.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/widget/croppinglabel.h b/widget/croppinglabel.h index 17f5666c0..aeca082b1 100644 --- a/widget/croppinglabel.h +++ b/widget/croppinglabel.h @@ -42,8 +42,6 @@ signals: protected: void setElidedText(); - void acceptText(); - void rejectText(); void hideTextEdit(bool acceptText); void showTextEdit(); From 24971f50e99aac4dcf8934f63f7c2201094c83c6 Mon Sep 17 00:00:00 2001 From: apprb Date: Mon, 1 Sep 2014 18:55:07 +0700 Subject: [PATCH 138/149] fix #243 : Smileys are broken --- widget/form/chatform.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/widget/form/chatform.cpp b/widget/form/chatform.cpp index 1e3b4cd16..50f09f5a2 100644 --- a/widget/form/chatform.cpp +++ b/widget/form/chatform.cpp @@ -218,8 +218,6 @@ void ChatForm::addMessage(QString author, QString message, QString date) void ChatForm::addMessage(QLabel* author, QLabel* message, QLabel* date) { - message->setText(SmileyPack::getInstance().smileyfied(message->text())); - QScrollBar* scroll = chatArea->verticalScrollBar(); lockSliderToBottom = scroll && scroll->value() == scroll->maximum(); author->setAlignment(Qt::AlignTop | Qt::AlignRight); @@ -262,6 +260,7 @@ void ChatForm::addMessage(QLabel* author, QLabel* message, QLabel* date) finalMessage += "
"; } message->setText(finalMessage.left(finalMessage.length()-4)); + message->setText(SmileyPack::getInstance().smileyfied(message->text())); message->setTextFormat(Qt::RichText); mainChatLayout->addWidget(author, curRow, 0); From f845bfb756667943a20fa3e798025dafc80fde2e Mon Sep 17 00:00:00 2001 From: krepa098 Date: Mon, 1 Sep 2014 18:03:31 +0200 Subject: [PATCH 139/149] xD smiley --- smileys/default/emoticons.xml | 6 +++ smileys/default/laugh_closed_eyes.png | Bin 0 -> 1461 bytes smileys/default/raw.svg | 54 +++++++++++++++++++++++--- 3 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 smileys/default/laugh_closed_eyes.png diff --git a/smileys/default/emoticons.xml b/smileys/default/emoticons.xml index f978d55d5..d1fe8c715 100644 --- a/smileys/default/emoticons.xml +++ b/smileys/default/emoticons.xml @@ -76,4 +76,10 @@ D: + + 😆 + xD + XD + + diff --git a/smileys/default/laugh_closed_eyes.png b/smileys/default/laugh_closed_eyes.png new file mode 100644 index 0000000000000000000000000000000000000000..fc294a5106f5684698476f0d86d83876e49789d7 GIT binary patch literal 1461 zcmV;m1xosfP)V=- zLvm$dbY)~9W^ZyJbZBKDaa3=3AaHVTYGq?|E+9#6b8u;LWn>^?c_4IXWgsF>Wp-t9 zAZ=-GWFaCTb8TsCWqBZQVPk7946eMW00010bVXQnLvL_-a%pF1bO1v`AVG9=a%p09 zbZKvHElzK4LvL+uWpZO_VQe61baZe!FE3+qWnpw_c4cF4ZEbIEb1rXkXD@7NV`Xl0 zWpgiLc`a^ZFEcJMFX6H#GynhuTS-JgR7i=vmw!xEWf;dl@8z5u_uRwHFoOg&@CRCC zW7Q~EWD92&Qfslb6m-~_39h!bSYx_b!_6&SYib6KEz#9X+a#v3VL4V*11U?VOu_hd zbz!D-y};#gpZ>Uj_r`_pMf1D8|Geit@8|jPzR!7%5)mSmQYsO69GIzTBmr0!J%Ahd zK}0S^yw`t$l~OLdMu};V@3WZmSUSFWv#`%iCKjNrn}PFP_`Q6fsySm1r8& zWu}w5s}wVB&ZI#Zr`8TA-iGI=Q?z@$EDx80abTs?Vk4Ggr3JV)7h#VM8LD?H@NL^m zpLc*~MC8{A!Ahw_BbMJP%9y@t1?py?quPHIDJthr?*I=5dp?#irIcZns zRVz@X1-MLuI;E684y@~}&rB!vX2Tm!n~Sh#rjx4cygoXoL*7 z)(&`hHP^29Gh0OZYyftRlDus6V5qwn%67vAcXR-EFO*loR}G=_X>%Yi8{Mu^0wbX| z4e|?fF@hH=1=suG(R^550*AhVAuBx0?}sDb!;5dhqL<-ZC(KS9zpgMB!!*bTP(Y$- z(0=tej&Q|czy}BG1Ktn%U`-B`u7!A4plEF02fGeH?_W?}4C`J1movP9!+w~ylzxww z)EHn{Rt78A9 zZinxF3Gej?Yo?}YB#jpQU^(u9j@t27Pp0I1pma@OOr*KV#A+Hz6O{abqJc&$n`P0{ z*3H2GhX_?$Hv^VMj|RBUci{sZ5V%4+4?qDf1&TpNCXr?Rr9 z3_RP~%DL0WIsN(HV{^gR2@xUQ#hHdmM4AJmWj~TIBThOyJ7ua`n)Qf$vdK2Kr!*rC zl}NmcGa`Zp;PFyjRYTd68G-7Rkp^$C_VV=7CG@y26HQ+RuwcP_9O`!pbNwOnRW*1$ zUaA2`H+4B3Ts?c}hIRfX + + + @@ -841,5 +850,40 @@ d="m 137.06672,1013.3344 c 0.25114,-1.6566 2.15608,-5.1205 7.23695,-5.1205 5.08089,0 6.93799,3.9294 6.55424,5.1205 -0.13763,0.4272 -0.47655,0.8569 -1.31761,0.4379 -1.70599,-0.8499 -2.65516,-1.2076 -5.57799,-1.2572 -2.92284,-0.05 -4.14543,1.2631 -5.36636,1.7495 -1.22092,0.4865 -1.61867,-0.3403 -1.52923,-0.9302 z" style="fill:#ffffff;stroke:#000000;stroke-width:0.76466024;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> + + + + + + + From 35b7ad3a58c8243ee69fa7decd6ede727241e047 Mon Sep 17 00:00:00 2001 From: apprb Date: Mon, 1 Sep 2014 22:02:26 +0700 Subject: [PATCH 140/149] Chatroom: common parts moved to the parent class --- qtox.pro | 6 ++- widget/friendwidget.cpp | 46 --------------------- widget/friendwidget.h | 13 +----- widget/genericchatroomwidget.cpp | 68 ++++++++++++++++++++++++++++++++ widget/genericchatroomwidget.h | 50 +++++++++++++++++++++++ widget/groupwidget.cpp | 45 +++------------------ widget/groupwidget.h | 15 ++----- 7 files changed, 132 insertions(+), 111 deletions(-) create mode 100644 widget/genericchatroomwidget.cpp create mode 100644 widget/genericchatroomwidget.h diff --git a/qtox.pro b/qtox.pro index 6060257cc..043086e8c 100644 --- a/qtox.pro +++ b/qtox.pro @@ -97,7 +97,8 @@ HEADERS += widget/form/addfriendform.h \ style.h \ widget/adjustingscrollarea.h \ widget/croppinglabel.h \ - widget/friendlistwidget.h + widget/friendlistwidget.h \ + widget/genericchatroomwidget.h SOURCES += \ widget/form/addfriendform.cpp \ @@ -134,4 +135,5 @@ SOURCES += \ widget/adjustingscrollarea.cpp \ widget/croppinglabel.cpp \ widget/friendlistwidget.cpp \ - coreav.cpp + coreav.cpp \ + widget/genericchatroomwidget.cpp diff --git a/widget/friendwidget.cpp b/widget/friendwidget.cpp index d41f3f52c..d703bfd60 100644 --- a/widget/friendwidget.cpp +++ b/widget/friendwidget.cpp @@ -122,47 +122,6 @@ void FriendWidget::contextMenuEvent(QContextMenuEvent * event) } } -void FriendWidget::mousePressEvent(QMouseEvent *event) -{ - if ((event->buttons() & Qt::LeftButton) == Qt::LeftButton) - { - if (isActiveWidget) - { - QPalette pal; - pal.setColor(QPalette::Background, QColor(250,250,250,255)); - this->setPalette(pal); - } - else - { - QPalette pal; - pal.setColor(QPalette::Background, QColor(85,85,85,255)); - this->setPalette(pal); - } - } -} - -void FriendWidget::enterEvent(QEvent*) -{ - if (isActiveWidget != 1) - { - QPalette pal; - pal.setColor(QPalette::Background, QColor(75,75,75,255)); - lastColor = this->palette().background().color(); - this->setPalette(pal); - } -} - -void FriendWidget::leaveEvent(QEvent*) -{ - if (isActiveWidget != 1) - { - QPalette pal; - pal.setColor(QPalette::Background, lastColor); - this->setPalette(pal); - } -} - - void FriendWidget::setAsActiveChatroom() { isActiveWidget = 1; @@ -201,11 +160,6 @@ void FriendWidget::setAsInactiveChatroom() avatar.setPixmap(QPixmap(":img/contact.png")); } -int FriendWidget::isActive() -{ - return isActiveWidget; -} - void FriendWidget::updateStatusLight() { Friend* f = FriendList::findFriend(friendId); diff --git a/widget/friendwidget.h b/widget/friendwidget.h index b174c2914..aae226bab 100644 --- a/widget/friendwidget.h +++ b/widget/friendwidget.h @@ -22,21 +22,18 @@ #include #include +#include "genericchatroomwidget.h" #include "croppinglabel.h" -struct FriendWidget : public QWidget +struct FriendWidget : public GenericChatroomWidget { Q_OBJECT public: FriendWidget(int FriendId, QString id); void mouseReleaseEvent (QMouseEvent* event); - void mousePressEvent(QMouseEvent *event); void contextMenuEvent(QContextMenuEvent * event); - void enterEvent(QEvent* event); - void leaveEvent(QEvent* event); void setAsActiveChatroom(); void setAsInactiveChatroom(); - int isActive(); void updateStatusLight(); signals: @@ -48,12 +45,6 @@ public: int friendId; QLabel avatar, statusPic; CroppingLabel name, statusMessage; - QHBoxLayout layout; - QVBoxLayout textLayout; - -private: - QColor lastColor; - int isActiveWidget; }; #endif // FRIENDWIDGET_H diff --git a/widget/genericchatroomwidget.cpp b/widget/genericchatroomwidget.cpp new file mode 100644 index 000000000..339fa125e --- /dev/null +++ b/widget/genericchatroomwidget.cpp @@ -0,0 +1,68 @@ +/* + Copyright (C) 2014 by Project Tox + + 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. +*/ + +#include "genericchatroomwidget.h" +#include + +GenericChatroomWidget::GenericChatroomWidget(QWidget *parent) : + QWidget(parent) +{ +} + +int GenericChatroomWidget::isActive() +{ + return isActiveWidget; +} + +void GenericChatroomWidget::mousePressEvent(QMouseEvent *event) +{ + if ((event->buttons() & Qt::LeftButton) == Qt::LeftButton) + { + if (isActive()) + { + QPalette pal; + pal.setColor(QPalette::Background, QColor(250,250,250,255)); + this->setPalette(pal); + } + else + { + QPalette pal; + pal.setColor(QPalette::Background, QColor(85,85,85,255)); + this->setPalette(pal); + } + } +} + +void GenericChatroomWidget::leaveEvent(QEvent *) +{ + if (isActive() != 1) + { + QPalette pal; + pal.setColor(QPalette::Background, lastColor); + this->setPalette(pal); + } +} + +void GenericChatroomWidget::enterEvent(QEvent *) +{ + if (isActive() != 1) + { + QPalette pal; + pal.setColor(QPalette::Background, QColor(75,75,75,255)); + lastColor = this->palette().background().color(); + this->setPalette(pal); + } +} diff --git a/widget/genericchatroomwidget.h b/widget/genericchatroomwidget.h new file mode 100644 index 000000000..7960dd099 --- /dev/null +++ b/widget/genericchatroomwidget.h @@ -0,0 +1,50 @@ +/* + Copyright (C) 2014 by Project Tox + + 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. +*/ + +#ifndef GENERICCHATROOMWIDGET_H +#define GENERICCHATROOMWIDGET_H + +#include +#include +#include + +class GenericChatroomWidget : public QWidget +{ + Q_OBJECT +public: + GenericChatroomWidget(QWidget *parent = 0); + void mousePressEvent(QMouseEvent *event); + void leaveEvent(QEvent *); + void enterEvent(QEvent *); + + virtual void setAsActiveChatroom(){;} + virtual void setAsInactiveChatroom(){;} + virtual void updateStatusLight(){;} + int isActive(); + +signals: + void chatroomWidgetClicked(GenericChatroomWidget* widget); + +public slots: + +protected: + int isActiveWidget; + QColor lastColor; + QHBoxLayout layout; + QVBoxLayout textLayout; +}; + +#endif // GENERICCHATROOMWIDGET_H diff --git a/widget/groupwidget.cpp b/widget/groupwidget.cpp index ac0608b1b..1f3e695a6 100644 --- a/widget/groupwidget.cpp +++ b/widget/groupwidget.cpp @@ -94,46 +94,6 @@ void GroupWidget::contextMenuEvent(QContextMenuEvent * event) } } -void GroupWidget::mousePressEvent(QMouseEvent *event) -{ - if ((event->buttons() & Qt::LeftButton) == Qt::LeftButton) - { - if (isActiveWidget) - { - QPalette pal; - pal.setColor(QPalette::Background, QColor(250,250,250,255)); - this->setPalette(pal); - } - else - { - QPalette pal; - pal.setColor(QPalette::Background, QColor(85,85,85,255)); - this->setPalette(pal); - } - } -} - -void GroupWidget::enterEvent(QEvent*) -{ - if (isActiveWidget != 1) - { - QPalette pal; - pal.setColor(QPalette::Background, QColor(75,75,75,255)); - lastColor = this->palette().background().color(); - this->setPalette(pal); - } -} - -void GroupWidget::leaveEvent(QEvent*) -{ - if (isActiveWidget != 1) - { - QPalette pal; - pal.setColor(QPalette::Background, lastColor); - this->setPalette(pal); - } -} - void GroupWidget::onUserListChanged() { Group* g = GroupList::findGroup(groupId); @@ -180,3 +140,8 @@ void GroupWidget::setAsInactiveChatroom() this->setPalette(pal3); avatar.setPixmap(QPixmap(":img/group.png")); } + +void GroupWidget::updateStatusLight() +{ + +} diff --git a/widget/groupwidget.h b/widget/groupwidget.h index ab2cf8929..ef21cda11 100644 --- a/widget/groupwidget.h +++ b/widget/groupwidget.h @@ -19,22 +19,19 @@ #include #include -#include -#include +#include "genericchatroomwidget.h" -class GroupWidget : public QWidget +class GroupWidget : public GenericChatroomWidget { Q_OBJECT public: GroupWidget(int GroupId, QString Name); void onUserListChanged(); void mouseReleaseEvent (QMouseEvent* event); - void mousePressEvent(QMouseEvent *event); void contextMenuEvent(QContextMenuEvent * event); - void enterEvent(QEvent* event); - void leaveEvent(QEvent* event); void setAsInactiveChatroom(); void setAsActiveChatroom(); + void updateStatusLight(); signals: void groupWidgetClicked(GroupWidget* widget); @@ -43,12 +40,6 @@ signals: public: int groupId; QLabel avatar, name, nusers, statusPic; - QHBoxLayout layout; - QVBoxLayout textLayout; - -private: - QColor lastColor; - int isActiveWidget; }; #endif // GROUPWIDGET_H From e76464a320ff39f498dd4677b837710ff8967a0f Mon Sep 17 00:00:00 2001 From: apprb Date: Mon, 1 Sep 2014 23:20:28 +0700 Subject: [PATCH 141/149] further GroupWidget and FriendWidget unification: activeFriendWidget and activeGroupWidget pointers replaced by the unified activeChatroomWidget pointer --- widget/friendwidget.cpp | 17 ++-- widget/friendwidget.h | 3 +- widget/genericchatroomwidget.cpp | 5 ++ widget/genericchatroomwidget.h | 8 ++ widget/groupwidget.cpp | 41 ++++++++-- widget/groupwidget.h | 3 +- widget/widget.cpp | 135 +++++++------------------------ widget/widget.h | 9 +-- 8 files changed, 98 insertions(+), 123 deletions(-) diff --git a/widget/friendwidget.cpp b/widget/friendwidget.cpp index d703bfd60..97c7b9c77 100644 --- a/widget/friendwidget.cpp +++ b/widget/friendwidget.cpp @@ -76,11 +76,6 @@ FriendWidget::FriendWidget(int FriendId, QString id) updateGeometry(); } -void FriendWidget::mouseReleaseEvent (QMouseEvent*) -{ - emit friendWidgetClicked(this); -} - void FriendWidget::contextMenuEvent(QContextMenuEvent * event) { QPoint pos = event->globalPos(); @@ -182,3 +177,15 @@ void FriendWidget::updateStatusLight() else if (status == Status::Offline && f->hasNewEvents == 1) statusPic.setPixmap(QPixmap(":img/status/dot_away_notification.png")); } + +void FriendWidget::setChatForm(Ui::MainWindow &ui) +{ + Friend* f = FriendList::findFriend(friendId); + f->chatForm->show(ui); +} + +void FriendWidget::resetEventFlags() +{ + Friend* f = FriendList::findFriend(friendId); + f->hasNewEvents = 0; +} diff --git a/widget/friendwidget.h b/widget/friendwidget.h index aae226bab..257d48a24 100644 --- a/widget/friendwidget.h +++ b/widget/friendwidget.h @@ -30,11 +30,12 @@ struct FriendWidget : public GenericChatroomWidget Q_OBJECT public: FriendWidget(int FriendId, QString id); - void mouseReleaseEvent (QMouseEvent* event); void contextMenuEvent(QContextMenuEvent * event); void setAsActiveChatroom(); void setAsInactiveChatroom(); void updateStatusLight(); + void setChatForm(Ui::MainWindow &); + void resetEventFlags(); signals: void friendWidgetClicked(FriendWidget* widget); diff --git a/widget/genericchatroomwidget.cpp b/widget/genericchatroomwidget.cpp index 339fa125e..234da1222 100644 --- a/widget/genericchatroomwidget.cpp +++ b/widget/genericchatroomwidget.cpp @@ -66,3 +66,8 @@ void GenericChatroomWidget::enterEvent(QEvent *) this->setPalette(pal); } } + +void GenericChatroomWidget::mouseReleaseEvent(QMouseEvent*) +{ + emit chatroomWidgetClicked(this); +} diff --git a/widget/genericchatroomwidget.h b/widget/genericchatroomwidget.h index 7960dd099..14e46c16e 100644 --- a/widget/genericchatroomwidget.h +++ b/widget/genericchatroomwidget.h @@ -21,18 +21,26 @@ #include #include +namespace Ui { + class MainWindow; +} + class GenericChatroomWidget : public QWidget { Q_OBJECT public: GenericChatroomWidget(QWidget *parent = 0); void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent (QMouseEvent* event); void leaveEvent(QEvent *); void enterEvent(QEvent *); virtual void setAsActiveChatroom(){;} virtual void setAsInactiveChatroom(){;} virtual void updateStatusLight(){;} + virtual void setChatForm(Ui::MainWindow &){;} + virtual void resetEventFlags(){;} + int isActive(); signals: diff --git a/widget/groupwidget.cpp b/widget/groupwidget.cpp index 1f3e695a6..b8c1cbcc0 100644 --- a/widget/groupwidget.cpp +++ b/widget/groupwidget.cpp @@ -17,10 +17,14 @@ #include "groupwidget.h" #include "grouplist.h" #include "group.h" +#include "settings.h" +#include "widget/form/groupchatform.h" #include #include #include +#include "ui_mainwindow.h" + GroupWidget::GroupWidget(int GroupId, QString Name) : groupId{GroupId} { @@ -72,11 +76,6 @@ GroupWidget::GroupWidget(int GroupId, QString Name) isActiveWidget = 0; } -void GroupWidget::mouseReleaseEvent (QMouseEvent*) -{ - emit groupWidgetClicked(this); -} - void GroupWidget::contextMenuEvent(QContextMenuEvent * event) { QPoint pos = event->globalPos(); @@ -143,5 +142,37 @@ void GroupWidget::setAsInactiveChatroom() void GroupWidget::updateStatusLight() { + Group *g = GroupList::findGroup(groupId); + if (Settings::getInstance().getUseNativeDecoration()) + { + if (g->hasNewMessages == 0) + { + statusPic.setPixmap(QPixmap(":img/status/dot_online.png")); + } else { + if (g->userWasMentioned == 0) statusPic.setPixmap(QPixmap(":img/status/dot_online_notification.png")); + else statusPic.setPixmap(QPixmap(":img/status/dot_online_notification.png")); + } + } else { + if (g->hasNewMessages == 0) + { + statusPic.setPixmap(QPixmap(":img/status/dot_groupchat.png")); + } else { + if (g->userWasMentioned == 0) statusPic.setPixmap(QPixmap(":img/status/dot_groupchat_newmessages.png")); + else statusPic.setPixmap(QPixmap(":img/status/dot_groupchat_notification.png")); + } + } +} + +void GroupWidget::setChatForm(Ui::MainWindow &ui) +{ + Group* g = GroupList::findGroup(groupId); + g->chatForm->show(ui); +} + +void GroupWidget::resetEventFlags() +{ + Group* g = GroupList::findGroup(groupId); + g->hasNewMessages = 0; + g->userWasMentioned = 0; } diff --git a/widget/groupwidget.h b/widget/groupwidget.h index ef21cda11..c32db80a6 100644 --- a/widget/groupwidget.h +++ b/widget/groupwidget.h @@ -27,11 +27,12 @@ class GroupWidget : public GenericChatroomWidget public: GroupWidget(int GroupId, QString Name); void onUserListChanged(); - void mouseReleaseEvent (QMouseEvent* event); void contextMenuEvent(QContextMenuEvent * event); void setAsInactiveChatroom(); void setAsActiveChatroom(); void updateStatusLight(); + void setChatForm(Ui::MainWindow &); + void resetEventFlags(); signals: void groupWidgetClicked(GroupWidget* widget); diff --git a/widget/widget.cpp b/widget/widget.cpp index 851502df0..1b67f05b3 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -43,8 +43,7 @@ Widget *Widget::instance{nullptr}; Widget::Widget(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), - activeFriendWidget{nullptr}, - activeGroupWidget{nullptr} + activeChatroomWidget{nullptr} { ui->setupUi(this); @@ -323,16 +322,14 @@ void Widget::onTransferClicked() { hideMainForms(); filesForm.show(*ui); - activeFriendWidget = nullptr; - activeGroupWidget = nullptr; + activeChatroomWidget = nullptr; } void Widget::onSettingsClicked() { hideMainForms(); settingsForm.show(*ui); - activeFriendWidget = nullptr; - activeGroupWidget = nullptr; + activeChatroomWidget = nullptr; } void Widget::hideMainForms() @@ -343,17 +340,9 @@ void Widget::hideMainForms() while ((item = ui->mainContent->layout()->takeAt(0)) != 0) item->widget()->hide(); - if (activeFriendWidget != nullptr) + if (activeChatroomWidget != nullptr) { - Friend* f = FriendList::findFriend(activeFriendWidget->friendId); - if (f != nullptr) - activeFriendWidget->setAsInactiveChatroom(); - } - if (activeGroupWidget != nullptr) - { - Group* g = GroupList::findGroup(activeGroupWidget->groupId); - if (g != nullptr) - activeGroupWidget->setAsInactiveChatroom(); + activeChatroomWidget->setAsInactiveChatroom(); } } @@ -411,7 +400,7 @@ void Widget::addFriend(int friendId, const QString &userId) Friend* newfriend = FriendList::addFriend(friendId, userId); QLayout* layout = contactListWidget->getFriendLayout(Status::Offline); layout->addWidget(newfriend->widget); - connect(newfriend->widget, SIGNAL(friendWidgetClicked(FriendWidget*)), this, SLOT(onFriendWidgetClicked(FriendWidget*))); + connect(newfriend->widget, SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), this, SLOT(onChatroomWidgetClicked(GenericChatroomWidget*))); connect(newfriend->widget, SIGNAL(removeFriend(int)), this, SLOT(removeFriend(int))); connect(newfriend->widget, SIGNAL(copyFriendIdToClipboard(int)), this, SLOT(copyFriendIdToClipboard(int))); connect(newfriend->chatForm, SIGNAL(sendMessage(int,QString)), core, SLOT(sendMessage(int,QString))); @@ -492,26 +481,18 @@ void Widget::onFriendUsernameLoaded(int friendId, const QString& username) f->setName(username); } -void Widget::onFriendWidgetClicked(FriendWidget *widget) +void Widget::onChatroomWidgetClicked(GenericChatroomWidget *widget) { - Friend* f = FriendList::findFriend(widget->friendId); - if (!f) - return; - hideMainForms(); - f->chatForm->show(*ui); - if (activeFriendWidget != nullptr) + widget->setChatForm(*ui); + if (activeChatroomWidget != nullptr) { - activeFriendWidget->setAsInactiveChatroom(); + activeChatroomWidget->setAsInactiveChatroom(); } - activeFriendWidget = widget; + activeChatroomWidget = widget; widget->setAsActiveChatroom(); - activeGroupWidget = nullptr; - - if (f->hasNewEvents != 0) - f->hasNewEvents = 0; - - f->widget->updateStatusLight(); + widget->resetEventFlags(); + widget->updateStatusLight(); } void Widget::onFriendMessageReceived(int friendId, const QString& message) @@ -522,10 +503,9 @@ void Widget::onFriendMessageReceived(int friendId, const QString& message) f->chatForm->addFriendMessage(message); - if (activeFriendWidget != nullptr) + if (activeChatroomWidget != nullptr) { - Friend* f2 = FriendList::findFriend(activeFriendWidget->friendId); - if ((f->friendId != f2->friendId) || isWindowMinimized || !isActiveWindow()) + if ((static_cast(f->widget) != activeChatroomWidget) || isWindowMinimized || !isActiveWindow()) { f->hasNewEvents = 1; newMessageAlert(); @@ -572,8 +552,8 @@ void Widget::removeFriend(int friendId) { Friend* f = FriendList::findFriend(friendId); f->widget->setAsInactiveChatroom(); - if (f->widget == activeFriendWidget) - activeFriendWidget = nullptr; + if (static_cast(f->widget) == activeChatroomWidget) + activeChatroomWidget = nullptr; FriendList::removeFriend(friendId); core->removeFriend(friendId); delete f; @@ -609,27 +589,15 @@ void Widget::onGroupMessageReceived(int groupnumber, int friendgroupnumber, cons g->chatForm->addGroupMessage(message, friendgroupnumber); - if (((activeGroupWidget && g->groupId != activeGroupWidget->groupId)) || isWindowMinimized || !isActiveWindow()) + if ((static_cast(g->widget) != activeChatroomWidget) || isWindowMinimized || !isActiveWindow()) { + g->hasNewMessages = 1; if (message.contains(core->getUsername(), Qt::CaseInsensitive)) { newMessageAlert(); - g->hasNewMessages = 1; g->userWasMentioned = 1; - if (Settings::getInstance().getUseNativeDecoration()) - g->widget->statusPic.setPixmap(QPixmap(":img/status/dot_online_notification.png")); - else - g->widget->statusPic.setPixmap(QPixmap(":img/status/dot_groupchat_notification.png")); } - else - if (g->hasNewMessages == 0) - { - g->hasNewMessages = 1; - if (Settings::getInstance().getUseNativeDecoration()) - g->widget->statusPic.setPixmap(QPixmap(":img/status/dot_online_notification.png")); - else - g->widget->statusPic.setPixmap(QPixmap(":img/status/dot_groupchat_newmessages.png")); - } + g->widget->updateStatusLight(); } } @@ -651,39 +619,12 @@ void Widget::onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t Cha g->updatePeer(peernumber,core->getGroupPeerName(groupnumber, peernumber)); } -void Widget::onGroupWidgetClicked(GroupWidget* widget) -{ - Group* g = GroupList::findGroup(widget->groupId); - if (!g) - return; - - hideMainForms(); - g->chatForm->show(*ui); - if (activeGroupWidget != nullptr) - { - activeGroupWidget->setAsInactiveChatroom(); - } - activeGroupWidget = widget; - widget->setAsActiveChatroom(); - activeFriendWidget = nullptr; - - if (g->hasNewMessages != 0) - { - g->hasNewMessages = 0; - g->userWasMentioned = 0; - if (Settings::getInstance().getUseNativeDecoration()) - g->widget->statusPic.setPixmap(QPixmap(":img/status/dot_online.png")); - else - g->widget->statusPic.setPixmap(QPixmap(":img/status/dot_groupchat.png")); - } -} - void Widget::removeGroup(int groupId) { Group* g = GroupList::findGroup(groupId); g->widget->setAsInactiveChatroom(); - if (g->widget == activeGroupWidget) - activeGroupWidget = nullptr; + if (static_cast(g->widget) == activeChatroomWidget) + activeChatroomWidget = nullptr; GroupList::removeGroup(groupId); core->removeGroup(groupId); delete g; @@ -709,10 +650,9 @@ Group *Widget::createGroup(int groupId) Group* newgroup = GroupList::addGroup(groupId, groupName); QLayout* layout = contactListWidget->getGroupLayout(); layout->addWidget(newgroup->widget); - if (!Settings::getInstance().getUseNativeDecoration()) - newgroup->widget->statusPic.setPixmap(QPixmap(":img/status/dot_groupchat.png")); + newgroup->widget->updateStatusLight(); - connect(newgroup->widget, SIGNAL(groupWidgetClicked(GroupWidget*)), this, SLOT(onGroupWidgetClicked(GroupWidget*))); + connect(newgroup->widget, SIGNAL(chatroomWidgetClicked(GenericChatroomWidget*)), this, SLOT(onChatroomWidgetClicked(GenericChatroomWidget*))); connect(newgroup->widget, SIGNAL(removeGroup(int)), this, SLOT(removeGroup(int))); connect(newgroup->chatForm, SIGNAL(sendMessage(int,QString)), core, SLOT(sendGroupMessage(int,QString))); return newgroup; @@ -732,15 +672,11 @@ bool Widget::isFriendWidgetCurActiveWidget(Friend* f) { if (!f) return false; - if (activeFriendWidget != nullptr) - { - Friend* f2 = FriendList::findFriend(activeFriendWidget->friendId); - if (f->friendId != f2->friendId) - return false; - } + + if (activeChatroomWidget == static_cast(f->widget)) + return true; else return false; - return true; } bool Widget::event(QEvent * e) @@ -761,21 +697,10 @@ bool Widget::event(QEvent * e) this->style()->polish(this); } isWindowMinimized = 0; - if (activeFriendWidget != nullptr) + if (activeChatroomWidget != nullptr) { - Friend* f = FriendList::findFriend(activeFriendWidget->friendId); - f->hasNewEvents = 0; - f->widget->updateStatusLight(); - } - else if (activeGroupWidget != nullptr) - { - Group* g = GroupList::findGroup(activeGroupWidget->groupId); - g->hasNewMessages = 0; - g->userWasMentioned = 0; - if (Settings::getInstance().getUseNativeDecoration()) - g->widget->statusPic.setPixmap(QPixmap(":img/status/dot_online.png")); - else - g->widget->statusPic.setPixmap(QPixmap(":img/status/dot_groupchat.png")); + activeChatroomWidget->resetEventFlags(); + activeChatroomWidget->updateStatusLight(); } } else if (e->type() == QEvent::WindowDeactivate && !Settings::getInstance().getUseNativeDecoration()) diff --git a/widget/widget.h b/widget/widget.h index ffba4c5ab..4559862f4 100644 --- a/widget/widget.h +++ b/widget/widget.h @@ -35,8 +35,7 @@ namespace Ui { class MainWindow; } -class GroupWidget; -struct FriendWidget; +class GenericChatroomWidget; class Group; struct Friend; @@ -95,14 +94,13 @@ private slots: void onFriendUsernameChanged(int friendId, const QString& username); void onFriendStatusMessageLoaded(int friendId, const QString& message); void onFriendUsernameLoaded(int friendId, const QString& username); - void onFriendWidgetClicked(FriendWidget* widget); + void onChatroomWidgetClicked(GenericChatroomWidget *); void onFriendMessageReceived(int friendId, const QString& message); void onFriendRequestReceived(const QString& userId, const QString& message); void onEmptyGroupCreated(int groupId); void onGroupInviteReceived(int32_t friendId, const uint8_t *publicKey); void onGroupMessageReceived(int groupnumber, int friendgroupnumber, const QString& message); void onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t change); - void onGroupWidgetClicked(GroupWidget* widget); void removeFriend(int friendId); void copyFriendIdToClipboard(int friendId); void removeGroup(int groupId); @@ -142,8 +140,7 @@ private: SettingsForm settingsForm; FilesForm filesForm; static Widget* instance; - FriendWidget* activeFriendWidget; - GroupWidget* activeGroupWidget; + GenericChatroomWidget* activeChatroomWidget; FriendListWidget* contactListWidget; SelfCamView* camview; Camera* camera; From 532b8cec838baeefb781d0bfec600190bd1478cd Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Mon, 1 Sep 2014 20:33:04 +0200 Subject: [PATCH 142/149] Add Jenkins build config --- qtox.pro | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/qtox.pro b/qtox.pro index 8f87e7255..8bedf38f1 100644 --- a/qtox.pro +++ b/qtox.pro @@ -36,7 +36,11 @@ TRANSLATIONS = translations/de.ts \ RESOURCES += res.qrc -INCLUDEPATH += libs/include +contains(JENKINS,YES) { + INCLUDEPATH += ./libs/include/ +} else { + INCLUDEPATH += libs/include +} # Rules for Windows, Mac OSX, and Linux win32 { @@ -52,6 +56,10 @@ win32 { } else { LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -lvpx -lopenal -lopencv_core -lopencv_highgui } + + contains(JENKINS, YES) { + LIBS = ./libs/lib/libtoxav.a ./libs/lib/libvpx.a ./libs/lib/libopus.a ./libs/lib/libtoxcore.a ./libs/lib/libsodium.a -lopencv_core -lopencv_highgui -lopenal + } } From 33064cdd17c0cc2ecdabf702af45481087221127 Mon Sep 17 00:00:00 2001 From: Bill Winslow Date: Mon, 1 Sep 2014 13:45:48 -0500 Subject: [PATCH 143/149] modify buildPackages --- buildPackages.sh | 54 ++++++++++++++++++++++++++++++++++++++++++ coreav.cpp | 16 +++++++++++++ tools/buildPackages.sh | 31 ------------------------ 3 files changed, 70 insertions(+), 31 deletions(-) create mode 100755 buildPackages.sh delete mode 100644 tools/buildPackages.sh diff --git a/buildPackages.sh b/buildPackages.sh new file mode 100755 index 000000000..cddbe29fa --- /dev/null +++ b/buildPackages.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +# Config (Update me if needed !) +VERSION_UPSTREAM="1.0" +VERSION_PACKAGE="1" +PACKAGENAME="qtox" +UPSTREAM_URL="https://github.com/tux3/qTox/archive/master.tar.gz" + +# Make some vars for convenience +VERNAME=$PACKAGENAME"_"$VERSION_UPSTREAM +FULLVERNAME=$VERNAME"-"$VERSION_PACKAGE +ARCHIVENAME=$VERNAME".orig.tar.gz" + +# ARCHIVENAME > FULLVERNAME > VERNAME = PACKAGENAME+UPVER + +# Get the requried tools if needed +echo "Installing missing tools (if any)..." +if [[ $EUID -ne 0 ]]; then + sudo apt-get install wget debhelper cdbs devscripts alien tar gzip build-essential +else + apt-get install wget debhelper cdbs devscripts alien tar gzip build-essential +fi + +mkdir -p .packages +cd .packages + +# Cleanup +rm -r $VERNAME 2> /dev/null +rm $ARCHIVENAME 2> /dev/null + +# Fectch sources and layout directories +wget -O $ARCHIVENAME $UPSTREAM_URL +tar xvf $ARCHIVENAME # Extracts to qTox-master +mv qTox-master $VERNAME +#tar cz $VERNAME > $ARCHIVENAME + +# Build packages +cd $VERNAME +debuild -us -uc +cd .. + +# alien warns that it should probably be run as root... +if [[ $EUID -ne 0 ]]; then + sudo alien ./$FULLVERNAME*.deb -r +else + alien ./$FULLVERNAME*.deb -r +fi + +mv *.deb .. +mv *.rpm .. + +rm -r * +cd .. +rmdir .packages diff --git a/coreav.cpp b/coreav.cpp index 2b18e37d4..2a3ce7a67 100644 --- a/coreav.cpp +++ b/coreav.cpp @@ -1,3 +1,19 @@ +/* + Copyright (C) 2013 by Maxim Biro + + This file is part of Tox Qt GUI. + + 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 COPYING file for more details. +*/ + #include "core.h" #include "widget/widget.h" diff --git a/tools/buildPackages.sh b/tools/buildPackages.sh deleted file mode 100644 index 03e7415a2..000000000 --- a/tools/buildPackages.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -# Config (Update me if needed !) -VERSION_UPSTREAM="1.0" -VERSION_PACKAGE="1" -PACKAGENAME="qtox" -UPSTREAM_GIT_URL="https://github.com/tux3/qtox.git" - -# Make some vars for convenience -VERNAME=$PACKAGENAME"_"$VERSION_UPSTREAM -FULLVERNAME=$VERNAME"-"$VERSION_PACKAGE -ARCHIVENAME=$VERNAME".orig.tar.gz" - -# Get the requried tools if needed -echo "Installing missing tools (if any)..." -apt-get install git debhelper cdbs devscripts alien tar gzip build-essential - -# Cleanup -rm -r $VERNAME 2> /dev/null -rm $ARCHIVENAME 2> /dev/null - -# Fectche sources and layour directories -git clone --depth 1 $UPSTREAM_GIT_URL -mv $PACKAGENAME $VERNAME -tar cz $VERNAME > $ARCHIVENAME - -# Build packages -cd $VERNAME -debuild -us -uc -cd .. -alien ./$FULLVERNAME*.deb -r From 68649cb44854a046e0adda5bf2ddbbff07f379ae Mon Sep 17 00:00:00 2001 From: Bill Winslow Date: Mon, 1 Sep 2014 14:09:31 -0500 Subject: [PATCH 144/149] Fancy package script --- buildPackages.sh | 68 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 12 deletions(-) diff --git a/buildPackages.sh b/buildPackages.sh index cddbe29fa..dc01f4a82 100755 --- a/buildPackages.sh +++ b/buildPackages.sh @@ -13,12 +13,53 @@ ARCHIVENAME=$VERNAME".orig.tar.gz" # ARCHIVENAME > FULLVERNAME > VERNAME = PACKAGENAME+UPVER +# Get some args +OPT_SUDO=true +OPT_APT=true +OPT_KEEP=false +while [ $# -ge 1 ] ; do + if [ ${1} = "-s" -o ${1} = "--no-sudo" ] ; then + OPT_SUDO=false + shift + elif [ ${1} = "-a" -o ${1} = "--no-apt" ] ; then + OPT_APT=false + shift + elif [ ${1} = "-k" -o ${1} = "--keep" ]; then + OPT_KEEP=true + shift + else + if [ ${1} != "-h" -a ${1} != "--help" ] ; then + echo "[ERROR] Unknown parameter \"${1}\"" + echo "" + fi + + # print help + echo "Use this script to build qTox packages for Debian and Red Hat families" + echo "" + echo "usage:" + echo " ${0} [-h|--help|-k|--keep|-s|--no-sudo|-a|--no-apt]" + echo "" + echo "parameters:" + echo " -h|--help : displays this help" + echo " -s|--no-sudo: disables using sudo for apt and alien" + echo " -a|--no-apt : disables apt-get (used for build deps) entirely" + echo " -k|--keep : does not delete the build files afterwards" + echo "" + echo "example usages:" + echo " ${0} -- build packages, cleaning up trash and running sudo alien and apt-get" + echo " ${0} -s -k -- build packages, keeping build files and non-sudo alien and apt-get" + exit 1 + fi +done + # Get the requried tools if needed -echo "Installing missing tools (if any)..." -if [[ $EUID -ne 0 ]]; then - sudo apt-get install wget debhelper cdbs devscripts alien tar gzip build-essential -else - apt-get install wget debhelper cdbs devscripts alien tar gzip build-essential +if [[ $OPT_APT = "true" ]]; then + echo "Installing missing tools (if any)..." + if [[ $EUID -ne 0 && $OPT_SUDO = "true" ]]; then + sudo apt-get install wget debhelper cdbs devscripts alien tar gzip build-essential + else + apt-get install wget debhelper cdbs devscripts alien tar gzip build-essential + fi fi mkdir -p .packages @@ -30,7 +71,7 @@ rm $ARCHIVENAME 2> /dev/null # Fectch sources and layout directories wget -O $ARCHIVENAME $UPSTREAM_URL -tar xvf $ARCHIVENAME # Extracts to qTox-master +tar xvf $ARCHIVENAME 2> /dev/null # Extracts to qTox-master mv qTox-master $VERNAME #tar cz $VERNAME > $ARCHIVENAME @@ -40,15 +81,18 @@ debuild -us -uc cd .. # alien warns that it should probably be run as root... -if [[ $EUID -ne 0 ]]; then - sudo alien ./$FULLVERNAME*.deb -r +if [[ $EUID -ne 0 && $OPT_SUDO = "true" ]]; then + sudo alien ./$FULLVERNAME*.deb -r else - alien ./$FULLVERNAME*.deb -r + alien ./$FULLVERNAME*.deb -r fi mv *.deb .. -mv *.rpm .. +mv -f *.rpm .. + +if [[ $OPT_KEEP = "false" ]]; then + rm -r * +fi -rm -r * cd .. -rmdir .packages +rmdir .packages 2> /dev/null # fails if non empty From 8a64a415a068781da88b8431864966788784f4a6 Mon Sep 17 00:00:00 2001 From: Bill Winslow Date: Mon, 1 Sep 2014 14:20:06 -0500 Subject: [PATCH 145/149] moved packages script back to tools --- buildPackages.sh => tools/buildPackages.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename buildPackages.sh => tools/buildPackages.sh (100%) diff --git a/buildPackages.sh b/tools/buildPackages.sh similarity index 100% rename from buildPackages.sh rename to tools/buildPackages.sh From 3ea7fc0f0ac6184b82db71c8a16db291ef45c247 Mon Sep 17 00:00:00 2001 From: Bill Winslow Date: Mon, 1 Sep 2014 15:47:40 -0500 Subject: [PATCH 146/149] Updated README.md, fix 239 --- README.md | 57 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 0e4f060b8..81e1f665a 100644 --- a/README.md +++ b/README.md @@ -15,29 +15,64 @@ However, it is not a fork. - Tox DNS - Translations in various languages -

Requirements

+

Downloads

-This client runs on Windows, Linux and Mac natively, but is not build regularly for Linux
-Linux users will have to compile the source code themselves if they want the latest updates. +This client runs on Windows, Linux and Mac natively.
Windows download
Mac download
-Linux download (12st July 2014 20:30 GMT)
-Note that the Linux download has not been tested and may not be up to date.
+Linux download (click "Last successful artifacts")

Screenshots

Note: The screenshots may not always be up to date, but they should give a good idea of the general look and features
-

Compiling

-Compiling toxgui requires Qt 5.2 with the Qt Multimedia module and a C++11 compatible compiler. -It also requires the toxcore and toxav libraries. +

Compiling on GNU-Linux

+

Acquiring dependencies

+Compiling qTox requires several dependencies, however these are easily installable +with your system's package manager. The step-by-step instructions assume Debian-style apt, but +it should be easy enough to get the packes with yum or pacman. -To compile, first clone or download the qTox repository and open a terminal in the qTox folder. -Then run the script bootstrap.sh (for Linux and Mac) or bootsrap.bat (for Windows) to download an up-to-date toxcore. -And finally run the commands "qmake" and "make" to start building qTox. +First, we need Qt 5.2 with a C++11 compatible compiler: +```bash +sudo apt-get install build-essential qt5-qmake qt5-default +``` +toxcore and toxav, the client-agnostic network code for Tox, has several dependencies +of its own (see its installation guide for more details): +```bash +sudo apt-get install libtool autotools-dev automake checkinstall check git yasm libopus-dev libvpx-dev +``` + +Finally, qTox itself requires OpenAL and OpenCV: +```bash +sudo apt-get install libopenal-dev libopencv-dev +``` + +

Compilation

+ +Having acquired all the dependencies, the following commands should get and compile qTox: + +```bash +wget -O qtox.tgz https://github.com/tux3/qTox/archive/master.tar.gz +tar xvf qtox.tgz +cd qTox-master +./bootstrap.sh # This will automagically download and compile libsodium, toxcore, and toxav +qmake +make # Should compile to "qtox" +``` + +And that's it! + +

Building packages

+ +qTox now has the experimental and probably-dodgy ability to package itself (in .deb +form natively, and .rpm form with alien). + +After installing the required dependencies, run `bootstrap.sh` and then run the +`buildPackages.sh` script, found in the tools folder. It will automatically get the +necessary packages for building .debs, so be prepared to type your password for sudo.

OSX Easy Install

From 9ea2566ba003c3ca74cc5a1b61f568abb657aad6 Mon Sep 17 00:00:00 2001 From: Bill Winslow Date: Mon, 1 Sep 2014 15:52:51 -0500 Subject: [PATCH 147/149] minutiae --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 81e1f665a..6264fbf25 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ This client runs on Windows, Linux and Mac natively.

Acquiring dependencies

Compiling qTox requires several dependencies, however these are easily installable with your system's package manager. The step-by-step instructions assume Debian-style apt, but -it should be easy enough to get the packes with yum or pacman. +it should be easy enough to get equivalent packages with yum or pacman. First, we need Qt 5.2 with a C++11 compatible compiler: ```bash @@ -40,7 +40,7 @@ sudo apt-get install build-essential qt5-qmake qt5-default ``` toxcore and toxav, the client-agnostic network code for Tox, has several dependencies -of its own (see its installation guide for more details): +of its own (see its installation guide for more details): ```bash sudo apt-get install libtool autotools-dev automake checkinstall check git yasm libopus-dev libvpx-dev ``` @@ -72,7 +72,7 @@ form natively, and .rpm form with alien< After installing the required dependencies, run `bootstrap.sh` and then run the `buildPackages.sh` script, found in the tools folder. It will automatically get the -necessary packages for building .debs, so be prepared to type your password for sudo. +packages necessary for building .debs, so be prepared to type your password for sudo.

OSX Easy Install

From 627f58087ce014bc229defebb0f56c7f54cd2af1 Mon Sep 17 00:00:00 2001 From: "Tux3 / Mlkj / !Lev.uXFMLA" Date: Wed, 3 Sep 2014 00:01:04 +0200 Subject: [PATCH 148/149] Disable status button when disconnected --- widget/widget.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/widget/widget.cpp b/widget/widget.cpp index 8757bfe66..81cd893bf 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -154,6 +154,9 @@ Widget::Widget(QWidget *parent) camera = new Camera; camview = new SelfCamView(camera); + // Disable some widgets until we're connected to the DHT + ui->statusButton->setEnabled(false); + qRegisterMetaType("Status"); qRegisterMetaType("vpx_image"); qRegisterMetaType("uint8_t"); @@ -267,11 +270,13 @@ Camera* Widget::getCamera() void Widget::onConnected() { + ui->statusButton->setEnabled(true); emit statusSet(Status::Online); } void Widget::onDisconnected() { + ui->statusButton->setEnabled(false); emit statusSet(Status::Offline); } From 2956c82091f5305357faa2a6271a8ed0ad5e70b7 Mon Sep 17 00:00:00 2001 From: Bill Winslow Date: Tue, 2 Sep 2014 18:03:55 -0500 Subject: [PATCH 149/149] package version is more appropriate --- debian/changelog | 2 +- debian/control | 4 +++- tools/buildPackages.sh | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index 1b56f518a..5b1593c67 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -qtox (1.0-1) UNRELEASED; urgency=medium local package +qtox (0.01pre-alpha-1) UNRELEASED; urgency=medium local package * Initial release. diff --git a/debian/control b/debian/control index 943501a77..ef73726b7 100644 --- a/debian/control +++ b/debian/control @@ -9,4 +9,6 @@ Package: qtox Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Tox client - qTox is a powerful Tox client that follows the Tox design guidelines + qTox is a powerful Tox client that follows the Tox design guidelines. + Tox is a decentralized and encrypted replacement for Skype, supporting + chats, audio, and video calls. diff --git a/tools/buildPackages.sh b/tools/buildPackages.sh index dc01f4a82..d0ec345c0 100755 --- a/tools/buildPackages.sh +++ b/tools/buildPackages.sh @@ -1,7 +1,7 @@ #!/bin/bash # Config (Update me if needed !) -VERSION_UPSTREAM="1.0" +VERSION_UPSTREAM="0.01pre-alpha" VERSION_PACKAGE="1" PACKAGENAME="qtox" UPSTREAM_URL="https://github.com/tux3/qTox/archive/master.tar.gz"