Merge branches 'pr920', 'pr1001', 'pr1003' and 'pr1005'
|
@ -14,6 +14,7 @@
|
|||
| Tox Core | most recent | core, av |
|
||||
| OpenCV | >= 2.4.9 | core, highgui, imgproc |
|
||||
| OpenAL Soft | >= 1.16.0 | |
|
||||
| filter_audio | most recent | |
|
||||
|
||||
|
||||
<a name="linux" />
|
||||
|
@ -127,6 +128,12 @@ cd /home/user/qTox
|
|||
./bootstrap.sh # use -h or --help for more information
|
||||
```
|
||||
|
||||
###filter_audio
|
||||
You also need to install filter_audio library separately if you did not run ``./bootstrap.sh``.
|
||||
```bash
|
||||
./install_libfilteraudio.sh
|
||||
```
|
||||
|
||||
After all the dependencies are thus reeady to go, compiling should be as simple as
|
||||
```bash
|
||||
qmake
|
||||
|
|
|
@ -37,6 +37,6 @@ This client runs on Windows, Linux and Mac natively.<br/>
|
|||
|
||||
##Developer overview:
|
||||
|
||||
[GitStats](http://207.12.89.155/index.html)<br/>
|
||||
[GitStats](http://104.219.184.93/index.html)<br/>
|
||||
[Mac & Linux jenkins](https://jenkins.libtoxcore.so/user/tux3/my-views/view/qTox/)<br/>
|
||||
[Windows jenkins](http://207.12.89.155:8080)<br/>
|
||||
[Windows jenkins](http://104.219.184.93:8080)<br/>
|
||||
|
|
14
bootstrap.sh
|
@ -15,6 +15,7 @@ SODIUM_VER=1.0.0
|
|||
# directory names of cloned repositories
|
||||
SODIUM_DIR=libsodium-$SODIUM_VER
|
||||
TOX_CORE_DIR=libtoxcore-latest
|
||||
FILTER_AUDIO_DIR=filter_audio
|
||||
|
||||
# this boolean describes whether the installation of
|
||||
# libsodium should be skipped or not
|
||||
|
@ -42,6 +43,11 @@ if [ -z "$TOX_CORE_DIR" ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$FILTER_AUDIO_DIR" ]; then
|
||||
echo "internal error detected!"
|
||||
echo "FILTER_AUDIO_DIR should not be empty... aborting"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
########## check input parameters ##########
|
||||
|
@ -95,7 +101,7 @@ mkdir -p ${BASE_DIR}
|
|||
# if exists, otherwise cloning them may fail
|
||||
rm -rf ${BASE_DIR}/${SODIUM_DIR}
|
||||
rm -rf ${BASE_DIR}/${TOX_CORE_DIR}
|
||||
|
||||
rm -rf ${BASE_DIR}/${FILTER_AUDIO_DIR}
|
||||
|
||||
|
||||
############### install step ###############
|
||||
|
@ -122,6 +128,12 @@ if [[ $TOX_ONLY = "false" ]]; then
|
|||
fi
|
||||
|
||||
popd
|
||||
|
||||
if [[ $GLOBAL = "false" ]]; then
|
||||
./install_libfilteraudio.sh ${BASE_DIR}/${FILTER_AUDIO_DIR} ${BASE_DIR}
|
||||
else
|
||||
./install_libfilteraudio.sh ${BASE_DIR}/${FILTER_AUDIO_DIR}
|
||||
fi
|
||||
fi
|
||||
|
||||
# clone current master of libtoxcore
|
||||
|
|
Before Width: | Height: | Size: 420 B After Width: | Height: | Size: 420 B |
Before Width: | Height: | Size: 716 B After Width: | Height: | Size: 716 B |
Before Width: | Height: | Size: 410 B After Width: | Height: | Size: 410 B |
Before Width: | Height: | Size: 719 B After Width: | Height: | Size: 719 B |
Before Width: | Height: | Size: 478 B After Width: | Height: | Size: 478 B |
Before Width: | Height: | Size: 704 B After Width: | Height: | Size: 704 B |
Before Width: | Height: | Size: 395 B After Width: | Height: | Size: 395 B |
Before Width: | Height: | Size: 711 B After Width: | Height: | Size: 711 B |
Before Width: | Height: | Size: 374 B After Width: | Height: | Size: 374 B |
Before Width: | Height: | Size: 637 B After Width: | Height: | Size: 637 B |
BIN
img/taskbar/light/taskbar_busy.png
Normal file
After Width: | Height: | Size: 386 B |
BIN
img/taskbar/light/taskbar_busy_2x.png
Normal file
After Width: | Height: | Size: 685 B |
BIN
img/taskbar/light/taskbar_idle.png
Normal file
After Width: | Height: | Size: 363 B |
BIN
img/taskbar/light/taskbar_idle_2x.png
Normal file
After Width: | Height: | Size: 635 B |
BIN
img/taskbar/light/taskbar_invisible.png
Normal file
After Width: | Height: | Size: 366 B |
BIN
img/taskbar/light/taskbar_invisible_2x.png
Normal file
After Width: | Height: | Size: 670 B |
BIN
img/taskbar/light/taskbar_offline.png
Normal file
After Width: | Height: | Size: 378 B |
BIN
img/taskbar/light/taskbar_offline_2x.png
Normal file
After Width: | Height: | Size: 677 B |
BIN
img/taskbar/light/taskbar_online.png
Normal file
After Width: | Height: | Size: 320 B |
BIN
img/taskbar/light/taskbar_online_2x.png
Normal file
After Width: | Height: | Size: 578 B |
40
install_libfilteraudio.sh
Executable file
|
@ -0,0 +1,40 @@
|
|||
#!/bin/sh
|
||||
|
||||
if [ -z $1 ]; then
|
||||
SOURCE_DIR="filter_audio/"
|
||||
else
|
||||
SOURCE_DIR="$1/"
|
||||
fi
|
||||
|
||||
if [ -z "$2" ]; then
|
||||
LIB_DIR="/usr/local/lib/"
|
||||
INCLUDE_DIR="/usr/local/include/"
|
||||
else
|
||||
LIB_DIR="$2/lib/"
|
||||
INCLUDE_DIR="$2/include/"
|
||||
fi
|
||||
|
||||
echo "Cloning filter_audio from GitHub.com"
|
||||
git clone https://github.com/irungentoo/filter_audio.git $SOURCE_DIR
|
||||
|
||||
echo "Compiling filter_audio"
|
||||
cd $SOURCE_DIR
|
||||
gcc -c -fPIC filter_audio.c aec/*.c agc/*.c ns/*.c other/*.c -lm -lpthread
|
||||
|
||||
echo "Creating shared object file"
|
||||
gcc *.o -shared -o libfilteraudio.so
|
||||
|
||||
echo "Cleaning up"
|
||||
rm *.o
|
||||
|
||||
muhcmd="cp libfilteraudio.so $LIB_DIR"
|
||||
[ -z "$2" ] && muhcmd="sudo $muhcmd"
|
||||
echo "Installing libfilteraudio.so with $muhcmd"
|
||||
$muhcmd
|
||||
|
||||
muhcmd="cp *.h $INCLUDE_DIR"
|
||||
[ -z "$2" ] && muhcmd="sudo $muhcmd"
|
||||
echo "Installing include files with $muhcmd"
|
||||
$muhcmd
|
||||
|
||||
echo "Finished."
|
|
@ -1,97 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
)
|
||||
|
||||
func fs_type(path string) int {
|
||||
//name := "FileOrDir"
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return -1
|
||||
}
|
||||
defer f.Close()
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return -1
|
||||
}
|
||||
switch mode := fi.Mode(); {
|
||||
case mode.IsDir():
|
||||
return 0
|
||||
case mode.IsRegular():
|
||||
return 1
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
func main() {
|
||||
usr, e := user.Current()
|
||||
if e != nil {
|
||||
log.Fatal(e)
|
||||
}
|
||||
|
||||
update_dir := usr.HomeDir + "/Library/Preferences/tox/update/"
|
||||
if _, err := os.Stat(update_dir); os.IsNotExist(err) {
|
||||
fmt.Println("Error: No update folder, is check for updates enabled?")
|
||||
return
|
||||
}
|
||||
fmt.Println("qTox Updater")
|
||||
|
||||
files, _ := ioutil.ReadDir(update_dir)
|
||||
killqtox := exec.Command("/usr/bin/killall", "qtox")
|
||||
_ = killqtox.Run()
|
||||
|
||||
for _, file := range files {
|
||||
if fs_type(update_dir+file.Name()) == 1 {
|
||||
fmt.Print("Installing: ")
|
||||
fmt.Println("/Applications/qtox.app/Contents/" + file.Name())
|
||||
if _, err := os.Stat("/Applications/qtox.app/Contents/" + file.Name()); os.IsNotExist(err) {
|
||||
newfile := exec.Command("/usr/libexec/authopen", "-c", "-x", "-m", "drwxrwxr-x+", "/Applications/qtox.app/Contents/"+file.Name())
|
||||
newfile.Run()
|
||||
}
|
||||
|
||||
cat := exec.Command("/bin/cat", update_dir+file.Name())
|
||||
auth := exec.Command("/usr/libexec/authopen", "-w", "/Applications/qtox.app/Contents/"+file.Name())
|
||||
auth.Stdin, _ = cat.StdoutPipe()
|
||||
auth.Stdout = os.Stdout
|
||||
auth.Stderr = os.Stderr
|
||||
_ = auth.Start()
|
||||
_ = cat.Run()
|
||||
_ = auth.Wait()
|
||||
|
||||
} else {
|
||||
files, _ := ioutil.ReadDir(update_dir + file.Name())
|
||||
for _, file2 := range files {
|
||||
fmt.Print("Installing: ")
|
||||
fmt.Println("/Applications/qtox.app/Contents/" + file.Name() + "/" + file2.Name())
|
||||
|
||||
if _, err := os.Stat("/Applications/qtox.app/Contents/" + file.Name() + "/" + file2.Name()); os.IsNotExist(err) {
|
||||
newfile := exec.Command("/usr/libexec/authopen", "-c", "-x", "-m", "drwxrwxr-x+", "/Applications/qtox.app/Contents/"+file.Name()+"/"+file2.Name())
|
||||
newfile.Run()
|
||||
}
|
||||
|
||||
cat := exec.Command("/bin/cat", update_dir+file.Name()+"/"+file2.Name())
|
||||
auth := exec.Command("/usr/libexec/authopen", "-w", "/Applications/qtox.app/Contents/"+file.Name()+"/"+file2.Name())
|
||||
auth.Stdin, _ = cat.StdoutPipe()
|
||||
auth.Stdout = os.Stdout
|
||||
auth.Stderr = os.Stderr
|
||||
_ = auth.Start()
|
||||
_ = cat.Run()
|
||||
_ = auth.Wait()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
os.RemoveAll(update_dir)
|
||||
fmt.Println("Update metadata wiped, launching qTox")
|
||||
launchqtox := exec.Command("/usr/bin/open", "-b", "im.tox.qtox")
|
||||
launchqtox.Run()
|
||||
}
|
23
osx/updater/.gitignore
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
13
osx/updater/README.md
Normal file
|
@ -0,0 +1,13 @@
|
|||
The qTox OS X updater is a mix of objective C and Go compiled as static binaries used do effortless updates in the background.
|
||||
|
||||
It uses Objective C to access Apples own security framework and call some long dead APIs in order to give the statically linked go updater permissions to install the latest build without prompting the user for every file.
|
||||
|
||||
* Release commits: ``https://github.com/Tox/qTox_updater``
|
||||
* Development commits: ``https://github.mit.edu/sean-2/updater``
|
||||
|
||||
Compiling:
|
||||
|
||||
* ```clang qtox_sudo.m -framework corefoundation -framework security -framework cocoa -Os -o qtox_sudo```
|
||||
* ```go build updater.go```
|
||||
|
||||
(Starting with this commit all commits will be signed with [this key](http://pgp.mit.edu/pks/lookup?op=get&search=0x13D2043169D25DF4).)
|
273
osx/updater/qtox_sudo.m
Normal file
|
@ -0,0 +1,273 @@
|
|||
// Modifications listed here GPLv3: https://gist.githubusercontent.com/stqism/2e82352026915f8f6ab3/raw/fca6f6f16fb8d61a64b6053dacf50c3433c2e0af/gistfile1.txt
|
||||
//
|
||||
// Copyright 2009 Performant Design, LLC. All rights reserved.
|
||||
// Copyright (C) 2014 Tox Foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation, either version 3 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
// more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <Security/Authorization.h>
|
||||
#include <Security/AuthorizationTags.h>
|
||||
|
||||
char *addFileToPath(const char *path, const char *filename) {
|
||||
char *outbuf;
|
||||
char *lc;
|
||||
|
||||
lc = (char *)path + strlen(path) - 1;
|
||||
|
||||
if (lc < path || *lc != '/') {
|
||||
lc = NULL;
|
||||
}
|
||||
|
||||
while (*filename == '/') {
|
||||
filename++;
|
||||
}
|
||||
|
||||
outbuf = malloc(strlen(path) + strlen(filename) + 1 + (lc == NULL ? 1 : 0));
|
||||
|
||||
sprintf(outbuf, "%s%s%s", path, (lc == NULL) ? "/" : "", filename);
|
||||
|
||||
return outbuf;
|
||||
}
|
||||
|
||||
int isExecFile(const char *name) {
|
||||
struct stat s;
|
||||
|
||||
return (!access(name, X_OK) && !stat(name, &s) && S_ISREG(s.st_mode));
|
||||
}
|
||||
|
||||
char *which(const char *filename)
|
||||
{
|
||||
char *path, *p, *n;
|
||||
|
||||
path = getenv("PATH");
|
||||
|
||||
if (!path) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = path = strdup(path);
|
||||
|
||||
while (p) {
|
||||
n = strchr(p, ':');
|
||||
|
||||
if (n) {
|
||||
*n++ = '\0';
|
||||
}
|
||||
|
||||
if (*p != '\0') {
|
||||
p = addFileToPath(p, filename);
|
||||
|
||||
if (isExecFile(p)) {
|
||||
free(path);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
||||
p = n;
|
||||
}
|
||||
|
||||
free(path);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int cocoaSudo(char *executable, char *commandArgs[], char *icon, char *prompt) {
|
||||
int retVal = 1;
|
||||
OSStatus status;
|
||||
AuthorizationRef authRef;
|
||||
|
||||
AuthorizationItem right = {kAuthorizationRightExecute, 0, NULL, 0};
|
||||
AuthorizationRights rightSet = {1, &right};
|
||||
|
||||
AuthorizationEnvironment myAuthorizationEnvironment;
|
||||
AuthorizationItem kAuthEnv[2];
|
||||
myAuthorizationEnvironment.items = kAuthEnv;
|
||||
|
||||
AuthorizationFlags flags = kAuthorizationFlagDefaults;
|
||||
|
||||
|
||||
if (prompt && icon) {
|
||||
kAuthEnv[0].name = kAuthorizationEnvironmentPrompt;
|
||||
kAuthEnv[0].valueLength = strlen(prompt);
|
||||
kAuthEnv[0].value = prompt;
|
||||
kAuthEnv[0].flags = 0;
|
||||
|
||||
kAuthEnv[1].name = kAuthorizationEnvironmentIcon;
|
||||
kAuthEnv[1].valueLength = strlen(icon);
|
||||
kAuthEnv[1].value = icon;
|
||||
kAuthEnv[1].flags = 0;
|
||||
|
||||
myAuthorizationEnvironment.count = 2;
|
||||
}
|
||||
else if (prompt) {
|
||||
kAuthEnv[0].name = kAuthorizationEnvironmentPrompt;
|
||||
kAuthEnv[0].valueLength = strlen(prompt);
|
||||
kAuthEnv[0].value = prompt;
|
||||
kAuthEnv[0].flags = 0;
|
||||
|
||||
myAuthorizationEnvironment.count = 1;
|
||||
}
|
||||
else if (icon) {
|
||||
kAuthEnv[0].name = kAuthorizationEnvironmentIcon;
|
||||
kAuthEnv[0].valueLength = strlen(icon);
|
||||
kAuthEnv[0].value = icon;
|
||||
kAuthEnv[0].flags = 0;
|
||||
|
||||
myAuthorizationEnvironment.count = 1;
|
||||
}
|
||||
else {
|
||||
myAuthorizationEnvironment.count = 0;
|
||||
}
|
||||
|
||||
status = AuthorizationCreate(NULL, &myAuthorizationEnvironment, flags, &authRef);
|
||||
|
||||
if (status != errAuthorizationSuccess) {
|
||||
NSLog(@"Could not create authorization reference object.");
|
||||
status = errAuthorizationBadAddress;
|
||||
}
|
||||
else {
|
||||
flags = kAuthorizationFlagDefaults |
|
||||
kAuthorizationFlagInteractionAllowed |
|
||||
kAuthorizationFlagPreAuthorize |
|
||||
kAuthorizationFlagExtendRights;
|
||||
|
||||
status = AuthorizationCopyRights(authRef, &rightSet, &myAuthorizationEnvironment, flags, NULL);
|
||||
}
|
||||
|
||||
if (status == errAuthorizationSuccess) {
|
||||
FILE *ioPipe;
|
||||
char buffer[1024];
|
||||
int bytesRead;
|
||||
|
||||
flags = kAuthorizationFlagDefaults;
|
||||
status = AuthorizationExecuteWithPrivileges(authRef, executable, flags, commandArgs, &ioPipe);
|
||||
|
||||
/* Just pipe processes' stdout to our stdout for now; hopefully can add stdin pipe later as well */
|
||||
|
||||
for (;;) {
|
||||
bytesRead = fread(buffer, sizeof(char), 1024, ioPipe);
|
||||
|
||||
if (bytesRead < 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
write(STDOUT_FILENO, buffer, bytesRead * sizeof(char));
|
||||
}
|
||||
|
||||
pid_t pid;
|
||||
int pidStatus;
|
||||
|
||||
do {
|
||||
pid = wait(&pidStatus);
|
||||
}
|
||||
while (pid != -1);
|
||||
|
||||
if (status == errAuthorizationSuccess) {
|
||||
retVal = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
AuthorizationFree(authRef, kAuthorizationFlagDestroyRights);
|
||||
authRef = NULL;
|
||||
|
||||
if (status != errAuthorizationCanceled) {
|
||||
// pre-auth failed
|
||||
NSLog(@"Pre-auth failed");
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void usage(char *appNameFull) {
|
||||
char *appName = strrchr(appNameFull, '/');
|
||||
|
||||
if (appName == NULL) {
|
||||
appName = appNameFull;
|
||||
}
|
||||
else {
|
||||
appName++;
|
||||
}
|
||||
|
||||
fprintf(stderr, "usage: %s command\n", appName);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
int retVal = 1;
|
||||
int programArgsStartAt = 1;
|
||||
char *icon = NULL;
|
||||
char *prompt = NULL;
|
||||
|
||||
if (programArgsStartAt >= argc) {
|
||||
usage(argv[0]);
|
||||
}
|
||||
else {
|
||||
char *executable;
|
||||
|
||||
if (strchr(argv[programArgsStartAt], '/')) {
|
||||
executable = isExecFile(argv[programArgsStartAt]) ? strdup(argv[programArgsStartAt]) : NULL;
|
||||
}
|
||||
else {
|
||||
executable = which(argv[programArgsStartAt]);
|
||||
}
|
||||
|
||||
if (executable) {
|
||||
char **commandArgs = malloc((argc - programArgsStartAt) * sizeof(char**));
|
||||
|
||||
memcpy(commandArgs, argv + programArgsStartAt + 1, (argc - programArgsStartAt - 1) * sizeof(char**));
|
||||
|
||||
commandArgs[argc - programArgsStartAt - 1] = NULL;
|
||||
|
||||
retVal = cocoaSudo(executable, commandArgs, icon, prompt);
|
||||
|
||||
free(commandArgs);
|
||||
free(executable);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Unable to find %s\n", argv[programArgsStartAt]);
|
||||
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (prompt) {
|
||||
free(prompt);
|
||||
}
|
||||
|
||||
[pool release];
|
||||
|
||||
return retVal;
|
||||
}
|
133
osx/updater/updater.go
Normal file
|
@ -0,0 +1,133 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"syscall"
|
||||
|
||||
"bitbucket.org/kardianos/osext"
|
||||
)
|
||||
|
||||
var custom_user string
|
||||
|
||||
func fs_type(path string) int {
|
||||
//name := "FileOrDir"
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return -1
|
||||
}
|
||||
defer f.Close()
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return -1
|
||||
}
|
||||
switch mode := fi.Mode(); {
|
||||
case mode.IsDir():
|
||||
return 0
|
||||
case mode.IsRegular():
|
||||
return 1
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
func install(path string, pathlen int) int {
|
||||
files, _ := ioutil.ReadDir(path)
|
||||
|
||||
for _, file := range files {
|
||||
if fs_type(path+file.Name()) == 1 {
|
||||
|
||||
addpath := ""
|
||||
if len(path) != pathlen {
|
||||
addpath = path[pathlen:len(path)]
|
||||
}
|
||||
|
||||
fmt.Print("Installing: ")
|
||||
fmt.Println("/Applications/qtox.app/Contents/" + addpath + file.Name())
|
||||
if _, err := os.Stat("/Applications/qtox.app/Contents/" + file.Name()); os.IsNotExist(err) {
|
||||
newfile := exec.Command("/usr/libexec/authopen", "-c", "-x", "-m", "drwxrwxr-x+", "/Applications/qtox.app/Contents/"+addpath+file.Name())
|
||||
newfile.Run()
|
||||
}
|
||||
|
||||
cat := exec.Command("/bin/cat", path+file.Name())
|
||||
|
||||
auth := exec.Command("/usr/libexec/authopen", "-w", "/Applications/qtox.app/Contents/"+addpath+file.Name())
|
||||
auth.Stdin, _ = cat.StdoutPipe()
|
||||
auth.Stdout = os.Stdout
|
||||
auth.Stderr = os.Stderr
|
||||
_ = auth.Start()
|
||||
_ = cat.Run()
|
||||
_ = auth.Wait()
|
||||
|
||||
} else {
|
||||
install(path+file.Name()+"/", pathlen)
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func main() {
|
||||
syscall.Setuid(0)
|
||||
usr, e := user.Current()
|
||||
if e != nil {
|
||||
log.Fatal(e)
|
||||
}
|
||||
|
||||
CHECK:
|
||||
if usr.Name != "System Administrator" {
|
||||
fmt.Println("Not running as root, relaunching")
|
||||
|
||||
appdir, _ := osext.Executable()
|
||||
appdir_len := len(appdir)
|
||||
sudo_path := appdir[0:(appdir_len-7)] + "qtox_sudo" //qtox_sudo is a fork of cocoasudo with all of its flags and other features stripped out
|
||||
|
||||
if _, err := os.Stat(sudo_path); os.IsNotExist(err) {
|
||||
fmt.Println("Error: No qtox_sudo binary installed, falling back")
|
||||
custom_user = usr.Name
|
||||
usr.Name = "System Administrator"
|
||||
goto CHECK
|
||||
}
|
||||
|
||||
relaunch := exec.Command(sudo_path, appdir, usr.Name)
|
||||
relaunch.Stdout = os.Stdout
|
||||
relaunch.Stderr = os.Stderr
|
||||
relaunch.Run()
|
||||
return
|
||||
|
||||
} else {
|
||||
|
||||
if len(os.Args) > 1 || custom_user != "" {
|
||||
|
||||
if custom_user == "" {
|
||||
custom_user = os.Args[1]
|
||||
}
|
||||
|
||||
update_dir := "/Users/" + custom_user + "/Library/Preferences/tox/update/"
|
||||
if _, err := os.Stat(update_dir); os.IsNotExist(err) {
|
||||
fmt.Println("Error: No update folder, is check for updates enabled?")
|
||||
return
|
||||
}
|
||||
fmt.Println("qTox Updater")
|
||||
|
||||
killqtox := exec.Command("/usr/bin/killall", "qtox")
|
||||
_ = killqtox.Run()
|
||||
|
||||
install(update_dir, len(update_dir))
|
||||
|
||||
os.RemoveAll(update_dir)
|
||||
fmt.Println("Update metadata wiped, launching qTox")
|
||||
launchqtox := exec.Command("/usr/bin/open", "-b", "im.tox.qtox")
|
||||
launchqtox.Run()
|
||||
|
||||
} else {
|
||||
fmt.Println("Error: no user passed")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
30
qtox.pro
|
@ -59,6 +59,12 @@ contains(DISABLE_PLATFORM_EXT, YES) {
|
|||
DEFINES += QTOX_PLATFORM_EXT
|
||||
}
|
||||
|
||||
contains(DISABLE_FILTER_AUDIO, YES) {
|
||||
|
||||
} else {
|
||||
DEFINES += QTOX_FILTER_AUDIO
|
||||
}
|
||||
|
||||
contains(JENKINS,YES) {
|
||||
INCLUDEPATH += ./libs/include/
|
||||
} else {
|
||||
|
@ -71,6 +77,14 @@ win32 {
|
|||
LIBS += -liphlpapi -L$$PWD/libs/lib -lsodium -ltoxav -ltoxcore -ltoxencryptsave -ltoxdns -lvpx -lpthread
|
||||
LIBS += -L$$PWD/libs/lib -lopencv_core248 -lopencv_highgui248 -lopencv_imgproc248 -lOpenAL32 -lopus
|
||||
LIBS += -lopengl32 -lole32 -loleaut32 -luuid -lvfw32 -ljpeg -ltiff -lpng -ljasper -lIlmImf -lHalf -lws2_32 -lz
|
||||
|
||||
contains(DEFINES, QTOX_FILTER_AUDIO) {
|
||||
contains(STATICPKG, YES) {
|
||||
LIBS += -Wl,-Bstatic -lfilteraudio
|
||||
} else {
|
||||
LIBS += -lfilteraudio
|
||||
}
|
||||
}
|
||||
} else {
|
||||
macx {
|
||||
BUNDLEID = im.tox.qtox
|
||||
|
@ -78,6 +92,7 @@ win32 {
|
|||
QMAKE_INFO_PLIST = osx/info.plist
|
||||
LIBS += -L$$PWD/libs/lib/ -ltoxcore -ltoxav -ltoxencryptsave -ltoxdns -lsodium -lvpx -framework OpenAL -lopencv_core -lopencv_highgui
|
||||
contains(DEFINES, QTOX_PLATFORM_EXT) { LIBS += -framework IOKit -framework CoreFoundation }
|
||||
contains(DEFINES, QTOX_FILTER_AUDIO) { LIBS += -lfilteraudio }
|
||||
} else {
|
||||
# If we're building a package, static link libtox[core,av] and libsodium, since they are not provided by any package
|
||||
contains(STATICPKG, YES) {
|
||||
|
@ -94,8 +109,16 @@ win32 {
|
|||
LIBS += -lX11 -lXss
|
||||
}
|
||||
|
||||
contains(DEFINES, QTOX_FILTER_AUDIO) {
|
||||
contains(STATICPKG, YES) {
|
||||
LIBS += -Wl,-Bstatic -lfilteraudio
|
||||
} else {
|
||||
LIBS += -lfilteraudio
|
||||
}
|
||||
}
|
||||
|
||||
contains(JENKINS, YES) {
|
||||
LIBS = ./libs/lib/libtoxav.a ./libs/lib/libvpx.a ./libs/lib/libopus.a ./libs/lib/libtoxdns.a ./libs/lib/libtoxencryptsave.a ./libs/lib/libtoxcore.a ./libs/lib/libsodium.a /usr/lib/libopencv_core.so /usr/lib/libopencv_highgui.so /usr/lib/libopencv_imgproc.so -lopenal -lX11 -lXss -s
|
||||
LIBS = ./libs/lib/libtoxav.a ./libs/lib/libvpx.a ./libs/lib/libopus.a ./libs/lib/libtoxdns.a ./libs/lib/libtoxencryptsave.a ./libs/lib/libtoxcore.a ./libs/lib/libsodium.a ./libs/lib/libfilteraudio.a /usr/lib/libopencv_core.so /usr/lib/libopencv_highgui.so /usr/lib/libopencv_imgproc.so -lopenal -lX11 -lXss -s
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -234,6 +257,11 @@ SOURCES += \
|
|||
src/widget/form/settings/advancedform.cpp \
|
||||
src/audio.cpp
|
||||
|
||||
contains(DEFINES, QTOX_FILTER_AUDIO) {
|
||||
HEADERS += src/audiofilterer.h
|
||||
SOURCES += src/audiofilterer.cpp
|
||||
}
|
||||
|
||||
contains(DEFINES, QTOX_PLATFORM_EXT) {
|
||||
HEADERS += src/platform/timer.h
|
||||
SOURCES += src/platform/timer_osx.cpp \
|
||||
|
|
14
res.qrc
|
@ -37,10 +37,14 @@
|
|||
<file>img/status/dot_online.png</file>
|
||||
<file>img/status/dot_online_2x.png</file>
|
||||
<file>img/status/dot_online_notification.png</file>
|
||||
<file>img/taskbar/taskbar_online_2x.png</file>
|
||||
<file>img/taskbar/taskbar_idle_2x.png</file>
|
||||
<file>img/taskbar/taskbar_busy_2x.png</file>
|
||||
<file>img/taskbar/taskbar_offline_2x.png</file>
|
||||
<file>img/taskbar/dark/taskbar_online_2x.png</file>
|
||||
<file>img/taskbar/dark/taskbar_idle_2x.png</file>
|
||||
<file>img/taskbar/dark/taskbar_busy_2x.png</file>
|
||||
<file>img/taskbar/dark/taskbar_offline_2x.png</file>
|
||||
<file>img/taskbar/light/taskbar_online_2x.png</file>
|
||||
<file>img/taskbar/light/taskbar_idle_2x.png</file>
|
||||
<file>img/taskbar/light/taskbar_busy_2x.png</file>
|
||||
<file>img/taskbar/light/taskbar_offline_2x.png</file>
|
||||
<file>img/transfer.png</file>
|
||||
<file>smileys/cylgom/angel.png</file>
|
||||
<file>smileys/cylgom/angry.png</file>
|
||||
|
@ -120,9 +124,11 @@
|
|||
<file>translations/fi.qm</file>
|
||||
<file>translations/fr.qm</file>
|
||||
<file>translations/it.qm</file>
|
||||
<file>translations/lt.qm</file>
|
||||
<file>translations/mannol.qm</file>
|
||||
<file>translations/pirate.qm</file>
|
||||
<file>translations/pl.qm</file>
|
||||
<file>translations/pt.qm</file>
|
||||
<file>translations/ru.qm</file>
|
||||
<file>translations/sv.qm</file>
|
||||
<file>translations/uk.qm</file>
|
||||
|
|
100
res/settings.ini
|
@ -1,42 +1,86 @@
|
|||
[DHT%20Server]
|
||||
dhtServerList\size=9
|
||||
dhtServerList\size=21
|
||||
dhtServerList\1\name=Nikolai Toryzin
|
||||
dhtServerList\1\userId=951C88B7E75C867418ACDB5D273821372BB5BD652740BCDF623A4FA293E75D2F
|
||||
dhtServerList\1\address=192.254.75.98
|
||||
dhtServerList\1\port=33445
|
||||
dhtServerList\2\name=sonOfRa
|
||||
dhtServerList\2\userId=04119E835DF3E78BACF0F84235B300546AF8B936F035185E2A8E9E0A67C8924F
|
||||
dhtServerList\2\address=144.76.60.215
|
||||
dhtServerList\2\port=33445
|
||||
dhtServerList\3\name=stal
|
||||
dhtServerList\3\userId=A09162D68618E742FFBCA1C2C70385E6679604B2D80EA6E84AD0996A1AC8A074
|
||||
dhtServerList\3\address=23.226.230.47
|
||||
dhtServerList\2\name=Nikolai Toryzin
|
||||
dhtServerList\2\userId=2A4B50D1D525DA2E669592A20C327B5FAD6C7E5962DC69296F9FEC77C4436E4E
|
||||
dhtServerList\2\address=31.7.57.236
|
||||
dhtServerList\2\port=443
|
||||
dhtServerList\3\name=sonOfRa
|
||||
dhtServerList\3\userId=04119E835DF3E78BACF0F84235B300546AF8B936F035185E2A8E9E0A67C8924F
|
||||
dhtServerList\3\address=144.76.60.215
|
||||
dhtServerList\3\port=33445
|
||||
dhtServerList\4\name=aitjcize
|
||||
dhtServerList\4\userId=7F9C31FE850E97CEFD4C4591DF93FC757C7C12549DDD55F8EEAECC34FE76C029
|
||||
dhtServerList\4\address=54.199.139.199
|
||||
dhtServerList\4\name=stal
|
||||
dhtServerList\4\userId=A09162D68618E742FFBCA1C2C70385E6679604B2D80EA6E84AD0996A1AC8A074
|
||||
dhtServerList\4\address=23.226.230.47
|
||||
dhtServerList\4\port=33445
|
||||
dhtServerList\5\name=astonex
|
||||
dhtServerList\5\userId=B98A2CEAA6C6A2FADC2C3632D284318B60FE5375CCB41EFA081AB67F500C1B0B
|
||||
dhtServerList\5\address=37.59.102.176
|
||||
dhtServerList\5\userId=10B20C49ACBD968D7C80F2E8438F92EA51F189F4E70CFBBB2C2C8C799E97F03E
|
||||
dhtServerList\5\address=178.62.125.224
|
||||
dhtServerList\5\port=33445
|
||||
dhtServerList\6\name=nurupo
|
||||
dhtServerList\6\userId=F404ABAA1C99A9D37D61AB54898F56793E1DEF8BD46B1038B9D822E8460FAB67
|
||||
dhtServerList\6\address=192.210.149.121
|
||||
dhtServerList\6\name=mousey
|
||||
dhtServerList\6\userId=5EB67C51D3FF5A9D528D242B669036ED2A30F8A60E674C45E7D43010CB2E1331
|
||||
dhtServerList\6\address=37.187.46.132
|
||||
dhtServerList\6\port=33445
|
||||
dhtServerList\7\name=mousey
|
||||
dhtServerList\7\userId=5EB67C51D3FF5A9D528D242B669036ED2A30F8A60E674C45E7D43010CB2E1331
|
||||
dhtServerList\7\address=37.187.46.132
|
||||
dhtServerList\7\name=SylvieLorxu
|
||||
dhtServerList\7\userId=4B2C19E924972CB9B57732FB172F8A8604DE13EEDA2A6234E348983344B23057
|
||||
dhtServerList\7\address=178.21.112.187
|
||||
dhtServerList\7\port=33445
|
||||
dhtServerList\8\name=Proplex
|
||||
dhtServerList\8\userId=7BE3951B97CA4B9ECDDA768E8C52BA19E9E2690AB584787BF4C90E04DBB75111
|
||||
dhtServerList\8\address=107.161.17.51
|
||||
dhtServerList\8\name=Munrek
|
||||
dhtServerList\8\userId=E398A69646B8CEACA9F0B84F553726C1C49270558C57DF5F3C368F05A7D71354
|
||||
dhtServerList\8\address=195.154.119.113
|
||||
dhtServerList\8\port=33445
|
||||
dhtServerList\9\name=SylvieLorxu
|
||||
dhtServerList\9\userId=4B2C19E924972CB9B57732FB172F8A8604DE13EEDA2A6234E348983344B23057
|
||||
dhtServerList\9\address=178.21.112.187
|
||||
dhtServerList\9\name=nurupo
|
||||
dhtServerList\9\userId=F404ABAA1C99A9D37D61AB54898F56793E1DEF8BD46B1038B9D822E8460FAB67
|
||||
dhtServerList\9\address=192.210.149.121
|
||||
dhtServerList\9\port=33445
|
||||
dhtServerList\10\name=Unknown (uTox)
|
||||
dhtServerList\10\userId=7187969BB10B54C98538BAE94C069CE5C84E650D54F7E596543D8FB1ECF4CF23
|
||||
dhtServerList\10\address=95.85.13.245
|
||||
dhtServerList\10\name=aitjcize
|
||||
dhtServerList\10\userId=7F9C31FE850E97CEFD4C4591DF93FC757C7C12549DDD55F8EEAECC34FE76C029
|
||||
dhtServerList\10\address=54.199.139.199
|
||||
dhtServerList\10\port=33445
|
||||
dhtServerList\11\name=Jfreegman
|
||||
dhtServerList\11\userId=8CD087E31C67568103E8C2A28653337E90E6B8EDA0D765D57C6B5172B4F1F04C
|
||||
dhtServerList\11\address=104.219.184.206
|
||||
dhtServerList\11\port=443
|
||||
dhtServerList\12\name=bunslow
|
||||
dhtServerList\12\userId=93574A3FAB7D612FEA29FD8D67D3DD10DFD07A075A5D62E8AF3DD9F5D0932E11
|
||||
dhtServerList\12\address=76.191.23.96
|
||||
dhtServerList\12\port=33445
|
||||
dhtServerList\13\name=Martin Schröder
|
||||
dhtServerList\13\userId=F5A1A38EFB6BD3C2C8AF8B10D85F0F89E931704D349F1D0720C3C4059AF2440A
|
||||
dhtServerList\13\address=46.38.239.179
|
||||
dhtServerList\13\port=33445
|
||||
dhtServerList\14\name=lkwg82
|
||||
dhtServerList\14\userId=2C308B4518862740AD9A121598BCA7713AFB25858B747313A4D073E2F6AC506C
|
||||
dhtServerList\14\address=144.76.93.230
|
||||
dhtServerList\14\port=33445
|
||||
dhtServerList\15\name=Impyy
|
||||
dhtServerList\15\userId=788236D34978D1D5BD822F0A5BEBD2C53C64CC31CD3149350EE27D4D9A2F9B6B
|
||||
dhtServerList\15\address=178.62.250.138
|
||||
dhtServerList\15\port=33445
|
||||
dhtServerList\16\name=Thierry Thomas
|
||||
dhtServerList\16\userId=7A2306BFBA665E5480AE59B31E116BE9C04DCEFE04D9FE25082316FA34B4DA0C
|
||||
dhtServerList\16\address=78.225.128.39
|
||||
dhtServerList\16\port=33445
|
||||
dhtServerList\17\name=Manolis
|
||||
dhtServerList\17\userId=461FA3776EF0FA655F1A05477DF1B3B614F7D6B124F7DB1DD4FE3C08B03B640F
|
||||
dhtServerList\17\address=130.133.110.14
|
||||
dhtServerList\17\port=33445
|
||||
dhtServerList\18\name=lawk1
|
||||
dhtServerList\18\userId=58D2DE4B169502669941E50780C1630FAA48A0B7026D6F4066C320D47AC6401E
|
||||
dhtServerList\18\address=178.62.150.106
|
||||
dhtServerList\18\port=33445
|
||||
dhtServerList\19\name=noisykeyboard
|
||||
dhtServerList\19\userId=5918AC3C06955962A75AD7DF4F80A5D7C34F7DB9E1498D2E0495DE35B3FE8A57
|
||||
dhtServerList\19\address=104.167.101.29
|
||||
dhtServerList\19\port=33445
|
||||
dhtServerList\20\name=aceawan
|
||||
dhtServerList\20\userId=391C96CB67AE893D4782B8E4495EB9D89CF1031F48460C06075AA8CE76D50A21
|
||||
dhtServerList\20\address=195.154.109.148
|
||||
dhtServerList\20\port=33445
|
||||
dhtServerList\21\name=pastly
|
||||
dhtServerList\21\userId=3E1FFDEB667BFF549F619EC6737834762124F50A89C8D0DBF1DDF64A2DD6CD1B
|
||||
dhtServerList\21\address=192.3.173.88
|
||||
dhtServerList\21\port=33445
|
||||
|
|
136
src/audio.cpp
|
@ -15,22 +15,40 @@
|
|||
*/
|
||||
|
||||
|
||||
// Output some extra debug info
|
||||
#define AUDIO_DEBUG 1
|
||||
|
||||
// Fix a 7 years old openal-soft/alsa bug
|
||||
// http://blog.gmane.org/gmane.comp.lib.openal.devel/month=20080501
|
||||
// If set to 1, the capture will be started as long as the device is open
|
||||
#define FIX_SND_PCM_PREPARE_BUG 0
|
||||
|
||||
#include "audio.h"
|
||||
#include "src/core.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QThread>
|
||||
#include <QMutexLocker>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
std::atomic<int> Audio::userCount{0};
|
||||
Audio* Audio::instance{nullptr};
|
||||
QThread* Audio::audioThread{nullptr};
|
||||
QMutex* Audio::audioInLock{nullptr};
|
||||
QMutex* Audio::audioOutLock{nullptr};
|
||||
ALCdevice* Audio::alInDev{nullptr};
|
||||
ALCdevice* Audio::alOutDev{nullptr};
|
||||
ALCcontext* Audio::alContext{nullptr};
|
||||
ALuint Audio::alMainSource{0};
|
||||
|
||||
void audioDebugLog(QString msg)
|
||||
{
|
||||
#if (AUDIO_DEBUG)
|
||||
qDebug()<<"Audio: "<<msg;
|
||||
#endif
|
||||
}
|
||||
|
||||
Audio& Audio::getInstance()
|
||||
{
|
||||
if (!instance)
|
||||
|
@ -39,6 +57,8 @@ Audio& Audio::getInstance()
|
|||
audioThread = new QThread(instance);
|
||||
audioThread->setObjectName("qTox Audio");
|
||||
audioThread->start();
|
||||
audioInLock = new QMutex(QMutex::Recursive);
|
||||
audioOutLock = new QMutex(QMutex::Recursive);
|
||||
instance->moveToThread(audioThread);
|
||||
}
|
||||
return *instance;
|
||||
|
@ -46,18 +66,46 @@ Audio& Audio::getInstance()
|
|||
|
||||
void Audio::suscribeInput()
|
||||
{
|
||||
if (!alInDev)
|
||||
{
|
||||
qWarning()<<"Audio::suscribeInput: input device is closed";
|
||||
return;
|
||||
}
|
||||
|
||||
audioDebugLog("suscribing");
|
||||
QMutexLocker lock(audioInLock);
|
||||
if (!userCount++ && alInDev)
|
||||
{
|
||||
#if (!FIX_SND_PCM_PREPARE_BUG)
|
||||
audioDebugLog("starting capture");
|
||||
alcCaptureStart(alInDev);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void Audio::unsuscribeInput()
|
||||
{
|
||||
if (!alInDev)
|
||||
{
|
||||
qWarning()<<"Audio::unsuscribeInput: input device is closed";
|
||||
return;
|
||||
}
|
||||
|
||||
audioDebugLog("unsuscribing");
|
||||
QMutexLocker lock(audioInLock);
|
||||
if (!--userCount && alInDev)
|
||||
{
|
||||
#if (!FIX_SND_PCM_PREPARE_BUG)
|
||||
audioDebugLog("stopping capture");
|
||||
alcCaptureStop(alInDev);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void Audio::openInput(const QString& inDevDescr)
|
||||
{
|
||||
audioDebugLog("Trying to open input "+inDevDescr);
|
||||
QMutexLocker lock(audioInLock);
|
||||
auto* tmp = alInDev;
|
||||
alInDev = nullptr;
|
||||
if (tmp)
|
||||
|
@ -80,11 +128,22 @@ void Audio::openInput(const QString& inDevDescr)
|
|||
|
||||
// Restart the capture if necessary
|
||||
if (userCount.load() != 0 && alInDev)
|
||||
{
|
||||
alcCaptureStart(alInDev);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if (FIX_SND_PCM_PREPARE_BUG)
|
||||
alcCaptureStart(alInDev);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Audio::openOutput(const QString& outDevDescr)
|
||||
{
|
||||
audioDebugLog("Trying to open output "+outDevDescr);
|
||||
QMutexLocker lock(audioOutLock);
|
||||
auto* tmp = alOutDev;
|
||||
alOutDev = nullptr;
|
||||
if (outDevDescr.isEmpty())
|
||||
|
@ -97,11 +156,8 @@ void Audio::openOutput(const QString& outDevDescr)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (alContext)
|
||||
{
|
||||
alcMakeContextCurrent(nullptr);
|
||||
if (alContext && alcMakeContextCurrent(nullptr) == ALC_TRUE)
|
||||
alcDestroyContext(alContext);
|
||||
}
|
||||
if (tmp)
|
||||
alcCloseDevice(tmp);
|
||||
alContext=alcCreateContext(alOutDev,nullptr);
|
||||
|
@ -122,26 +178,48 @@ void Audio::openOutput(const QString& outDevDescr)
|
|||
|
||||
void Audio::closeInput()
|
||||
{
|
||||
audioDebugLog("Closing input");
|
||||
QMutexLocker lock(audioInLock);
|
||||
if (alInDev)
|
||||
alcCaptureCloseDevice(alInDev);
|
||||
|
||||
userCount = 0;
|
||||
{
|
||||
if (alcCaptureCloseDevice(alInDev) == ALC_TRUE)
|
||||
{
|
||||
alInDev = nullptr;
|
||||
userCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning() << "Audio: Failed to close input";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Audio::closeOutput()
|
||||
{
|
||||
if (alContext)
|
||||
{
|
||||
alcMakeContextCurrent(nullptr);
|
||||
audioDebugLog("Closing output");
|
||||
QMutexLocker lock(audioOutLock);
|
||||
if (alContext && alcMakeContextCurrent(nullptr) == ALC_TRUE)
|
||||
alcDestroyContext(alContext);
|
||||
}
|
||||
|
||||
if (alOutDev)
|
||||
alcCloseDevice(alOutDev);
|
||||
{
|
||||
if (alcCloseDevice(alOutDev) == ALC_TRUE)
|
||||
{
|
||||
alOutDev = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning() << "Audio: Failed to close output";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Audio::playMono16Sound(const QByteArray& data)
|
||||
{
|
||||
QMutexLocker lock(audioOutLock);
|
||||
if (!alOutDev)
|
||||
return;
|
||||
|
||||
ALuint buffer;
|
||||
alGenBuffers(1, &buffer);
|
||||
alBufferData(buffer, AL_FORMAT_MONO16, data.data(), data.size(), 44100);
|
||||
|
@ -163,6 +241,8 @@ void Audio::playGroupAudio(int group, int peer, const int16_t* data,
|
|||
{
|
||||
assert(QThread::currentThread() == audioThread);
|
||||
|
||||
QMutexLocker lock(audioOutLock);
|
||||
|
||||
ToxGroupCall& call = Core::groupCalls[group];
|
||||
|
||||
if (!call.active || call.muteVol)
|
||||
|
@ -178,20 +258,22 @@ void Audio::playAudioBuffer(ALuint alSource, const int16_t *data, int samples, u
|
|||
{
|
||||
assert(channels == 1 || channels == 2);
|
||||
|
||||
QMutexLocker lock(audioOutLock);
|
||||
|
||||
ALuint bufid;
|
||||
ALint processed = 0, queued = 16;
|
||||
alGetSourcei(alSource, AL_BUFFERS_PROCESSED, &processed);
|
||||
alGetSourcei(alSource, AL_BUFFERS_QUEUED, &queued);
|
||||
alSourcei(alSource, AL_LOOPING, AL_FALSE);
|
||||
|
||||
if(processed)
|
||||
if (processed)
|
||||
{
|
||||
ALuint bufids[processed];
|
||||
alSourceUnqueueBuffers(alSource, processed, bufids);
|
||||
alDeleteBuffers(processed - 1, bufids + 1);
|
||||
bufid = bufids[0];
|
||||
}
|
||||
else if(queued < 16)
|
||||
else if (queued < 16)
|
||||
{
|
||||
alGenBuffers(1, &bufid);
|
||||
}
|
||||
|
@ -207,6 +289,30 @@ void Audio::playAudioBuffer(ALuint alSource, const int16_t *data, int samples, u
|
|||
|
||||
ALint state;
|
||||
alGetSourcei(alSource, AL_SOURCE_STATE, &state);
|
||||
if(state != AL_PLAYING)
|
||||
if (state != AL_PLAYING)
|
||||
alSourcePlay(alSource);
|
||||
}
|
||||
|
||||
bool Audio::isInputReady()
|
||||
{
|
||||
return (alInDev && userCount);
|
||||
}
|
||||
|
||||
bool Audio::isOutputClosed()
|
||||
{
|
||||
return (alOutDev);
|
||||
}
|
||||
|
||||
bool Audio::tryCaptureSamples(uint8_t* buf, int framesize)
|
||||
{
|
||||
QMutexLocker lock(audioInLock);
|
||||
|
||||
ALint samples=0;
|
||||
alcGetIntegerv(Audio::alInDev, ALC_CAPTURE_SAMPLES, sizeof(samples), &samples);
|
||||
if (samples < framesize)
|
||||
return false;
|
||||
|
||||
memset(buf, 0, framesize * 2 * av_DefaultSettings.audio_channels); // Avoid uninitialized values (Valgrind)
|
||||
alcCaptureSamples(Audio::alInDev, buf, framesize);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ class QString;
|
|||
class QByteArray;
|
||||
class QTimer;
|
||||
class QThread;
|
||||
class QMutex;
|
||||
struct Tox;
|
||||
|
||||
class Audio : QObject
|
||||
|
@ -52,7 +53,11 @@ public:
|
|||
static void closeInput(); ///< Close an input device, please don't use unless everyone's unsuscribed
|
||||
static void closeOutput(); ///< Close an output device
|
||||
|
||||
static bool isInputReady(); ///< Returns true if the input device is open and suscribed to
|
||||
static bool isOutputClosed(); ///< Returns true if the output device is open
|
||||
|
||||
static void playMono16Sound(const QByteArray& data); ///< Play a 44100Hz mono 16bit PCM sound
|
||||
static bool tryCaptureSamples(uint8_t* buf, int framesize); ///< Does nothing and return false on failure
|
||||
|
||||
/// May be called from any thread, will always queue a call to playGroupAudio
|
||||
/// The first and last argument are ignored, but allow direct compatibility with toxcore
|
||||
|
@ -66,7 +71,6 @@ public slots:
|
|||
|
||||
public:
|
||||
static QThread* audioThread;
|
||||
static ALCdevice* alOutDev, *alInDev;
|
||||
static ALCcontext* alContext;
|
||||
static ALuint alMainSource;
|
||||
|
||||
|
@ -77,6 +81,8 @@ private:
|
|||
private:
|
||||
static Audio* instance;
|
||||
static std::atomic<int> userCount;
|
||||
static ALCdevice* alOutDev, *alInDev;
|
||||
static QMutex* audioInLock, *audioOutLock;
|
||||
};
|
||||
|
||||
#endif // AUDIO_H
|
||||
|
|
53
src/audiofilterer.cpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
Copyright (C) 2014 by Project Tox <https://tox.im>
|
||||
|
||||
This file is part of qTox, a Qt-based graphical interface for Tox.
|
||||
|
||||
This program is libre software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef QTOX_FILTER_AUDIO
|
||||
|
||||
#include "audiofilterer.h"
|
||||
extern "C"{
|
||||
#include <filter_audio.h>
|
||||
}
|
||||
|
||||
void AudioFilterer::startFilter(unsigned int fs)
|
||||
{
|
||||
closeFilter();
|
||||
filter = new_filter_audio(fs);
|
||||
}
|
||||
|
||||
void AudioFilterer::closeFilter()
|
||||
{
|
||||
if (filter)
|
||||
kill_filter_audio(filter);
|
||||
filter = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void AudioFilterer::filterAudio(int16_t* data, int framesize)
|
||||
{
|
||||
if (!filter)
|
||||
return;
|
||||
|
||||
filter_audio(filter, (int16_t*) data, framesize);
|
||||
}
|
||||
|
||||
|
||||
AudioFilterer::~AudioFilterer()
|
||||
{
|
||||
closeFilter();
|
||||
}
|
||||
|
||||
#endif // QTOX_FILTER_AUDIO
|
41
src/audiofilterer.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
Copyright (C) 2014 by Project Tox <https://tox.im>
|
||||
|
||||
This file is part of qTox, a Qt-based graphical interface for Tox.
|
||||
|
||||
This program is libre software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#ifdef QTOX_FILTER_AUDIO
|
||||
#ifndef AUDIOFILTERER_H
|
||||
#define AUDIOFILTERER_H
|
||||
#include <cstdint>
|
||||
|
||||
#ifndef _FILTER_AUDIO
|
||||
typedef struct Filter_Audio Filter_Audio;
|
||||
#endif
|
||||
|
||||
class AudioFilterer
|
||||
{
|
||||
public:
|
||||
explicit AudioFilterer() = default;
|
||||
~AudioFilterer();
|
||||
|
||||
void startFilter(unsigned int fs);
|
||||
void filterAudio(int16_t* data, int framesize);
|
||||
void closeFilter();
|
||||
|
||||
private:
|
||||
struct Filter_Audio* filter{nullptr};
|
||||
};
|
||||
|
||||
#endif // AUDIOFILTERER_H
|
||||
#endif // QTOX_FILTER_AUDIO
|
|
@ -64,6 +64,7 @@ unsigned char AutoUpdater::key[crypto_sign_PUBLICKEYBYTES];
|
|||
const QString AutoUpdater::checkURI = AutoUpdater::updateServer+"/qtox/"+AutoUpdater::platform+"/version";
|
||||
const QString AutoUpdater::flistURI = AutoUpdater::updateServer+"/qtox/"+AutoUpdater::platform+"/flist";
|
||||
const QString AutoUpdater::filesURI = AutoUpdater::updateServer+"/qtox/"+AutoUpdater::platform+"/files/";
|
||||
bool AutoUpdater::abortFlag{false};
|
||||
|
||||
bool AutoUpdater::isUpdateAvailable()
|
||||
{
|
||||
|
@ -251,7 +252,11 @@ AutoUpdater::UpdateFile AutoUpdater::getUpdateFile(UpdateFileMeta fileMeta)
|
|||
QNetworkAccessManager *manager = new QNetworkAccessManager;
|
||||
QNetworkReply* reply = manager->get(QNetworkRequest(QUrl(filesURI+fileMeta.id)));
|
||||
while (!reply->isFinished())
|
||||
{
|
||||
if (abortFlag)
|
||||
return file;
|
||||
qApp->processEvents();
|
||||
}
|
||||
|
||||
if (reply->error() != QNetworkReply::NoError)
|
||||
{
|
||||
|
@ -280,6 +285,9 @@ bool AutoUpdater::downloadUpdate()
|
|||
QList<UpdateFileMeta> newFlist = parseFlist(newFlistData);
|
||||
QList<UpdateFileMeta> diff = genUpdateDiff(newFlist);
|
||||
|
||||
if (abortFlag)
|
||||
return false;
|
||||
|
||||
qDebug() << "AutoUpdater: Need to update "<<diff.size()<<" files";
|
||||
|
||||
// Create an empty directory to download updates into
|
||||
|
@ -308,6 +316,9 @@ bool AutoUpdater::downloadUpdate()
|
|||
// Download and write each new file
|
||||
for (UpdateFileMeta fileMeta : diff)
|
||||
{
|
||||
if (abortFlag)
|
||||
return false;
|
||||
|
||||
qDebug() << "AutoUpdater: Downloading '"+fileMeta.installpath+"' ...";
|
||||
|
||||
// Create subdirs if necessary
|
||||
|
@ -317,6 +328,8 @@ bool AutoUpdater::downloadUpdate()
|
|||
|
||||
// Download
|
||||
UpdateFile file = getUpdateFile(fileMeta);
|
||||
if (abortFlag)
|
||||
return false;
|
||||
if (file.data.isNull())
|
||||
{
|
||||
qWarning() << "AutoUpdater::downloadUpdate: Error downloading a file, aborting...";
|
||||
|
@ -357,7 +370,7 @@ bool AutoUpdater::isLocalUpdateReady()
|
|||
if (!updateDir.exists())
|
||||
return false;
|
||||
|
||||
// Check that we have a flist and that every file on the diff exists
|
||||
// Check that we have a flist and generate a diff
|
||||
QFile updateFlistFile(updateDirStr+"flist");
|
||||
if (!updateFlistFile.open(QIODevice::ReadOnly))
|
||||
return false;
|
||||
|
@ -367,9 +380,23 @@ bool AutoUpdater::isLocalUpdateReady()
|
|||
QList<UpdateFileMeta> updateFlist = parseFlist(updateFlistData);
|
||||
QList<UpdateFileMeta> diff = genUpdateDiff(updateFlist);
|
||||
|
||||
// If the update wasn't downloaded correctly, redownload it
|
||||
// We don't check signatures to not block qTox too long, the updater will do it anyway
|
||||
for (UpdateFileMeta fileMeta : diff)
|
||||
{
|
||||
if (!QFile::exists(updateDirStr+fileMeta.installpath))
|
||||
{
|
||||
QtConcurrent::run(&AutoUpdater::downloadUpdate);
|
||||
return false;
|
||||
}
|
||||
|
||||
QFile f(updateDirStr+fileMeta.installpath);
|
||||
if (f.size() != (int64_t)fileMeta.size)
|
||||
{
|
||||
QtConcurrent::run(&AutoUpdater::downloadUpdate);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -433,3 +460,8 @@ void AutoUpdater::checkUpdatesAsyncInteractiveWorker()
|
|||
downloadUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void AutoUpdater::abortUpdates()
|
||||
{
|
||||
abortFlag = true;
|
||||
}
|
||||
|
|
|
@ -78,15 +78,18 @@ public:
|
|||
/// Will try to download an update, if successful returns true and qTox will apply it after a restart
|
||||
/// Will try to follow qTox's proxy settings, may block and processEvents
|
||||
static bool downloadUpdate();
|
||||
/// Returns true if an update is downloaded and ready to be installed
|
||||
/// If so, call installLocalUpdate. If not, call downloadUpdate.
|
||||
/// This only checks that we downloaded an update and didn't stop in the middle, not that every file is still valid
|
||||
/// Returns true if an update is downloaded and ready to be installed,
|
||||
/// if so, call installLocalUpdate.
|
||||
/// If an update was partially downloaded, the function will resume asynchronously and return false
|
||||
static bool isLocalUpdateReady();
|
||||
/// Launches the qTox updater to try to install the local update and exits immediately
|
||||
/// Will not check that the update actually exists, use isLocalUpdateReady first for that
|
||||
/// The qTox updater will restart us after the update is done
|
||||
/// Note: If we fail to start the qTox updater, we will delete the update and exit
|
||||
[[ noreturn ]] static void installLocalUpdate();
|
||||
/// Aborting will make some functions try to return early
|
||||
/// Call before qTox exits to avoid the updater running in the background
|
||||
static void abortUpdates();
|
||||
|
||||
protected:
|
||||
/// Parses and validates a flist file. Returns an empty list on error
|
||||
|
@ -118,6 +121,7 @@ private:
|
|||
static const QString filesURI; ///< URI of the actual files of the latest version
|
||||
static const QString updaterBin; ///< Path to the qtox-updater binary
|
||||
static unsigned char key[];
|
||||
static bool abortFlag; ///< If true, try to abort everything.
|
||||
};
|
||||
|
||||
#endif // AUTOUPDATE_H
|
||||
|
|
38
src/core.cpp
|
@ -49,6 +49,8 @@ QList<ToxFile> Core::fileRecvQueue;
|
|||
QHash<int, ToxGroupCall> Core::groupCalls;
|
||||
QThread* Core::coreThread{nullptr};
|
||||
|
||||
#define MAX_GROUP_MESSAGE_LEN 1024
|
||||
|
||||
Core::Core(Camera* cam, QThread *CoreThread, QString loadPath) :
|
||||
tox(nullptr), camera(cam), loadPath(loadPath), ready{false}
|
||||
{
|
||||
|
@ -121,7 +123,7 @@ void Core::make_tox()
|
|||
// IPv6 needed for LAN discovery, but can crash some weird routers. On by default, can be disabled in options.
|
||||
bool enableIPv6 = Settings::getInstance().getEnableIPv6();
|
||||
bool forceTCP = Settings::getInstance().getForceTCP();
|
||||
bool useProxy = Settings::getInstance().getUseProxy();
|
||||
ProxyType proxyType = Settings::getInstance().getProxyType();
|
||||
|
||||
if (enableIPv6)
|
||||
qDebug() << "Core starting with IPv6 enabled";
|
||||
|
@ -133,11 +135,11 @@ void Core::make_tox()
|
|||
toxOptions.udp_disabled = forceTCP;
|
||||
|
||||
// No proxy by default
|
||||
toxOptions.proxy_enabled = false;
|
||||
toxOptions.proxy_type = TOX_PROXY_NONE;
|
||||
toxOptions.proxy_address[0] = 0;
|
||||
toxOptions.proxy_port = 0;
|
||||
|
||||
if (useProxy)
|
||||
if (proxyType != ProxyType::ptNone)
|
||||
{
|
||||
QString proxyAddr = Settings::getInstance().getProxyAddr();
|
||||
int proxyPort = Settings::getInstance().getProxyPort();
|
||||
|
@ -149,7 +151,11 @@ void Core::make_tox()
|
|||
else if (proxyAddr != "" && proxyPort > 0)
|
||||
{
|
||||
qDebug() << "Core: using proxy" << proxyAddr << ":" << proxyPort;
|
||||
toxOptions.proxy_enabled = true;
|
||||
// protection against changings in TOX_PROXY_TYPE enum
|
||||
if (proxyType == ProxyType::ptSOCKS5)
|
||||
toxOptions.proxy_type = TOX_PROXY_SOCKS5;
|
||||
else if (proxyType == ProxyType::ptHTTP)
|
||||
toxOptions.proxy_type = TOX_PROXY_HTTP;
|
||||
uint16_t sz = CString::fromString(proxyAddr, (unsigned char*)toxOptions.proxy_address);
|
||||
toxOptions.proxy_address[sz] = 0;
|
||||
toxOptions.proxy_port = proxyPort;
|
||||
|
@ -165,7 +171,7 @@ void Core::make_tox()
|
|||
tox = tox_new(&toxOptions);
|
||||
if (tox == nullptr)
|
||||
{
|
||||
if (toxOptions.proxy_enabled)
|
||||
if (toxOptions.proxy_type != TOX_PROXY_NONE)
|
||||
{
|
||||
//QMessageBox::critical(Widget::getInstance(), tr("Proxy failure", "popup title"),
|
||||
//tr("toxcore failed to start with your proxy settings. qTox cannot run; please modify your "
|
||||
|
@ -183,7 +189,7 @@ void Core::make_tox()
|
|||
else
|
||||
qWarning() << "Core failed to start with IPv6, falling back to IPv4. LAN discovery may not work properly.";
|
||||
}
|
||||
else if (toxOptions.proxy_enabled)
|
||||
else if (toxOptions.proxy_type != TOX_PROXY_NONE)
|
||||
{
|
||||
emit badProxy();
|
||||
return;
|
||||
|
@ -728,7 +734,7 @@ void Core::requestFriendship(const QString& friendAddress, const QString& messag
|
|||
{
|
||||
const QString userId = friendAddress.mid(0, TOX_CLIENT_ID_SIZE * 2);
|
||||
|
||||
if(hasFriendWithAddress(friendAddress))
|
||||
if (hasFriendWithAddress(friendAddress))
|
||||
{
|
||||
emit failedToAddFriend(userId, QString(tr("Friend is already added")));
|
||||
}
|
||||
|
@ -779,7 +785,7 @@ void Core::sendTyping(int friendId, bool typing)
|
|||
|
||||
void Core::sendGroupMessage(int groupId, const QString& message)
|
||||
{
|
||||
QList<CString> cMessages = splitMessage(message);
|
||||
QList<CString> cMessages = splitMessage(message, MAX_GROUP_MESSAGE_LEN);
|
||||
|
||||
for (auto &cMsg :cMessages)
|
||||
{
|
||||
|
@ -792,7 +798,7 @@ void Core::sendGroupMessage(int groupId, const QString& message)
|
|||
|
||||
void Core::sendGroupAction(int groupId, const QString& message)
|
||||
{
|
||||
QList<CString> cMessages = splitMessage(message);
|
||||
QList<CString> cMessages = splitMessage(message, MAX_GROUP_MESSAGE_LEN);
|
||||
|
||||
for (auto &cMsg :cMessages)
|
||||
{
|
||||
|
@ -1677,7 +1683,7 @@ void Core::createGroup(uint8_t type)
|
|||
bool Core::hasFriendWithAddress(const QString &addr) const
|
||||
{
|
||||
// Valid length check
|
||||
if(addr.length() != (TOX_FRIEND_ADDRESS_SIZE * 2))
|
||||
if (addr.length() != (TOX_FRIEND_ADDRESS_SIZE * 2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -1689,7 +1695,7 @@ bool Core::hasFriendWithAddress(const QString &addr) const
|
|||
bool Core::hasFriendWithPublicKey(const QString &pubkey) const
|
||||
{
|
||||
// Valid length check
|
||||
if(pubkey.length() != (TOX_CLIENT_ID_SIZE * 2))
|
||||
if (pubkey.length() != (TOX_CLIENT_ID_SIZE * 2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -1706,7 +1712,7 @@ bool Core::hasFriendWithPublicKey(const QString &pubkey) const
|
|||
QString addrOrId = getFriendAddress(ids[i]);
|
||||
|
||||
// Set true if found
|
||||
if(addrOrId.toUpper().startsWith(pubkey.toUpper()))
|
||||
if (addrOrId.toUpper().startsWith(pubkey.toUpper()))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
|
@ -1741,17 +1747,17 @@ QString Core::getFriendUsername(int friendnumber) const
|
|||
return CString::toString(name, tox_get_name_size(tox, friendnumber));
|
||||
}
|
||||
|
||||
QList<CString> Core::splitMessage(const QString &message)
|
||||
QList<CString> Core::splitMessage(const QString &message, int maxLen)
|
||||
{
|
||||
QList<CString> splittedMsgs;
|
||||
QByteArray ba_message(message.toUtf8());
|
||||
|
||||
while (ba_message.size() > TOX_MAX_MESSAGE_LENGTH)
|
||||
while (ba_message.size() > maxLen)
|
||||
{
|
||||
int splitPos = ba_message.lastIndexOf(' ', TOX_MAX_MESSAGE_LENGTH - 1);
|
||||
int splitPos = ba_message.lastIndexOf(' ', maxLen - 1);
|
||||
if (splitPos <= 0)
|
||||
{
|
||||
splitPos = TOX_MAX_MESSAGE_LENGTH;
|
||||
splitPos = maxLen;
|
||||
if (ba_message[splitPos] & 0x80)
|
||||
{
|
||||
do {
|
||||
|
|
|
@ -33,6 +33,9 @@ class QTimer;
|
|||
class QString;
|
||||
class CString;
|
||||
class VideoSource;
|
||||
#ifdef QTOX_FILTER_AUDIO
|
||||
class AudioFilterer;
|
||||
#endif
|
||||
|
||||
class Core : public QObject
|
||||
{
|
||||
|
@ -47,7 +50,7 @@ public:
|
|||
static const QString TOX_EXT;
|
||||
static const QString CONFIG_FILE_NAME;
|
||||
static QString sanitize(QString name);
|
||||
static QList<CString> splitMessage(const QString &message);
|
||||
static QList<CString> splitMessage(const QString &message, int maxLen);
|
||||
|
||||
QString getPeerName(const ToxID& id) const;
|
||||
|
||||
|
@ -283,6 +286,9 @@ private:
|
|||
int dhtServerId;
|
||||
static QList<ToxFile> fileSendQueue, fileRecvQueue;
|
||||
static ToxCall calls[TOXAV_MAX_CALLS];
|
||||
#ifdef QTOX_FILTER_AUDIO
|
||||
static AudioFilterer * filterer[TOXAV_MAX_CALLS];
|
||||
#endif
|
||||
static QHash<int, ToxGroupCall> groupCalls; // Maps group IDs to ToxGroupCalls
|
||||
QMutex fileSendMutex, messageSendMutex;
|
||||
bool ready;
|
||||
|
|
144
src/coreav.cpp
|
@ -17,10 +17,17 @@
|
|||
#include "core.h"
|
||||
#include "video/camera.h"
|
||||
#include "audio.h"
|
||||
#ifdef QTOX_FILTER_AUDIO
|
||||
#include "audiofilterer.h"
|
||||
#endif
|
||||
#include "misc/settings.h"
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
|
||||
ToxCall Core::calls[TOXAV_MAX_CALLS];
|
||||
#ifdef QTOX_FILTER_AUDIO
|
||||
AudioFilterer * Core::filterer[TOXAV_MAX_CALLS] { nullptr};
|
||||
#endif
|
||||
const int Core::videobufsize{TOXAV_MAX_VIDEO_WIDTH * TOXAV_MAX_VIDEO_HEIGHT * 4};
|
||||
uint8_t* Core::videobuf;
|
||||
|
||||
|
@ -65,6 +72,19 @@ void Core::prepareCall(int friendId, int callId, ToxAv* toxav, bool videoEnabled
|
|||
calls[callId].sendVideoTimer->start();
|
||||
Camera::getInstance()->subscribe();
|
||||
}
|
||||
|
||||
#ifdef QTOX_FILTER_AUDIO
|
||||
if (Settings::getInstance().getFilterAudio())
|
||||
{
|
||||
Core::filterer[callId] = new AudioFilterer();
|
||||
filterer[callId]->startFilter(48000);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete filterer[callId];
|
||||
filterer[callId] = nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Core::onAvMediaChange(void* toxav, int32_t callId, void* core)
|
||||
|
@ -194,6 +214,7 @@ void Core::cleanupCall(int callId)
|
|||
if (calls[callId].videoEnabled)
|
||||
Camera::getInstance()->unsubscribe();
|
||||
Audio::unsuscribeInput();
|
||||
toxav_kill_transmission(Core::getInstance()->toxav, callId);
|
||||
}
|
||||
|
||||
void Core::playCallAudio(void* toxav, int32_t callId, const int16_t *data, uint16_t samples, void *user_data)
|
||||
|
@ -207,7 +228,7 @@ void Core::playCallAudio(void* toxav, int32_t callId, const int16_t *data, uint1
|
|||
alGenSources(1, &calls[callId].alSource);
|
||||
|
||||
ToxAvCSettings dest;
|
||||
if(toxav_get_peer_csettings((ToxAv*)toxav, callId, 0, &dest) == 0)
|
||||
if (toxav_get_peer_csettings((ToxAv*)toxav, callId, 0, &dest) == 0)
|
||||
playAudioBuffer(calls[callId].alSource, data, samples, dest.audio_channels, dest.audio_sample_rate);
|
||||
}
|
||||
|
||||
|
@ -216,7 +237,7 @@ void Core::sendCallAudio(int callId, ToxAv* toxav)
|
|||
if (!calls[callId].active)
|
||||
return;
|
||||
|
||||
if (calls[callId].muteMic || !Audio::alInDev)
|
||||
if (calls[callId].muteMic || !Audio::isInputReady())
|
||||
{
|
||||
calls[callId].sendAudioTimer->start();
|
||||
return;
|
||||
|
@ -226,28 +247,25 @@ void Core::sendCallAudio(int callId, ToxAv* toxav)
|
|||
const int bufsize = framesize * 2 * av_DefaultSettings.audio_channels;
|
||||
uint8_t buf[bufsize], dest[bufsize];
|
||||
|
||||
bool frame = false;
|
||||
ALint samples;
|
||||
alcGetIntegerv(Audio::alInDev, ALC_CAPTURE_SAMPLES, sizeof(samples), &samples);
|
||||
if(samples >= framesize)
|
||||
{
|
||||
memset(buf, 0, bufsize); // Avoid uninitialized values (Valgrind)
|
||||
alcCaptureSamples(Audio::alInDev, buf, framesize);
|
||||
frame = 1;
|
||||
}
|
||||
|
||||
if(frame)
|
||||
if (Audio::tryCaptureSamples(buf, framesize))
|
||||
{
|
||||
int r;
|
||||
if((r = toxav_prepare_audio_frame(toxav, callId, dest, framesize*2, (int16_t*)buf, framesize)) < 0)
|
||||
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)
|
||||
#ifdef QTOX_FILTER_AUDIO
|
||||
if (filterer[callId])
|
||||
filterer[callId]->filterAudio((int16_t*) buf, framesize);
|
||||
#endif
|
||||
|
||||
if ((r = toxav_send_audio(toxav, callId, dest, r)) < 0)
|
||||
{
|
||||
qDebug() << "Core: toxav_send_audio error";
|
||||
}
|
||||
}
|
||||
calls[callId].sendAudioTimer->start();
|
||||
}
|
||||
|
@ -271,7 +289,7 @@ void Core::sendCallVideo(int callId)
|
|||
if (frame.w && frame.h)
|
||||
{
|
||||
int result;
|
||||
if((result = toxav_prepare_video_frame(toxav, callId, videobuf, videobufsize, &frame)) < 0)
|
||||
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);
|
||||
|
@ -279,7 +297,7 @@ void Core::sendCallVideo(int callId)
|
|||
return;
|
||||
}
|
||||
|
||||
if((result = toxav_send_video(toxav, callId, (uint8_t*)videobuf, result)) < 0)
|
||||
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);
|
||||
|
@ -294,14 +312,16 @@ void Core::sendCallVideo(int callId)
|
|||
|
||||
void Core::micMuteToggle(int callId)
|
||||
{
|
||||
if (calls[callId].active) {
|
||||
if (calls[callId].active)
|
||||
{
|
||||
calls[callId].muteMic = !calls[callId].muteMic;
|
||||
}
|
||||
}
|
||||
|
||||
void Core::volMuteToggle(int callId)
|
||||
{
|
||||
if (calls[callId].active) {
|
||||
if (calls[callId].active)
|
||||
{
|
||||
calls[callId].muteVol = !calls[callId].muteVol;
|
||||
alSourcef(calls[callId].alSource, AL_GAIN, calls[callId].muteVol ? 0.f : 1.f);
|
||||
}
|
||||
|
@ -321,6 +341,15 @@ void Core::onAvCancel(void* _toxav, int32_t callId, void* core)
|
|||
|
||||
calls[callId].active = false;
|
||||
|
||||
#ifdef QTOX_FILTER_AUDIO
|
||||
if (filterer[callId])
|
||||
{
|
||||
filterer[callId]->closeFilter();
|
||||
delete filterer[callId];
|
||||
filterer[callId] = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
emit static_cast<Core*>(core)->avCancel(friendId, callId);
|
||||
}
|
||||
|
||||
|
@ -379,59 +408,6 @@ void Core::onAvRinging(void* _toxav, int32_t call_index, void* core)
|
|||
}
|
||||
}
|
||||
|
||||
//void Core::onAvStarting(void* _toxav, int32_t call_index, void* core)
|
||||
//{
|
||||
// ToxAv* toxav = static_cast<ToxAv*>(_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*>(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*>(core)->avStarting(friendId, call_index, false);
|
||||
// }
|
||||
|
||||
// delete transSettings;
|
||||
//}
|
||||
|
||||
//void Core::onAvEnding(void* _toxav, int32_t call_index, void* core)
|
||||
//{
|
||||
// ToxAv* toxav = static_cast<ToxAv*>(_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*>(core)->avEnding(friendId, call_index);
|
||||
//}
|
||||
|
||||
void Core::onAvRequestTimeout(void* _toxav, int32_t call_index, void* core)
|
||||
{
|
||||
ToxAv* toxav = static_cast<ToxAv*>(_toxav);
|
||||
|
@ -540,7 +516,7 @@ void Core::onAvStart(void* _toxav, int32_t call_index, void* core)
|
|||
// This function's logic was shamelessly stolen from uTox
|
||||
void Core::playAudioBuffer(ALuint alSource, const int16_t *data, int samples, unsigned channels, int sampleRate)
|
||||
{
|
||||
if(!channels || channels > 2)
|
||||
if (!channels || channels > 2)
|
||||
{
|
||||
qWarning() << "Core::playAudioBuffer: trying to play on "<<channels<<" channels! Giving up.";
|
||||
return;
|
||||
|
@ -552,14 +528,14 @@ void Core::playAudioBuffer(ALuint alSource, const int16_t *data, int samples, un
|
|||
alGetSourcei(alSource, AL_BUFFERS_QUEUED, &queued);
|
||||
alSourcei(alSource, AL_LOOPING, AL_FALSE);
|
||||
|
||||
if(processed)
|
||||
if (processed)
|
||||
{
|
||||
ALuint bufids[processed];
|
||||
alSourceUnqueueBuffers(alSource, processed, bufids);
|
||||
alDeleteBuffers(processed - 1, bufids + 1);
|
||||
bufid = bufids[0];
|
||||
}
|
||||
else if(queued < 32)
|
||||
else if (queued < 32)
|
||||
{
|
||||
alGenBuffers(1, &bufid);
|
||||
}
|
||||
|
@ -575,7 +551,7 @@ void Core::playAudioBuffer(ALuint alSource, const int16_t *data, int samples, un
|
|||
|
||||
ALint state;
|
||||
alGetSourcei(alSource, AL_SOURCE_STATE, &state);
|
||||
if(state != AL_PLAYING)
|
||||
if (state != AL_PLAYING)
|
||||
{
|
||||
alSourcePlay(alSource);
|
||||
//qDebug() << "Core: Starting audio source " << (int)alSource;
|
||||
|
@ -630,7 +606,7 @@ void Core::sendGroupCallAudio(int groupId, ToxAv* toxav)
|
|||
if (!groupCalls[groupId].active)
|
||||
return;
|
||||
|
||||
if (groupCalls[groupId].muteMic || !Audio::alInDev)
|
||||
if (groupCalls[groupId].muteMic || !Audio::isInputReady())
|
||||
{
|
||||
groupCalls[groupId].sendAudioTimer->start();
|
||||
return;
|
||||
|
@ -640,20 +616,10 @@ void Core::sendGroupCallAudio(int groupId, ToxAv* toxav)
|
|||
const int bufsize = framesize * 2 * av_DefaultSettings.audio_channels;
|
||||
uint8_t buf[bufsize];
|
||||
|
||||
bool frame = false;
|
||||
ALint samples;
|
||||
alcGetIntegerv(Audio::alInDev, ALC_CAPTURE_SAMPLES, sizeof(samples), &samples);
|
||||
if(samples >= framesize)
|
||||
{
|
||||
memset(buf, 0, bufsize); // Avoid uninitialized values (Valgrind)
|
||||
alcCaptureSamples(Audio::alInDev, buf, framesize);
|
||||
frame = 1;
|
||||
}
|
||||
|
||||
if(frame)
|
||||
if (Audio::tryCaptureSamples(buf, framesize))
|
||||
{
|
||||
int r;
|
||||
if((r = toxav_group_send_audio(toxav_get_tox(toxav), groupId, (int16_t*)buf,
|
||||
if ((r = toxav_group_send_audio(toxav_get_tox(toxav), groupId, (int16_t*)buf,
|
||||
framesize, av_DefaultSettings.audio_channels, av_DefaultSettings.audio_sample_rate)) < 0)
|
||||
{
|
||||
qDebug() << "Core: toxav_group_send_audio error";
|
||||
|
|
|
@ -145,7 +145,9 @@ GroupWidget *Group::getGroupWidget()
|
|||
|
||||
QStringList Group::getPeerList() const
|
||||
{
|
||||
return peers.values();
|
||||
QStringList peerNames(peers.values());
|
||||
peerNames.sort(Qt::CaseInsensitive);
|
||||
return peerNames;
|
||||
}
|
||||
|
||||
void Group::setEventFlag(int f)
|
||||
|
|
|
@ -70,7 +70,7 @@ int main(int argc, char *argv[])
|
|||
parser.process(a);
|
||||
|
||||
Settings::getInstance(); // Build our Settings singleton as soon as QApplication is ready, not before
|
||||
if(parser.isSet("P"))
|
||||
if (parser.isSet("P"))
|
||||
Settings::getInstance().setCurrentProfile(parser.value("P"));
|
||||
|
||||
sodium_init(); // For the auto-updater
|
||||
|
@ -156,7 +156,7 @@ int main(int argc, char *argv[])
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
else if(!ipc.isCurrentOwner() && !parser.isSet("P"))
|
||||
else if (!ipc.isCurrentOwner() && !parser.isSet("P"))
|
||||
{
|
||||
time_t event = ipc.postEvent("$activate");
|
||||
ipc.waitUntilProcessed(event);
|
||||
|
|
|
@ -1034,7 +1034,7 @@ QSplitter:handle{
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>284</width>
|
||||
<height>401</height>
|
||||
<height>399</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5"/>
|
||||
|
@ -1665,7 +1665,7 @@ QSplitter:handle{
|
|||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>57</height>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
|
@ -1775,7 +1775,7 @@ QSplitter:handle{
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>775</width>
|
||||
<height>19</height>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
|
@ -130,7 +130,7 @@ void Settings::load()
|
|||
autostartInTray = s.value("autostartInTray", false).toBool();
|
||||
closeToTray = s.value("closeToTray", false).toBool();
|
||||
forceTCP = s.value("forceTCP", false).toBool();
|
||||
useProxy = s.value("useProxy", false).toBool();
|
||||
setProxyType(s.value("proxyType", static_cast<int>(ProxyType::ptNone)).toInt());
|
||||
proxyAddr = s.value("proxyAddr", "").toString();
|
||||
proxyPort = s.value("proxyPort", 0).toInt();
|
||||
currentProfile = s.value("currentProfile", "").toString();
|
||||
|
@ -168,6 +168,7 @@ void Settings::load()
|
|||
timestampFormat = s.value("timestampFormat", "hh:mm").toString();
|
||||
minimizeOnClose = s.value("minimizeOnClose", false).toBool();
|
||||
minimizeToTray = s.value("minimizeToTray", false).toBool();
|
||||
lightTrayIcon = s.value("lightTrayIcon", false).toBool();
|
||||
useNativeStyle = s.value("nativeStyle", false).toBool();
|
||||
useEmoticons = s.value("useEmoticons", true).toBool();
|
||||
statusChangeNotificationEnabled = s.value("statusChangeNotificationEnabled", false).toBool();
|
||||
|
@ -189,7 +190,7 @@ void Settings::load()
|
|||
s.endGroup();
|
||||
|
||||
s.beginGroup("Privacy");
|
||||
typingNotification = s.value("typingNotification", false).toBool();
|
||||
typingNotification = s.value("typingNotification", true).toBool();
|
||||
enableLogging = s.value("enableLogging", false).toBool();
|
||||
encryptLogs = s.value("encryptLogs", false).toBool();
|
||||
encryptTox = s.value("encryptTox", false).toBool();
|
||||
|
@ -198,6 +199,7 @@ void Settings::load()
|
|||
s.beginGroup("Audio");
|
||||
inDev = s.value("inDev", "").toString();
|
||||
outDev = s.value("outDev", "").toString();
|
||||
filterAudio = s.value("filterAudio", false).toBool();
|
||||
s.endGroup();
|
||||
|
||||
// Read the embedded DHT bootsrap nodes list if needed
|
||||
|
@ -281,7 +283,7 @@ void Settings::save(QString path, bool writeFriends)
|
|||
s.setValue("showSystemTray", showSystemTray);
|
||||
s.setValue("autostartInTray",autostartInTray);
|
||||
s.setValue("closeToTray", closeToTray);
|
||||
s.setValue("useProxy", useProxy);
|
||||
s.setValue("proxyType", static_cast<int>(proxyType));
|
||||
s.setValue("forceTCP", forceTCP);
|
||||
s.setValue("proxyAddr", proxyAddr);
|
||||
s.setValue("proxyPort", proxyPort);
|
||||
|
@ -317,6 +319,7 @@ void Settings::save(QString path, bool writeFriends)
|
|||
s.setValue("timestampFormat", timestampFormat);
|
||||
s.setValue("minimizeOnClose", minimizeOnClose);
|
||||
s.setValue("minimizeToTray", minimizeToTray);
|
||||
s.setValue("lightTrayIcon", lightTrayIcon);
|
||||
s.setValue("nativeStyle", useNativeStyle);
|
||||
s.setValue("useEmoticons", useEmoticons);
|
||||
s.setValue("themeColor", themeColor);
|
||||
|
@ -340,6 +343,7 @@ void Settings::save(QString path, bool writeFriends)
|
|||
s.beginGroup("Audio");
|
||||
s.setValue("inDev", inDev);
|
||||
s.setValue("outDev", outDev);
|
||||
s.setValue("filterAudio", filterAudio);
|
||||
s.endGroup();
|
||||
|
||||
if (!writeFriends || currentProfile.isEmpty()) // Core::switchConfiguration
|
||||
|
@ -532,6 +536,16 @@ void Settings::setMinimizeToTray(bool newValue)
|
|||
minimizeToTray = newValue;
|
||||
}
|
||||
|
||||
bool Settings::getLightTrayIcon() const
|
||||
{
|
||||
return lightTrayIcon;
|
||||
}
|
||||
|
||||
void Settings::setLightTrayIcon(bool newValue)
|
||||
{
|
||||
lightTrayIcon = newValue;
|
||||
}
|
||||
|
||||
bool Settings::getStatusChangeNotificationEnabled() const
|
||||
{
|
||||
return statusChangeNotificationEnabled;
|
||||
|
@ -572,13 +586,17 @@ void Settings::setForceTCP(bool newValue)
|
|||
forceTCP = newValue;
|
||||
}
|
||||
|
||||
bool Settings::getUseProxy() const
|
||||
ProxyType Settings::getProxyType() const
|
||||
{
|
||||
return useProxy;
|
||||
return proxyType;
|
||||
}
|
||||
void Settings::setUseProxy(bool newValue)
|
||||
|
||||
void Settings::setProxyType(int newValue)
|
||||
{
|
||||
useProxy = newValue;
|
||||
if (newValue >= 0 && newValue <= 2)
|
||||
proxyType = static_cast<ProxyType>(newValue);
|
||||
else
|
||||
proxyType = ProxyType::ptNone;
|
||||
}
|
||||
|
||||
QString Settings::getProxyAddr() const
|
||||
|
@ -888,6 +906,16 @@ void Settings::setOutDev(const QString& deviceSpecifier)
|
|||
outDev = deviceSpecifier;
|
||||
}
|
||||
|
||||
bool Settings::getFilterAudio() const
|
||||
{
|
||||
return filterAudio;
|
||||
}
|
||||
|
||||
void Settings::setFilterAudio(bool newValue)
|
||||
{
|
||||
filterAudio = newValue;
|
||||
}
|
||||
|
||||
QString Settings::getFriendAdress(const QString &publicKey) const
|
||||
{
|
||||
QString key = ToxID::fromString(publicKey).publicKey;
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
struct ToxID;
|
||||
namespace Db { enum class syncType; }
|
||||
|
||||
enum ProxyType {ptNone, ptSOCKS5, ptHTTP};
|
||||
|
||||
class Settings : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -61,6 +63,9 @@ public:
|
|||
|
||||
bool getMinimizeToTray() const;
|
||||
void setMinimizeToTray(bool newValue);
|
||||
|
||||
bool getLightTrayIcon() const;
|
||||
void setLightTrayIcon(bool newValue);
|
||||
|
||||
QString getStyle() const;
|
||||
void setStyle(const QString& newValue);
|
||||
|
@ -86,8 +91,8 @@ public:
|
|||
QString getProxyAddr() const;
|
||||
void setProxyAddr(const QString& newValue);
|
||||
|
||||
bool getUseProxy() const;
|
||||
void setUseProxy(bool newValue);
|
||||
ProxyType getProxyType() const;
|
||||
void setProxyType(int newValue);
|
||||
|
||||
int getProxyPort() const;
|
||||
void setProxyPort(int newValue);
|
||||
|
@ -125,6 +130,9 @@ public:
|
|||
QString getOutDev() const;
|
||||
void setOutDev(const QString& deviceSpecifier);
|
||||
|
||||
bool getFilterAudio() const;
|
||||
void setFilterAudio(bool newValue);
|
||||
|
||||
// Assume all widgets have unique names
|
||||
// Don't use it to save every single thing you want to save, use it
|
||||
// for some general purpose widgets, such as MainWindows or Splitters,
|
||||
|
@ -248,13 +256,14 @@ private:
|
|||
bool autostartInTray;
|
||||
bool closeToTray;
|
||||
bool minimizeToTray;
|
||||
bool lightTrayIcon;
|
||||
bool useEmoticons;
|
||||
bool checkUpdates;
|
||||
bool showInFront;
|
||||
|
||||
bool forceTCP;
|
||||
|
||||
bool useProxy;
|
||||
ProxyType proxyType;
|
||||
QString proxyAddr;
|
||||
int proxyPort;
|
||||
|
||||
|
@ -298,6 +307,7 @@ private:
|
|||
// Audio
|
||||
QString inDev;
|
||||
QString outDev;
|
||||
bool filterAudio;
|
||||
|
||||
struct friendProp
|
||||
{
|
||||
|
|
|
@ -69,9 +69,9 @@ QList<QPair<QString, QString> > SmileyPack::listSmileyPacks(const QStringList &p
|
|||
|
||||
if (relPath.leftRef(2) == "..")
|
||||
{
|
||||
if(!smileyPacks.contains(QPair<QString, QString>(packageName, absPath)))
|
||||
if (!smileyPacks.contains(QPair<QString, QString>(packageName, absPath)))
|
||||
smileyPacks << QPair<QString, QString>(packageName, absPath);
|
||||
else if(!smileyPacks.contains(QPair<QString, QString>(packageName, relPath)))
|
||||
else if (!smileyPacks.contains(QPair<QString, QString>(packageName, relPath)))
|
||||
smileyPacks << QPair<QString, QString>(packageName, relPath); // use relative path for subdirectories
|
||||
}
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ bool SmileyPack::load(const QString& filename)
|
|||
|
||||
// open emoticons.xml
|
||||
QFile xmlFile(filename);
|
||||
if(!xmlFile.open(QIODevice::ReadOnly))
|
||||
if (!xmlFile.open(QIODevice::ReadOnly))
|
||||
return false; // cannot open file
|
||||
|
||||
/* parse the cfg file
|
||||
|
@ -138,14 +138,14 @@ bool SmileyPack::load(const QString& filename)
|
|||
QPixmap pm;
|
||||
pm.loadFromData(getCachedSmiley(emoticon), "PNG");
|
||||
|
||||
if(pm.size().width() > 0)
|
||||
if (pm.size().width() > 0)
|
||||
emoticonSet.push_back(emoticon);
|
||||
|
||||
stringElement = stringElement.nextSibling().toElement();
|
||||
|
||||
}
|
||||
|
||||
if(emoticonSet.size() > 0)
|
||||
if (emoticonSet.size() > 0)
|
||||
emoticons.push_back(emoticonSet);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ uint32_t Platform::getIdleTime()
|
|||
{
|
||||
LASTINPUTINFO info = { 0 };
|
||||
info.cbSize = sizeof(info);
|
||||
if(GetLastInputInfo(&info))
|
||||
if (GetLastInputInfo(&info))
|
||||
return GetTickCount() - info.dwTime;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ uint32_t Platform::getIdleTime()
|
|||
uint32_t idleTime = 0;
|
||||
|
||||
Display *display = XOpenDisplay(NULL);
|
||||
if(!display)
|
||||
if (!display)
|
||||
{
|
||||
qDebug() << "XOpenDisplay(NULL) failed";
|
||||
return 0;
|
||||
|
@ -33,10 +33,10 @@ uint32_t Platform::getIdleTime()
|
|||
|
||||
int32_t x11event = 0, x11error = 0;
|
||||
static int32_t hasExtension = XScreenSaverQueryExtension(display, &x11event, &x11error);
|
||||
if(hasExtension)
|
||||
if (hasExtension)
|
||||
{
|
||||
XScreenSaverInfo *info = XScreenSaverAllocInfo();
|
||||
if(info)
|
||||
if (info)
|
||||
{
|
||||
XScreenSaverQueryInfo(display, DefaultRootWindow(display), info);
|
||||
idleTime = info->idle;
|
||||
|
|
|
@ -219,6 +219,11 @@ fallbackOnTox1:
|
|||
tox_dns3_kill(tox_dns3);
|
||||
#if TOX1_SILENT_FALLBACK
|
||||
toxIdStr = queryTox1(record, silent);
|
||||
#elif TOX1_ASK_FALLBACK
|
||||
QMessageBox::StandardButton btn = QMessageBox::warning(nullptr, "qTox", tr("It appears that qTox has to use the old tox1 protocol.\n\
|
||||
Unfortunately tox1 is not secure. Should it be used anyway?"), QMessageBox::Ok|QMessageBox::No, QMessageBox::No);
|
||||
if (btn == QMessageBox::Ok)
|
||||
queryTox1(record, silent);
|
||||
#endif
|
||||
return toxIdStr;
|
||||
}
|
||||
|
@ -258,6 +263,11 @@ ToxID ToxDNS::resolveToxAddress(const QString &address, bool silent)
|
|||
{
|
||||
#if TOX1_SILENT_FALLBACK
|
||||
toxId = ToxID::fromString(queryTox1(address, silent));
|
||||
#elif TOX1_ASK_FALLBACK
|
||||
QMessageBox::StandardButton btn = QMessageBox::warning(nullptr, "qTox", tr("It appears that qTox has to use the old tox1 protocol.\n\
|
||||
Unfortunately tox1 is not secure. Should it be used anyway?"), QMessageBox::Ok|QMessageBox::No, QMessageBox::No);
|
||||
if (btn == QMessageBox::Ok)
|
||||
toxId = ToxID::fromString(queryTox1(address, silent));
|
||||
#else
|
||||
return toxId;
|
||||
#endif
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
/// Tox1 is not encrypted, it's unsafe
|
||||
#define TOX1_SILENT_FALLBACK 0
|
||||
|
||||
/// That said if the user insists ...
|
||||
#define TOX1_ASK_FALLBACK 1
|
||||
|
||||
/// Handles tox1 and tox3 DNS queries
|
||||
class ToxDNS : public QObject
|
||||
{
|
||||
|
|
|
@ -129,7 +129,7 @@ void CameraWorker::applyProps()
|
|||
if (!cam.isOpened())
|
||||
return;
|
||||
|
||||
for(int prop : props.keys())
|
||||
for (int prop : props.keys())
|
||||
cam.set(prop, props.value(prop));
|
||||
}
|
||||
|
||||
|
@ -148,7 +148,7 @@ void CameraWorker::subscribe()
|
|||
|
||||
void CameraWorker::unsubscribe()
|
||||
{
|
||||
if(--refCount <= 0)
|
||||
if (--refCount <= 0)
|
||||
{
|
||||
cam.release();
|
||||
refCount = 0;
|
||||
|
|
|
@ -65,7 +65,7 @@ void ChatAreaWidget::mouseReleaseEvent(QMouseEvent * event)
|
|||
QTextCursor cursor(document());
|
||||
cursor.setPosition(pos);
|
||||
|
||||
if(!cursor.atEnd())
|
||||
if (!cursor.atEnd())
|
||||
{
|
||||
cursor.setPosition(pos+1);
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ void AddFriendForm::onSendTriggered()
|
|||
this->toxId.clear();
|
||||
this->message.clear();
|
||||
} else {
|
||||
if (Settings::getInstance().getUseProxy())
|
||||
if (Settings::getInstance().getProxyType() != ProxyType::ptNone)
|
||||
{
|
||||
QMessageBox::StandardButton btn = QMessageBox::warning(main, "qTox", tr("qTox needs to use the Tox DNS, but can't do it through a proxy.\n\
|
||||
Ignore the proxy and connect to the Internet directly?"), QMessageBox::Ok|QMessageBox::No, QMessageBox::No);
|
||||
|
|
|
@ -54,6 +54,15 @@ ChatForm::ChatForm(Friend* chatFriend)
|
|||
statusMessageLabel->setFont(Style::getFont(Style::Medium));
|
||||
statusMessageLabel->setMinimumHeight(Style::getFont(Style::Medium).pixelSize());
|
||||
|
||||
isTypingLabel = new QLabel();
|
||||
QFont font = isTypingLabel->font();
|
||||
font.setItalic(true);
|
||||
font.setPixelSize(8);
|
||||
isTypingLabel->setFont(font);
|
||||
|
||||
QVBoxLayout* mainLayout = dynamic_cast<QVBoxLayout*>(layout());
|
||||
mainLayout->insertWidget(1, isTypingLabel);
|
||||
|
||||
netcam = new NetCamView();
|
||||
timer = nullptr;
|
||||
|
||||
|
@ -71,6 +80,7 @@ ChatForm::ChatForm(Friend* chatFriend)
|
|||
connect(callButton, &QPushButton::clicked, this, &ChatForm::onCallTriggered);
|
||||
connect(videoButton, &QPushButton::clicked, this, &ChatForm::onVideoCallTriggered);
|
||||
connect(msgEdit, &ChatTextEdit::enterPressed, this, &ChatForm::onSendTriggered);
|
||||
connect(msgEdit, &ChatTextEdit::textChanged, this, &ChatForm::onTextEditChanged);
|
||||
connect(micButton, SIGNAL(clicked()), this, SLOT(onMicMuteToggle()));
|
||||
connect(volButton, SIGNAL(clicked()), this, SLOT(onVolMuteToggle()));
|
||||
connect(chatWidget, &ChatAreaWidget::onFileTranfertInterract, this, &ChatForm::onFileTansBtnClicked);
|
||||
|
@ -103,7 +113,7 @@ void ChatForm::onSendTriggered()
|
|||
if (isAction)
|
||||
msg = msg = msg.right(msg.length() - 4);
|
||||
|
||||
QList<CString> splittedMsg = Core::splitMessage(msg);
|
||||
QList<CString> splittedMsg = Core::splitMessage(msg, TOX_MAX_MESSAGE_LENGTH);
|
||||
QDateTime timestamp = QDateTime::currentDateTime();
|
||||
|
||||
for (CString& c_msg : splittedMsg)
|
||||
|
@ -132,6 +142,21 @@ void ChatForm::onSendTriggered()
|
|||
msgEdit->clear();
|
||||
}
|
||||
|
||||
void ChatForm::onTextEditChanged()
|
||||
{
|
||||
bool isNowTyping;
|
||||
if (!Settings::getInstance().isTypingNotificationEnabled())
|
||||
isNowTyping = false;
|
||||
else
|
||||
isNowTyping = msgEdit->toPlainText().length() > 0;
|
||||
|
||||
if (isTyping != isNowTyping)
|
||||
{
|
||||
isTyping = isNowTyping;
|
||||
Core::getInstance()->sendTyping(f->getFriendID(), isTyping);
|
||||
}
|
||||
}
|
||||
|
||||
void ChatForm::onAttachClicked()
|
||||
{
|
||||
QStringList paths = QFileDialog::getOpenFileNames(0,tr("Send a file"));
|
||||
|
@ -230,10 +255,11 @@ void ChatForm::onFileRecvRequest(ToxFile file)
|
|||
|
||||
void ChatForm::onAvInvite(int FriendId, int CallId, bool video)
|
||||
{
|
||||
qDebug() << "onAvInvite";
|
||||
if (FriendId != f->getFriendID())
|
||||
return;
|
||||
|
||||
qDebug() << "onAvInvite";
|
||||
|
||||
callId = CallId;
|
||||
callButton->disconnect();
|
||||
videoButton->disconnect();
|
||||
|
@ -267,10 +293,11 @@ void ChatForm::onAvInvite(int FriendId, int CallId, bool video)
|
|||
|
||||
void ChatForm::onAvStart(int FriendId, int CallId, bool video)
|
||||
{
|
||||
qDebug() << "onAvStart";
|
||||
if (FriendId != f->getFriendID())
|
||||
return;
|
||||
|
||||
qDebug() << "onAvStart";
|
||||
|
||||
audioInputFlag = true;
|
||||
audioOutputFlag = true;
|
||||
callId = CallId;
|
||||
|
@ -301,11 +328,12 @@ void ChatForm::onAvStart(int FriendId, int CallId, bool video)
|
|||
|
||||
void ChatForm::onAvCancel(int FriendId, int)
|
||||
{
|
||||
qDebug() << "onAvCancel";
|
||||
|
||||
|
||||
if (FriendId != f->getFriendID())
|
||||
return;
|
||||
|
||||
|
||||
qDebug() << "onAvCancel";
|
||||
|
||||
stopCounter();
|
||||
|
||||
audioInputFlag = false;
|
||||
|
@ -330,11 +358,11 @@ void ChatForm::onAvCancel(int FriendId, int)
|
|||
|
||||
void ChatForm::onAvEnd(int FriendId, int)
|
||||
{
|
||||
qDebug() << "onAvEnd";
|
||||
|
||||
if (FriendId != f->getFriendID())
|
||||
return;
|
||||
|
||||
qDebug() << "onAvEnd";
|
||||
|
||||
audioInputFlag = false;
|
||||
audioOutputFlag = false;
|
||||
micButton->setObjectName("green");
|
||||
|
@ -357,10 +385,11 @@ void ChatForm::onAvEnd(int FriendId, int)
|
|||
|
||||
void ChatForm::onAvRinging(int FriendId, int CallId, bool video)
|
||||
{
|
||||
qDebug() << "onAvRinging";
|
||||
if (FriendId != f->getFriendID())
|
||||
return;
|
||||
|
||||
qDebug() << "onAvRinging";
|
||||
|
||||
callId = CallId;
|
||||
callButton->disconnect();
|
||||
videoButton->disconnect();
|
||||
|
@ -386,11 +415,11 @@ void ChatForm::onAvRinging(int FriendId, int CallId, bool video)
|
|||
|
||||
void ChatForm::onAvStarting(int FriendId, int CallId, bool video)
|
||||
{
|
||||
qDebug() << "onAvStarting";
|
||||
|
||||
if (FriendId != f->getFriendID())
|
||||
return;
|
||||
|
||||
qDebug() << "onAvStarting";
|
||||
|
||||
callButton->disconnect();
|
||||
videoButton->disconnect();
|
||||
if (video)
|
||||
|
@ -417,11 +446,11 @@ void ChatForm::onAvStarting(int FriendId, int CallId, bool video)
|
|||
|
||||
void ChatForm::onAvEnding(int FriendId, int)
|
||||
{
|
||||
qDebug() << "onAvEnding";
|
||||
|
||||
if (FriendId != f->getFriendID())
|
||||
return;
|
||||
|
||||
qDebug() << "onAvEnding";
|
||||
|
||||
audioInputFlag = false;
|
||||
audioOutputFlag = false;
|
||||
micButton->setObjectName("green");
|
||||
|
@ -446,11 +475,11 @@ void ChatForm::onAvEnding(int FriendId, int)
|
|||
|
||||
void ChatForm::onAvRequestTimeout(int FriendId, int)
|
||||
{
|
||||
qDebug() << "onAvRequestTimeout";
|
||||
|
||||
if (FriendId != f->getFriendID())
|
||||
return;
|
||||
|
||||
qDebug() << "onAvRequestTimeout";
|
||||
|
||||
audioInputFlag = false;
|
||||
audioOutputFlag = false;
|
||||
micButton->setObjectName("green");
|
||||
|
@ -473,11 +502,11 @@ void ChatForm::onAvRequestTimeout(int FriendId, int)
|
|||
|
||||
void ChatForm::onAvPeerTimeout(int FriendId, int)
|
||||
{
|
||||
qDebug() << "onAvPeerTimeout";
|
||||
|
||||
if (FriendId != f->getFriendID())
|
||||
return;
|
||||
|
||||
qDebug() << "onAvPeerTimeout";
|
||||
|
||||
audioInputFlag = false;
|
||||
audioOutputFlag = false;
|
||||
micButton->setObjectName("green");
|
||||
|
@ -500,11 +529,11 @@ void ChatForm::onAvPeerTimeout(int FriendId, int)
|
|||
|
||||
void ChatForm::onAvRejected(int FriendId, int)
|
||||
{
|
||||
qDebug() << "onAvRejected";
|
||||
|
||||
if (FriendId != f->getFriendID())
|
||||
return;
|
||||
|
||||
qDebug() << "onAvRejected";
|
||||
|
||||
audioInputFlag = false;
|
||||
audioOutputFlag = false;
|
||||
micButton->setObjectName("green");
|
||||
|
@ -529,11 +558,11 @@ void ChatForm::onAvRejected(int FriendId, int)
|
|||
|
||||
void ChatForm::onAvMediaChange(int FriendId, int CallId, bool video)
|
||||
{
|
||||
qDebug() << "onAvMediaChange";
|
||||
|
||||
if (FriendId != f->getFriendID() || CallId != callId)
|
||||
return;
|
||||
|
||||
qDebug() << "onAvMediaChange";
|
||||
|
||||
if (video)
|
||||
{
|
||||
netcam->show(Core::getInstance()->getVideoSourceFromCall(CallId), f->getDisplayedName());
|
||||
|
@ -554,7 +583,7 @@ void ChatForm::onAnswerCallTriggered()
|
|||
}
|
||||
|
||||
void ChatForm::onHangupCallTriggered()
|
||||
{
|
||||
{
|
||||
qDebug() << "onHangupCallTriggered";
|
||||
|
||||
audioInputFlag = false;
|
||||
|
@ -590,11 +619,11 @@ void ChatForm::onVideoCallTriggered()
|
|||
|
||||
void ChatForm::onAvCallFailed(int FriendId)
|
||||
{
|
||||
qDebug() << "onAvCallFailed";
|
||||
|
||||
if (FriendId != f->getFriendID())
|
||||
return;
|
||||
|
||||
qDebug() << "onAvCallFailed";
|
||||
|
||||
audioInputFlag = false;
|
||||
audioOutputFlag = false;
|
||||
callButton->disconnect();
|
||||
|
@ -793,7 +822,7 @@ void ChatForm::onLoadHistory()
|
|||
|
||||
void ChatForm::startCounter()
|
||||
{
|
||||
if(!timer)
|
||||
if (!timer)
|
||||
{
|
||||
timer = new QTimer();
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(updateTime()));
|
||||
|
@ -805,7 +834,7 @@ void ChatForm::startCounter()
|
|||
|
||||
void ChatForm::stopCounter()
|
||||
{
|
||||
if(timer)
|
||||
if (timer)
|
||||
{
|
||||
addSystemInfoMessage(tr("Call with %1 ended. %2").arg(f->getDisplayedName(),
|
||||
secondsToDHMS(timeElapsed.elapsed()/1000)),
|
||||
|
@ -834,10 +863,10 @@ QString ChatForm::secondsToDHMS(quint32 duration)
|
|||
int hours = (int) (duration % 24);
|
||||
int days = (int) (duration / 24);
|
||||
|
||||
if(minutes == 0)
|
||||
if (minutes == 0)
|
||||
return cD + res.sprintf("%02ds", seconds);
|
||||
|
||||
if(hours == 0 && days == 0)
|
||||
if (hours == 0 && days == 0)
|
||||
return cD + res.sprintf("%02dm %02ds", minutes, seconds);
|
||||
|
||||
if (days == 0)
|
||||
|
@ -870,6 +899,14 @@ void ChatForm::dischargeReceipt(int receipt)
|
|||
}
|
||||
}
|
||||
|
||||
void ChatForm::setFriendTyping(bool isTyping)
|
||||
{
|
||||
if (isTyping)
|
||||
isTypingLabel->setText(f->getDisplayedName() + " " + tr("is typing..."));
|
||||
else
|
||||
isTypingLabel->clear();
|
||||
}
|
||||
|
||||
void ChatForm::clearReciepts()
|
||||
{
|
||||
receipts.clear();
|
||||
|
|
|
@ -39,6 +39,7 @@ public:
|
|||
void loadHistory(QDateTime since, bool processUndelivered = false);
|
||||
|
||||
void dischargeReceipt(int receipt);
|
||||
void setFriendTyping(bool isTyping);
|
||||
|
||||
signals:
|
||||
void sendFile(int32_t friendId, QString, QString, long long);
|
||||
|
@ -75,6 +76,7 @@ public slots:
|
|||
|
||||
private slots:
|
||||
void onSendTriggered();
|
||||
void onTextEditChanged();
|
||||
void onAttachClicked();
|
||||
void onCallTriggered();
|
||||
void onVideoCallTriggered();
|
||||
|
@ -100,6 +102,7 @@ private:
|
|||
QLabel *callDuration;
|
||||
QTimer *timer;
|
||||
QElapsedTimer timeElapsed;
|
||||
QLabel *isTypingLabel;
|
||||
|
||||
QHash<uint, FileTransferInstance*> ftransWidgets;
|
||||
void startCounter();
|
||||
|
@ -107,6 +110,7 @@ private:
|
|||
QString secondsToDHMS(quint32 duration);
|
||||
QHash<int, int> receipts;
|
||||
QMap<int, MessageActionPtr> undeliveredMsgs;
|
||||
bool isTyping;
|
||||
};
|
||||
|
||||
#endif // CHATFORM_H
|
||||
|
|
|
@ -52,10 +52,13 @@ GenericChatForm::GenericChatForm(QWidget *parent) :
|
|||
nameLabel->setEditable(true);
|
||||
|
||||
avatar = new MaskablePixmapWidget(this, QSize(40,40), ":/img/avatar_mask.png");
|
||||
QHBoxLayout *headLayout = new QHBoxLayout(), *mainFootLayout = new QHBoxLayout();
|
||||
headTextLayout = new QVBoxLayout();
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout();
|
||||
QVBoxLayout *footButtonsSmall = new QVBoxLayout(), *volMicLayout = new QVBoxLayout();
|
||||
QHBoxLayout *headLayout = new QHBoxLayout(),
|
||||
*mainFootLayout = new QHBoxLayout();
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout(),
|
||||
*footButtonsSmall = new QVBoxLayout(),
|
||||
*volMicLayout = new QVBoxLayout();
|
||||
headTextLayout = new QVBoxLayout();
|
||||
|
||||
chatWidget = new ChatAreaWidget();
|
||||
|
||||
|
@ -76,10 +79,10 @@ GenericChatForm::GenericChatForm(QWidget *parent) :
|
|||
videoButton->setFixedSize(50,40);
|
||||
videoButton->setToolTip(tr("Video call: RED means you're on a call"));
|
||||
volButton = new QPushButton();
|
||||
volButton->setFixedSize(25,20);
|
||||
//volButton->setFixedSize(25,20);
|
||||
volButton->setToolTip(tr("Toggle speakers volume: RED is OFF"));
|
||||
micButton = new QPushButton();
|
||||
micButton->setFixedSize(25,20);
|
||||
// micButton->setFixedSize(25,20);
|
||||
micButton->setToolTip(tr("Toggle microphone: RED is OFF"));
|
||||
|
||||
footButtonsSmall->setSpacing(2);
|
||||
|
@ -119,6 +122,13 @@ GenericChatForm::GenericChatForm(QWidget *parent) :
|
|||
mainFootLayout->addSpacing(5);
|
||||
mainFootLayout->addWidget(sendButton);
|
||||
mainFootLayout->setSpacing(0);
|
||||
|
||||
headTextLayout->addStretch();
|
||||
headTextLayout->addWidget(nameLabel);
|
||||
|
||||
volMicLayout->addWidget(micButton, Qt::AlignTop);
|
||||
volMicLayout->addSpacing(2);
|
||||
volMicLayout->addWidget(volButton, Qt::AlignBottom);
|
||||
|
||||
headWidget->setLayout(headLayout);
|
||||
headLayout->addWidget(avatar);
|
||||
|
@ -130,16 +140,6 @@ GenericChatForm::GenericChatForm(QWidget *parent) :
|
|||
headLayout->addWidget(videoButton);
|
||||
headLayout->setSpacing(0);
|
||||
|
||||
volMicLayout->addStretch();
|
||||
volMicLayout->addSpacing(1);
|
||||
volMicLayout->addWidget(micButton);
|
||||
volMicLayout->addSpacing(2);
|
||||
volMicLayout->addWidget(volButton);
|
||||
volMicLayout->addStretch();
|
||||
|
||||
headTextLayout->addStretch();
|
||||
headTextLayout->addWidget(nameLabel);
|
||||
|
||||
//Fix for incorrect layouts on OS X as per
|
||||
//https://bugreports.qt-project.org/browse/QTBUG-14591
|
||||
sendButton->setAttribute(Qt::WA_LayoutUsesWidgetRect);
|
||||
|
@ -255,7 +255,8 @@ void GenericChatForm::onEmoteButtonClicked()
|
|||
|
||||
void GenericChatForm::onChatWidgetClicked()
|
||||
{
|
||||
msgEdit->setFocus();
|
||||
if (!chatWidget->textCursor().hasSelection())
|
||||
msgEdit->setFocus();
|
||||
}
|
||||
|
||||
void GenericChatForm::onEmoteInsertRequested(QString str)
|
||||
|
|
|
@ -32,5 +32,11 @@ LoadHistoryDialog::~LoadHistoryDialog()
|
|||
QDateTime LoadHistoryDialog::getFromDate()
|
||||
{
|
||||
QDateTime res(ui->fromDate->selectedDate());
|
||||
if (res.date().month() != ui->fromDate->monthShown() || res.date().year() != ui->fromDate->yearShown())
|
||||
{
|
||||
QDate newDate(ui->fromDate->yearShown(), ui->fromDate->monthShown(), 1);
|
||||
res.setDate(newDate);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -33,12 +33,19 @@ AVForm::AVForm() :
|
|||
bodyUI = new Ui::AVSettings;
|
||||
bodyUI->setupUi(this);
|
||||
|
||||
#ifdef QTOX_FILTER_AUDIO
|
||||
bodyUI->filterAudio->setChecked(Settings::getInstance().getFilterAudio());
|
||||
#else
|
||||
bodyUI->filterAudio->setDisabled(true);
|
||||
#endif
|
||||
|
||||
connect(Camera::getInstance(), &Camera::propProbingFinished, this, &AVForm::onPropProbingFinished);
|
||||
connect(Camera::getInstance(), &Camera::resolutionProbingFinished, this, &AVForm::onResProbingFinished);
|
||||
|
||||
auto qcomboboxIndexChanged = (void(QComboBox::*)(const QString&)) &QComboBox::currentIndexChanged;
|
||||
connect(bodyUI->inDevCombobox, qcomboboxIndexChanged, this, &AVForm::onInDevChanged);
|
||||
connect(bodyUI->outDevCombobox, qcomboboxIndexChanged, this, &AVForm::onOutDevChanged);
|
||||
connect(bodyUI->filterAudio, SIGNAL(toggled(bool)), this, SLOT(onFilterAudioToggled(bool)));
|
||||
connect(bodyUI->rescanButton, &QPushButton::clicked, this, [=](){getAudioInDevices(); getAudioOutDevices();});
|
||||
}
|
||||
|
||||
|
@ -189,3 +196,8 @@ void AVForm::onOutDevChanged(const QString& deviceDescriptor)
|
|||
Settings::getInstance().setOutDev(deviceDescriptor);
|
||||
Audio::openOutput(deviceDescriptor);
|
||||
}
|
||||
|
||||
void AVForm::onFilterAudioToggled(bool filterAudio)
|
||||
{
|
||||
Settings::getInstance().setFilterAudio(filterAudio);
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ private slots:
|
|||
// audio
|
||||
void onInDevChanged(const QString& deviceDescriptor);
|
||||
void onOutDevChanged(const QString& deviceDescriptor);
|
||||
void onFilterAudioToggled(bool filterAudio);
|
||||
|
||||
// camera
|
||||
void onPropProbingFinished(Camera::Prop prop, double val);
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>810</width>
|
||||
<height>496</height>
|
||||
<width>808</width>
|
||||
<height>618</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
|
@ -96,6 +96,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QCheckBox" name="filterAudio">
|
||||
<property name="text">
|
||||
<string>Filter audio</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
|
||||
#include "src/autoupdate.h"
|
||||
|
||||
static QStringList locales = {"bg", "de", "en", "es", "fr", "it", "mannol", "pirate", "pl", "ru", "fi", "sv", "uk"};
|
||||
static QStringList langs = {"Български", "Deutsch", "English", "Español", "Français", "Italiano", "mannol", "Pirate", "Polski", "Русский", "Suomi", "Svenska", "Українська"};
|
||||
static QStringList locales = {"bg", "de", "en", "es", "fr", "it", "lt", "mannol", "pirate", "pl", "pt", "ru", "fi", "sv", "uk"};
|
||||
static QStringList langs = {"Български", "Deutsch", "English", "Español", "Français", "Italiano", "Lietuvių", "mannol", "Pirate", "Polski", "Português", "Русский", "Suomi", "Svenska", "Українська"};
|
||||
|
||||
static QStringList timeFormats = {"hh:mm AP", "hh:mm", "hh:mm:ss AP", "hh:mm:ss"};
|
||||
|
||||
|
@ -54,7 +54,7 @@ GeneralForm::GeneralForm(SettingsWidget *myParent) :
|
|||
bodyUI->cbMakeToxPortable->setChecked(Settings::getInstance().getMakeToxPortable());
|
||||
|
||||
bool showSystemTray = Settings::getInstance().getShowSystemTray();
|
||||
|
||||
|
||||
bodyUI->showSystemTray->setChecked(showSystemTray);
|
||||
bodyUI->startInTray->setChecked(Settings::getInstance().getAutostartInTray());
|
||||
bodyUI->startInTray->setEnabled(showSystemTray);
|
||||
|
@ -62,6 +62,8 @@ GeneralForm::GeneralForm(SettingsWidget *myParent) :
|
|||
bodyUI->closeToTray->setEnabled(showSystemTray);
|
||||
bodyUI->minimizeToTray->setChecked(Settings::getInstance().getMinimizeToTray());
|
||||
bodyUI->minimizeToTray->setEnabled(showSystemTray);
|
||||
bodyUI->lightTrayIcon->setChecked(Settings::getInstance().getLightTrayIcon());
|
||||
bodyUI->lightTrayIcon->setEnabled(showSystemTray);
|
||||
bodyUI->statusChanges->setChecked(Settings::getInstance().getStatusChangeNotificationEnabled());
|
||||
bodyUI->useEmoticons->setChecked(Settings::getInstance().getUseEmoticons());
|
||||
bodyUI->autoacceptFiles->setChecked(Settings::getInstance().getAutoSaveEnabled());
|
||||
|
@ -80,7 +82,7 @@ GeneralForm::GeneralForm(SettingsWidget *myParent) :
|
|||
bodyUI->styleBrowser->addItem(tr("None"));
|
||||
bodyUI->styleBrowser->addItems(QStyleFactory::keys());
|
||||
|
||||
if(QStyleFactory::keys().contains(Settings::getInstance().getStyle()))
|
||||
if (QStyleFactory::keys().contains(Settings::getInstance().getStyle()))
|
||||
bodyUI->styleBrowser->setCurrentText(Settings::getInstance().getStyle());
|
||||
else
|
||||
bodyUI->styleBrowser->setCurrentText(tr("None"));
|
||||
|
@ -110,7 +112,7 @@ GeneralForm::GeneralForm(SettingsWidget *myParent) :
|
|||
if (port != -1)
|
||||
bodyUI->proxyPort->setValue(port);
|
||||
|
||||
bodyUI->cbUseProxy->setChecked(Settings::getInstance().getUseProxy());
|
||||
bodyUI->proxyType->setCurrentIndex(static_cast<int>(Settings::getInstance().getProxyType()));
|
||||
onUseProxyUpdated();
|
||||
|
||||
//general
|
||||
|
@ -121,11 +123,12 @@ GeneralForm::GeneralForm(SettingsWidget *myParent) :
|
|||
connect(bodyUI->startInTray, &QCheckBox::stateChanged, this, &GeneralForm::onSetAutostartInTray);
|
||||
connect(bodyUI->closeToTray, &QCheckBox::stateChanged, this, &GeneralForm::onSetCloseToTray);
|
||||
connect(bodyUI->minimizeToTray, &QCheckBox::stateChanged, this, &GeneralForm::onSetMinimizeToTray);
|
||||
connect(bodyUI->lightTrayIcon, &QCheckBox::stateChanged, this, &GeneralForm::onSetLightTrayIcon);
|
||||
connect(bodyUI->statusChanges, &QCheckBox::stateChanged, this, &GeneralForm::onSetStatusChange);
|
||||
connect(bodyUI->autoAwaySpinBox, SIGNAL(editingFinished()), this, SLOT(onAutoAwayChanged()));
|
||||
connect(bodyUI->showInFront, &QCheckBox::stateChanged, this, &GeneralForm::onSetShowInFront);
|
||||
connect(bodyUI->autoacceptFiles, &QCheckBox::stateChanged, this, &GeneralForm::onAutoAcceptFileChange);
|
||||
if(bodyUI->autoacceptFiles->isChecked())
|
||||
if (bodyUI->autoacceptFiles->isChecked())
|
||||
connect(bodyUI->autoSaveFilesDir, SIGNAL(clicked()), this, SLOT(onAutoSaveDirChange()));
|
||||
//theme
|
||||
connect(bodyUI->useEmoticons, &QCheckBox::stateChanged, this, &GeneralForm::onUseEmoticonsChange);
|
||||
|
@ -137,7 +140,7 @@ GeneralForm::GeneralForm(SettingsWidget *myParent) :
|
|||
//connection
|
||||
connect(bodyUI->cbEnableIPv6, &QCheckBox::stateChanged, this, &GeneralForm::onEnableIPv6Updated);
|
||||
connect(bodyUI->cbEnableUDP, &QCheckBox::stateChanged, this, &GeneralForm::onUDPUpdated);
|
||||
connect(bodyUI->cbUseProxy, &QCheckBox::stateChanged, this, &GeneralForm::onUseProxyUpdated);
|
||||
connect(bodyUI->proxyType, SIGNAL(currentIndexChanged(int)), this, SLOT(onUseProxyUpdated()));
|
||||
connect(bodyUI->proxyAddr, &QLineEdit::editingFinished, this, &GeneralForm::onProxyAddrEdited);
|
||||
connect(bodyUI->proxyPort, SIGNAL(valueChanged(int)), this, SLOT(onProxyPortEdited(int)));
|
||||
connect(bodyUI->reconnectButton, &QPushButton::clicked, this, &GeneralForm::onReconnectClicked);
|
||||
|
@ -187,6 +190,12 @@ void GeneralForm::onSetCloseToTray()
|
|||
Settings::getInstance().setCloseToTray(bodyUI->closeToTray->isChecked());
|
||||
}
|
||||
|
||||
void GeneralForm::onSetLightTrayIcon()
|
||||
{
|
||||
Settings::getInstance().setLightTrayIcon(bodyUI->lightTrayIcon->isChecked());
|
||||
Widget::getInstance()->updateTrayIcon();
|
||||
}
|
||||
|
||||
void GeneralForm::onSetMinimizeToTray()
|
||||
{
|
||||
Settings::getInstance().setMinimizeToTray(bodyUI->minimizeToTray->isChecked());
|
||||
|
@ -194,7 +203,7 @@ void GeneralForm::onSetMinimizeToTray()
|
|||
|
||||
void GeneralForm::onStyleSelected(QString style)
|
||||
{
|
||||
if(bodyUI->styleBrowser->currentIndex() == 0)
|
||||
if (bodyUI->styleBrowser->currentIndex() == 0)
|
||||
Settings::getInstance().setStyle("None");
|
||||
else
|
||||
Settings::getInstance().setStyle(style);
|
||||
|
@ -223,7 +232,7 @@ void GeneralForm::onAutoAcceptFileChange()
|
|||
{
|
||||
Settings::getInstance().setAutoSaveEnabled(bodyUI->autoacceptFiles->isChecked());
|
||||
|
||||
if(bodyUI->autoacceptFiles->isChecked() == true)
|
||||
if (bodyUI->autoacceptFiles->isChecked() == true)
|
||||
connect(bodyUI->autoSaveFilesDir, SIGNAL(clicked()), this, SLOT(onAutoSaveDirChange()));
|
||||
else
|
||||
disconnect(bodyUI->autoSaveFilesDir, SIGNAL(clicked()),this, SLOT(onAutoSaveDirChange()));
|
||||
|
@ -233,7 +242,7 @@ void GeneralForm::onAutoSaveDirChange()
|
|||
{
|
||||
QString previousDir = Settings::getInstance().getGlobalAutoAcceptDir();
|
||||
QString directory = QFileDialog::getExistingDirectory(0, tr("Choose an auto accept directory","popup title"));
|
||||
if(directory.isEmpty())
|
||||
if (directory.isEmpty())
|
||||
directory = previousDir;
|
||||
|
||||
Settings::getInstance().setGlobalAutoAcceptDir(directory);
|
||||
|
@ -279,11 +288,11 @@ void GeneralForm::onProxyPortEdited(int port)
|
|||
|
||||
void GeneralForm::onUseProxyUpdated()
|
||||
{
|
||||
bool state = bodyUI->cbUseProxy->isChecked();
|
||||
int proxytype = bodyUI->proxyType->currentIndex();
|
||||
|
||||
bodyUI->proxyAddr->setEnabled(state);
|
||||
bodyUI->proxyPort->setEnabled(state);
|
||||
Settings::getInstance().setUseProxy(state);
|
||||
bodyUI->proxyAddr->setEnabled(proxytype);
|
||||
bodyUI->proxyPort->setEnabled(proxytype);
|
||||
Settings::getInstance().setProxyType(proxytype);
|
||||
}
|
||||
|
||||
void GeneralForm::onReconnectClicked()
|
||||
|
@ -301,7 +310,7 @@ void GeneralForm::reloadSmiles()
|
|||
QStringList smiles;
|
||||
smiles << ":)" << ";)" << ":p" << ":O" << ":["; //just in case...
|
||||
|
||||
for(int i = 0; i < emoticons.size(); i++)
|
||||
for (int i = 0; i < emoticons.size(); i++)
|
||||
smiles.push_front(emoticons.at(i).first());
|
||||
|
||||
int pixSize = 30;
|
||||
|
|
|
@ -37,6 +37,7 @@ private slots:
|
|||
void onSetShowSystemTray();
|
||||
void onSetAutostartInTray();
|
||||
void onSetCloseToTray();
|
||||
void onSetLightTrayIcon();
|
||||
void onSmileyBrowserIndexChanged(int index);
|
||||
void onUDPUpdated();
|
||||
void onProxyAddrEdited();
|
||||
|
|
|
@ -38,12 +38,12 @@
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>509</width>
|
||||
<height>849</height>
|
||||
<y>-173</y>
|
||||
<width>511</width>
|
||||
<height>797</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="0,0,1">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="0,0,0">
|
||||
<property name="spacing">
|
||||
<number>9</number>
|
||||
</property>
|
||||
|
@ -109,7 +109,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<item row="1" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="trayBehavior">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="startInTray">
|
||||
|
@ -152,6 +152,13 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="lightTrayIcon">
|
||||
<property name="text">
|
||||
<string>Light icon</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -216,6 +223,9 @@
|
|||
<property name="toolTip">
|
||||
<string>Set to 0 to disable</string>
|
||||
</property>
|
||||
<property name="showGroupSeparator" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> minutes</string>
|
||||
</property>
|
||||
|
@ -225,9 +235,6 @@
|
|||
<property name="maximum">
|
||||
<number>2147483647</number>
|
||||
</property>
|
||||
<property name="showGroupSeparator" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -294,6 +301,9 @@
|
|||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
|
@ -317,23 +327,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="styleLabel">
|
||||
<property name="text">
|
||||
<string>Style</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="styleBrowser">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0,0">
|
||||
<property name="sizeConstraint">
|
||||
|
@ -391,6 +384,23 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="styleLabel">
|
||||
<property name="text">
|
||||
<string>Style</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="styleBrowser">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="themeColorLabel">
|
||||
<property name="text">
|
||||
|
@ -462,7 +472,7 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignTop">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="connectionGroup">
|
||||
<property name="title">
|
||||
<string>Connection Settings</string>
|
||||
|
@ -492,11 +502,40 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbUseProxy">
|
||||
<property name="text">
|
||||
<string>Use proxy (SOCKS5)</string>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="proxyLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Proxy type</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="proxyType">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>SOCKS5</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>HTTP</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="proxyLayout">
|
||||
|
|
|
@ -43,11 +43,11 @@
|
|||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbTypingNotification">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
<property name="toolTip">
|
||||
<string extracomment="Your friends will be able to see when you are typing."/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Typing Notification</string>
|
||||
<string>Send Typing Notifications</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -52,7 +52,7 @@ void TabCompleter::buildCompletionList()
|
|||
// that section is then used as the completion regex
|
||||
QRegExp regex(QString("^[-_\\[\\]{}|`^.\\\\]*").append(QRegExp::escape(tabAbbrev)), Qt::CaseInsensitive);
|
||||
|
||||
for(auto name : group->getPeerList())
|
||||
for (auto name : group->getPeerList())
|
||||
if (regex.indexIn(name) > -1)
|
||||
completionMap[name.toLower()] = name;
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ FriendListWidget::FriendListWidget(QWidget *parent) :
|
|||
|
||||
for (Status s : {Status::Online, Status::Away, Status::Busy, Status::Offline})
|
||||
{
|
||||
QLayout *l = new QVBoxLayout();
|
||||
QVBoxLayout *l = new QVBoxLayout();
|
||||
l->setSpacing(0);
|
||||
l->setMargin(0);
|
||||
|
||||
|
@ -46,12 +46,12 @@ FriendListWidget::FriendListWidget(QWidget *parent) :
|
|||
mainLayout->addLayout(layouts[static_cast<int>(Status::Offline)], 4, 0);
|
||||
}
|
||||
|
||||
QLayout* FriendListWidget::getGroupLayout()
|
||||
QVBoxLayout* FriendListWidget::getGroupLayout()
|
||||
{
|
||||
return groupLayout;
|
||||
}
|
||||
|
||||
QLayout* FriendListWidget::getFriendLayout(Status s)
|
||||
QVBoxLayout* FriendListWidget::getFriendLayout(Status s)
|
||||
{
|
||||
auto res = layouts.find(static_cast<int>(s));
|
||||
if (res != layouts.end())
|
||||
|
@ -61,8 +61,11 @@ QLayout* FriendListWidget::getFriendLayout(Status s)
|
|||
return layouts[static_cast<int>(Status::Online)];
|
||||
}
|
||||
|
||||
void FriendListWidget::moveWidget(QWidget *w, Status s)
|
||||
void FriendListWidget::moveWidget(QWidget *w, Status s, int hasNewEvents)
|
||||
{
|
||||
mainLayout->removeWidget(w);
|
||||
getFriendLayout(s)->addWidget(w);
|
||||
if (hasNewEvents == 0)
|
||||
getFriendLayout(s)->addWidget(w);
|
||||
else
|
||||
getFriendLayout(s)->insertWidget(0, w);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include <QHash>
|
||||
#include "src/corestructs.h"
|
||||
|
||||
class QLayout;
|
||||
class QVBoxLayout;
|
||||
class QGridLayout;
|
||||
class QPixmap;
|
||||
|
||||
|
@ -31,17 +31,17 @@ class FriendListWidget : public QWidget
|
|||
public:
|
||||
explicit FriendListWidget(QWidget *parent = 0);
|
||||
|
||||
QLayout* getGroupLayout();
|
||||
QLayout* getFriendLayout(Status s);
|
||||
void moveWidget(QWidget *w, Status s);
|
||||
QVBoxLayout* getGroupLayout();
|
||||
QVBoxLayout* getFriendLayout(Status s);
|
||||
void moveWidget(QWidget *w, Status s, int hasNewEvents);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
QHash<int, QLayout*> layouts;
|
||||
QLayout *groupLayout;
|
||||
QHash<int, QVBoxLayout*> layouts;
|
||||
QVBoxLayout *groupLayout;
|
||||
QGridLayout *mainLayout;
|
||||
};
|
||||
|
||||
|
|
|
@ -130,6 +130,6 @@ void MaskablePixmapWidget::paintEvent(QPaintEvent *)
|
|||
|
||||
void MaskablePixmapWidget::mousePressEvent(QMouseEvent*)
|
||||
{
|
||||
if(clickable)
|
||||
if (clickable)
|
||||
emit clicked();
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ MessageAction::MessageAction(const QString &author, const QString &message, cons
|
|||
QString MessageAction::getMessage(QString div)
|
||||
{
|
||||
QString message_;
|
||||
if(Settings::getInstance().getUseEmoticons())
|
||||
if (Settings::getInstance().getUseEmoticons())
|
||||
message_ = SmileyPack::getInstance().smileyfied(toHtmlChars(message));
|
||||
else
|
||||
message_ = toHtmlChars(message);
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
|
||||
void toxActivateEventHandler(const QByteArray& data)
|
||||
{
|
||||
if(data != "$activate")
|
||||
if (data != "$activate")
|
||||
return;
|
||||
Widget::getInstance()->show();
|
||||
Widget::getInstance()->activateWindow();
|
||||
|
@ -96,12 +96,11 @@ void Widget::init()
|
|||
statusAway->setIcon(QIcon(":ui/statusButton/dot_idle.png"));
|
||||
connect(statusAway, SIGNAL(triggered()), this, SLOT(setStatusAway()));
|
||||
statusBusy = new QAction(tr("Busy"), this);
|
||||
connect(statusBusy, SIGNAL(triggered()), this, SLOT(setStatusBusy()));
|
||||
statusBusy->setIcon(QIcon(":ui/statusButton/dot_busy.png"));
|
||||
connect(statusBusy, SIGNAL(triggered()), this, SLOT(setStatusBusy()));
|
||||
actionQuit = new QAction(tr("&Quit"), this);
|
||||
connect(actionQuit, SIGNAL(triggered()), qApp, SLOT(quit()));
|
||||
|
||||
trayMenu->addAction(new QAction(tr("Change status to:"), this));
|
||||
trayMenu->addAction(statusOnline);
|
||||
trayMenu->addAction(statusAway);
|
||||
trayMenu->addAction(statusBusy);
|
||||
|
@ -116,7 +115,7 @@ void Widget::init()
|
|||
|
||||
if (Settings::getInstance().getShowSystemTray()){
|
||||
icon->show();
|
||||
if(Settings::getInstance().getAutostartInTray() == false)
|
||||
if (Settings::getInstance().getAutostartInTray() == false)
|
||||
this->show();
|
||||
}
|
||||
else
|
||||
|
@ -149,7 +148,7 @@ void Widget::init()
|
|||
|
||||
ui->tooliconsZone->setStyleSheet(Style::resolve("QPushButton{background-color:@themeDark;border:none;}QPushButton:hover{background-color:@themeMediumDark;border:none;}"));
|
||||
|
||||
if(QStyleFactory::keys().contains(Settings::getInstance().getStyle())
|
||||
if (QStyleFactory::keys().contains(Settings::getInstance().getStyle())
|
||||
&& Settings::getInstance().getStyle() != "None")
|
||||
{
|
||||
ui->mainHead->setStyle(QStyleFactory::create(Settings::getInstance().getStyle()));
|
||||
|
@ -243,6 +242,7 @@ void Widget::init()
|
|||
connect(core, &Core::avInvite, this, &Widget::playRingtone);
|
||||
connect(core, &Core::blockingClearContacts, this, &Widget::clearContactsList, Qt::BlockingQueuedConnection);
|
||||
connect(core, &Core::blockingGetPassword, this, &Widget::getPassword, Qt::BlockingQueuedConnection);
|
||||
connect(core, &Core::friendTypingChanged, this, &Widget::onFriendTypingChanged);
|
||||
|
||||
connect(core, SIGNAL(messageSentResult(int,QString,int)), this, SLOT(onMessageSendResult(int,QString,int)));
|
||||
connect(core, SIGNAL(groupSentResult(int,QString,int)), this, SLOT(onGroupSendResult(int,QString,int)));
|
||||
|
@ -300,14 +300,15 @@ void Widget::updateTrayIcon()
|
|||
return;
|
||||
QString status = ui->statusButton->property("status").toString();
|
||||
QString pic;
|
||||
QString color = Settings::getInstance().getLightTrayIcon() ? "light" : "dark";
|
||||
if (status == "online")
|
||||
pic = ":img/taskbar/taskbar_online_2x.png";
|
||||
pic = ":img/taskbar/" + color + "/taskbar_online_2x.png";
|
||||
else if (status == "away")
|
||||
pic = ":img/taskbar/taskbar_idle_2x.png";
|
||||
pic = ":img/taskbar/" + color + "/taskbar_idle_2x.png";
|
||||
else if (status == "busy")
|
||||
pic = ":img/taskbar/taskbar_busy_2x.png";
|
||||
pic = ":img/taskbar/" + color + "/taskbar_busy_2x.png";
|
||||
else
|
||||
pic = ":img/taskbar/taskbar_offline_2x.png";
|
||||
pic = ":img/taskbar/" + color + "/taskbar_offline_2x.png";
|
||||
icon->setIcon(QIcon(pic));
|
||||
}
|
||||
|
||||
|
@ -318,6 +319,7 @@ Widget::~Widget()
|
|||
coreThread->wait(500); // In case of deadlock (can happen with QtAudio/PA bugs)
|
||||
if (!coreThread->isFinished())
|
||||
coreThread->terminate();
|
||||
AutoUpdater::abortUpdates();
|
||||
delete core;
|
||||
delete settingsWidget;
|
||||
delete addFriendForm;
|
||||
|
@ -348,7 +350,7 @@ QThread* Widget::getCoreThread()
|
|||
|
||||
void Widget::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
if(Settings::getInstance().getShowSystemTray() && Settings::getInstance().getCloseToTray() == true)
|
||||
if (Settings::getInstance().getShowSystemTray() && Settings::getInstance().getCloseToTray() == true)
|
||||
{
|
||||
event->ignore();
|
||||
this->hide();
|
||||
|
@ -365,7 +367,7 @@ void Widget::changeEvent(QEvent *event)
|
|||
{
|
||||
if (event->type() == QEvent::WindowStateChange)
|
||||
{
|
||||
if(isMinimized() && Settings::getInstance().getMinimizeToTray())
|
||||
if (isMinimized() && Settings::getInstance().getMinimizeToTray())
|
||||
{
|
||||
this->hide();
|
||||
}
|
||||
|
@ -415,7 +417,7 @@ QList<QString> Widget::searchProfiles()
|
|||
QDir dir(Settings::getSettingsDirPath());
|
||||
dir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
|
||||
dir.setNameFilters(QStringList("*.tox"));
|
||||
for(QFileInfo file : dir.entryInfoList())
|
||||
for (QFileInfo file : dir.entryInfoList())
|
||||
out += file.completeBaseName();
|
||||
return out;
|
||||
}
|
||||
|
@ -591,7 +593,7 @@ void Widget::onIconClick(QSystemTrayIcon::ActivationReason reason)
|
|||
{
|
||||
switch (reason) {
|
||||
case QSystemTrayIcon::Trigger:
|
||||
if(this->isHidden() == true)
|
||||
if (this->isHidden() == true)
|
||||
{
|
||||
this->show();
|
||||
this->activateWindow();
|
||||
|
@ -712,7 +714,7 @@ void Widget::addFriend(int friendId, const QString &userId)
|
|||
void Widget::addFriendFailed(const QString&, const QString& errorInfo)
|
||||
{
|
||||
QString info = QString(tr("Couldn't request friendship"));
|
||||
if(!errorInfo.isEmpty()) {
|
||||
if (!errorInfo.isEmpty()) {
|
||||
info = info + (QString(": ") + errorInfo);
|
||||
}
|
||||
|
||||
|
@ -725,7 +727,7 @@ void Widget::onFriendStatusChanged(int friendId, Status status)
|
|||
if (!f)
|
||||
return;
|
||||
|
||||
contactListWidget->moveWidget(f->getFriendWidget(), status);
|
||||
contactListWidget->moveWidget(f->getFriendWidget(), status, f->getEventFlag());
|
||||
|
||||
bool isActualChange = f->getStatus() != status;
|
||||
|
||||
|
@ -733,7 +735,7 @@ void Widget::onFriendStatusChanged(int friendId, Status status)
|
|||
f->getFriendWidget()->updateStatusLight();
|
||||
|
||||
//won't print the message if there were no messages before
|
||||
if(!f->getChatForm()->isEmpty()
|
||||
if (!f->getChatForm()->isEmpty()
|
||||
&& Settings::getInstance().getStatusChangeNotificationEnabled())
|
||||
{
|
||||
QString fStatus = "";
|
||||
|
@ -1178,6 +1180,14 @@ void Widget::getPassword(QString info, int passtype, uint8_t* salt)
|
|||
}
|
||||
}
|
||||
|
||||
void Widget::onFriendTypingChanged(int friendId, bool isTyping)
|
||||
{
|
||||
Friend* f = FriendList::findFriend(friendId);
|
||||
if (!f)
|
||||
return;
|
||||
f->getChatForm()->setFriendTyping(isTyping);
|
||||
}
|
||||
|
||||
void Widget::onSetShowSystemTray(bool newValue){
|
||||
icon->setVisible(newValue);
|
||||
}
|
||||
|
|
|
@ -132,6 +132,7 @@ private slots:
|
|||
void onIconClick(QSystemTrayIcon::ActivationReason);
|
||||
void onUserAwayCheck();
|
||||
void getPassword(QString info, int passtype, uint8_t* salt);
|
||||
void onFriendTypingChanged(int friendId, bool isTyping);
|
||||
void onSetShowSystemTray(bool newValue);
|
||||
void onSplitterMoved(int pos, int index);
|
||||
|
||||
|
|
539
translations/de.ts
vendored
140
translations/fr.ts
vendored
|
@ -76,13 +76,13 @@
|
|||
<message>
|
||||
<location filename="../src/widget/form/addfriendform.cpp" line="34"/>
|
||||
<source>Add Friends</source>
|
||||
<translation>Ajouter des amis</translation>
|
||||
<translation>Ajouter des contacts</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/addfriendform.cpp" line="37"/>
|
||||
<source>Tox ID</source>
|
||||
<comment>Tox ID of the person you're sending a friend request to</comment>
|
||||
<translation>ID Tox</translation>
|
||||
<translation>Tox ID</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/addfriendform.cpp" line="38"/>
|
||||
|
@ -93,25 +93,25 @@
|
|||
<message>
|
||||
<location filename="../src/widget/form/addfriendform.cpp" line="39"/>
|
||||
<source>Send friend request</source>
|
||||
<translation>Envoyer la demande d'ami</translation>
|
||||
<translation>Envoyer la demande de contact</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/addfriendform.cpp" line="40"/>
|
||||
<source>Tox me maybe?</source>
|
||||
<comment>Default message in friend requests if the field is left blank. Write something appropriate!</comment>
|
||||
<translation>Je souhaiterais vous ajouter à mes contacts</translation>
|
||||
<translation>Je souhaiterais vous ajouter à mes contacts.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/addfriendform.cpp" line="89"/>
|
||||
<source>Please fill in a valid Tox ID</source>
|
||||
<comment>Tox ID of the friend you're sending a friend request to</comment>
|
||||
<translation>Merci de remplir un ID Tox valide</translation>
|
||||
<translation>Merci d'entrer un Tox ID valide</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/addfriendform.cpp" line="92"/>
|
||||
<source>You can't add yourself as a friend!</source>
|
||||
<comment>When trying to add your own Tox ID as friend</comment>
|
||||
<translation>Vous ne pouvez pas vous ajouter vous même en temps qu'ami!</translation>
|
||||
<translation>Vous ne pouvez pas vous ajouter vous-même !</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/addfriendform.cpp" line="100"/>
|
||||
|
@ -123,19 +123,19 @@ Ignorer le proxy et se connecter directement à Internet ?</translation>
|
|||
<message>
|
||||
<source>qTox needs to use the Tox DNS, but can't do it through a proxy
|
||||
Ignore the proxy and connect to the Internet directly ?</source>
|
||||
<translation type="vanished">qTox as besoin d'utiliser le DNS Tox, mais ne peut pas le faire avec un proxy
|
||||
<translation type="vanished">qTox a besoin d'utiliser le DNS Tox, mais ne peut pas le faire avec un proxy
|
||||
Ignorer le proxy et se connecter directement à Internet ?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/addfriendform.cpp" line="110"/>
|
||||
<source>This Tox ID does not exist</source>
|
||||
<comment>DNS error</comment>
|
||||
<translation>Cet ID Tox n'existe pas</translation>
|
||||
<translation>Ce Tox ID n'existe pas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>This address does not exist</source>
|
||||
<comment>The DNS gives the Tox ID associated to toxme.se addresses</comment>
|
||||
<translation type="vanished">Cette addresse n'existe pas</translation>
|
||||
<translation type="vanished">Cette adresse n'existe pas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error while looking up DNS</source>
|
||||
|
@ -178,22 +178,22 @@ Ignorer le proxy et se connecter directement à Internet ?</translation>
|
|||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="148"/>
|
||||
<source>Bad Idea</source>
|
||||
<translation>Mauvaise Idée</translation>
|
||||
<translation>Mauvaise idée</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="148"/>
|
||||
<source>You're trying to send a special (sequential) file, that's not going to work!</source>
|
||||
<translation>Vous êtes en train d'essayer d'envoyer un fichier spécial (sequentiel), ça ne marchera pas!</translation>
|
||||
<translation>Vous êtes en train d'essayer d'envoyer un fichier spécial (sequentiel), ça ne fonctionnera pas !</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="254"/>
|
||||
<source>%1 calling</source>
|
||||
<translation>%1 appelle</translation>
|
||||
<translation>%1 appel</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="323"/>
|
||||
<source>%1 stopped calling</source>
|
||||
<translation>%1a arreté l'appel</translation>
|
||||
<translation>%1 a arreté l'appel</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="379"/>
|
||||
|
@ -229,7 +229,7 @@ Ignorer le proxy et se connecter directement à Internet ?</translation>
|
|||
<message>
|
||||
<location filename="../src/core.cpp" line="256"/>
|
||||
<source>Toxing on qTox</source>
|
||||
<translation>Toxer avec qTox</translation>
|
||||
<translation>Je Tox sur qTox</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="257"/>
|
||||
|
@ -239,7 +239,7 @@ Ignorer le proxy et se connecter directement à Internet ?</translation>
|
|||
<message>
|
||||
<location filename="../src/core.cpp" line="746"/>
|
||||
<source>Friend is already added</source>
|
||||
<translation>Cet ami est déjà dans cos contact</translation>
|
||||
<translation>Ce contact est déjà dans vos contacts</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1176"/>
|
||||
|
@ -249,7 +249,7 @@ Ignorer le proxy et se connecter directement à Internet ?</translation>
|
|||
<message>
|
||||
<location filename="../src/core.cpp" line="1176"/>
|
||||
<source>The .tox file is encrypted, but encryption was not checked, continuing regardless.</source>
|
||||
<translation>Le fichier .tox est chiffré, mais l'encryption n'as pas été activée. Le problème sera ignoré.</translation>
|
||||
<translation>Le fichier .tox est chiffré, mais le chiffrement n'a pas été activé. Le problème sera ignoré.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1183"/>
|
||||
|
@ -261,14 +261,14 @@ Ignorer le proxy et se connecter directement à Internet ?</translation>
|
|||
<location filename="../src/core.cpp" line="1197"/>
|
||||
<location filename="../src/core.cpp" line="1261"/>
|
||||
<source>Password error</source>
|
||||
<translation>Mod de passe invalide</translation>
|
||||
<translation>Mot de passe invalide</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1185"/>
|
||||
<location filename="../src/core.cpp" line="1261"/>
|
||||
<source>Failed to setup password.
|
||||
Empty password.</source>
|
||||
<translation>Impossible de mettre ne place le mot de passe.
|
||||
<translation>Impossible de mettre en place le mot de passe.
|
||||
Le mot de passe est vide.</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -289,7 +289,7 @@ Le mot de passe est vide.</translation>
|
|||
<message>
|
||||
<location filename="../src/core.cpp" line="1198"/>
|
||||
<source>Wrong password has been entered</source>
|
||||
<translation>Un mauvais mot de passe à été entré</translation>
|
||||
<translation>Un mauvais mot de passe a été entré</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1259"/>
|
||||
|
@ -316,7 +316,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<message>
|
||||
<location filename="../src/core.cpp" line="1277"/>
|
||||
<source>Due to incorret password logging will be disabled</source>
|
||||
<translation>À cause d'un mauvais mot de passe, l'historique sera désactivé</translation>
|
||||
<translation>Due à l'utilisation d'un mauvais mot de passe, l'historique sera désactivé</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1350"/>
|
||||
|
@ -326,7 +326,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<message>
|
||||
<location filename="../src/core.cpp" line="1350"/>
|
||||
<source>Will be saved without encryption!</source>
|
||||
<translation>L'historique sera sauvegardé sans être chiffré!</translation>
|
||||
<translation>L'historique sera sauvegardé sans être chiffré !</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -380,12 +380,12 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<location filename="../src/widget/tool/friendrequestdialog.cpp" line="30"/>
|
||||
<source>Friend request</source>
|
||||
<comment>Title of the window to aceept/deny a friend request</comment>
|
||||
<translation>Demande d'ami</translation>
|
||||
<translation>Demande de contact</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/tool/friendrequestdialog.cpp" line="32"/>
|
||||
<source>Someone wants to make friends with you</source>
|
||||
<translation>Quelqu'un veut devenir votre ami</translation>
|
||||
<translation>Quelqu'un vient de vous ajouter dans sa liste de contacts</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/tool/friendrequestdialog.cpp" line="33"/>
|
||||
|
@ -395,7 +395,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<message>
|
||||
<location filename="../src/widget/tool/friendrequestdialog.cpp" line="37"/>
|
||||
<source>Friend request message:</source>
|
||||
<translation>Message de demande d'ami:</translation>
|
||||
<translation>Message au sujet de la demande:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/tool/friendrequestdialog.cpp" line="44"/>
|
||||
|
@ -422,7 +422,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<location filename="../src/widget/friendwidget.cpp" line="56"/>
|
||||
<source>Copy friend ID</source>
|
||||
<comment>Menu to copy the Tox ID of that friend</comment>
|
||||
<translation>Copier l'ID ami</translation>
|
||||
<translation>Copier l'ID du contact</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/friendwidget.cpp" line="68"/>
|
||||
|
@ -458,7 +458,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<message>
|
||||
<source>Disable global auto accept</source>
|
||||
<comment>context menu entry</comment>
|
||||
<translation type="vanished">Désactiver l'acceptation automatique de fichier</translation>
|
||||
<translation type="vanished">Désactiver le téléchargement automatique de fichiers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/friendwidget.cpp" line="109"/>
|
||||
|
@ -470,7 +470,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<location filename="../src/widget/friendwidget.cpp" line="76"/>
|
||||
<source>Remove friend</source>
|
||||
<comment>Menu to remove the friend from our friendlist</comment>
|
||||
<translation>Supprimer ami</translation>
|
||||
<translation>Supprimer ce contact</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -502,7 +502,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<location filename="../src/widget/form/settings/generalform.cpp" line="267"/>
|
||||
<source>You can't disconnect while a call is active!</source>
|
||||
<comment>popup text</comment>
|
||||
<translation>Vous ne pouvez pas vous déconnecter avec un appel en cours!</translation>
|
||||
<translation>Vous ne pouvez pas vous déconnecter avec un appel en cours !</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -520,7 +520,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<location filename="../src/widget/form/settings/generalsettings.ui" line="64"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="80"/>
|
||||
<source>The translation may not load until qTox restarts.</source>
|
||||
<translation>La translation peut ne pas se charger jusqu'à ce que qTox redémarre.</translation>
|
||||
<translation>La traduction peut ne pas prendre effet immédiatement. Redémarrez qTox si ce n'est pas le cas.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Translation:</source>
|
||||
|
@ -550,7 +550,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="133"/>
|
||||
<source>Minimize to tray</source>
|
||||
<translation>Minimizer dans la barre d'état</translation>
|
||||
<translation>Minimiser dans la barre d'état</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="142"/>
|
||||
|
@ -564,7 +564,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
</message>
|
||||
<message>
|
||||
<source>Auto away after (0 to disable):</source>
|
||||
<translation type="vanished">Auto-absent après (0 pour désactiver):</translation>
|
||||
<translation type="vanished">Se rendre absent après (0 pour désactiver):</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="191"/>
|
||||
|
@ -620,7 +620,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<location filename="../src/widget/form/settings/generalsettings.ui" line="492"/>
|
||||
<source>Reconnect</source>
|
||||
<comment>reconnect button</comment>
|
||||
<translation>Reconnection</translation>
|
||||
<translation>Se reconnecter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="422"/>
|
||||
|
@ -640,7 +640,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="156"/>
|
||||
<source>Focus qTox when a message is received</source>
|
||||
<translation>Montrer qTox quand un message est reçu</translation>
|
||||
<translation>Montrer la fênetre qTox quand un message est reçu</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="163"/>
|
||||
|
@ -713,7 +713,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<message>
|
||||
<source>This allows, e.g., toxing over Tor. It adds load to the Tox network however, so use only when necessary.</source>
|
||||
<extracomment>force tcp checkbox tooltip</extracomment>
|
||||
<translation type="vanished">Permet par exemple d'utiliser Tox à travers Tor, mais ce n'est à utiliser que si nécessaire, car cela ralenti le réseau Tox.</translation>
|
||||
<translation type="vanished">Permet par exemple d'utiliser Tox à travers Tor, mais ce n'est à utiliser que si nécessaire car cela ralenti le réseau Tox.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Disable UDP (not recommended)</source>
|
||||
|
@ -748,7 +748,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="64"/>
|
||||
<source>Smileys</source>
|
||||
<translation>Emoticones</translation>
|
||||
<translation>Émoticônes</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="68"/>
|
||||
|
@ -768,7 +768,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="77"/>
|
||||
<source>Toggle speakers volume</source>
|
||||
<translation>Couper les haut parleurs</translation>
|
||||
<translation>Couper les haut-parleurs</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="80"/>
|
||||
|
@ -818,7 +818,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<location filename="../src/widget/groupwidget.cpp" line="44"/>
|
||||
<location filename="../src/widget/groupwidget.cpp" line="66"/>
|
||||
<source>0 users in chat</source>
|
||||
<translation>0 personnes</translation>
|
||||
<translation>Le groupe est vide</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/groupwidget.cpp" line="53"/>
|
||||
|
@ -844,7 +844,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<location filename="../src/widget/form/settings/identityform.cpp" line="133"/>
|
||||
<source>You can't switch profiles while a call is active!</source>
|
||||
<comment>popup text</comment>
|
||||
<translation>Vous ne pouvez pas changer de profil quand un appel est en cours!</translation>
|
||||
<translation>Vous ne pouvez pas changer de profil quand un appel est en cours !</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="143"/>
|
||||
|
@ -894,7 +894,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="186"/>
|
||||
<source>The file you chose could not be written to.</source>
|
||||
<translation>Le fichier que vous avez choisi n'as pas pu être écrit.</translation>
|
||||
<translation>Le fichier que vous avez choisi n'es pas disponible en écriture.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="194"/>
|
||||
|
@ -912,7 +912,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<location filename="../src/widget/form/settings/identityform.cpp" line="198"/>
|
||||
<source>Deletion imminent!</source>
|
||||
<comment>deletion confirmation title</comment>
|
||||
<translation>Suppression imminente!</translation>
|
||||
<translation>Suppression imminente !</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="199"/>
|
||||
|
@ -936,13 +936,13 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<location filename="../src/widget/form/settings/identityform.cpp" line="223"/>
|
||||
<source>Ignoring non-Tox file</source>
|
||||
<comment>popup title</comment>
|
||||
<translation>Fichier non-Tox ignoré</translation>
|
||||
<translation>Fichier incompatible avec Tox ignoré</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="224"/>
|
||||
<source>Warning: you've chosen a file that is not a Tox save file; ignoring.</source>
|
||||
<comment>popup text</comment>
|
||||
<translation>Attention: Vous avez sélectionné un fichier qui n'est pas une sauvegarde Tox: il sera ignoré.</translation>
|
||||
<translation>Attention: Vous avez sélectionné un fichier qui n'est pas une sauvegarde Tox, il sera ignoré.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="230"/>
|
||||
|
@ -986,7 +986,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<message>
|
||||
<location filename="../src/widget/form/settings/identitysettings.ui" line="88"/>
|
||||
<source>Your Tox ID (click to copy)</source>
|
||||
<translation>Votre ID Tox (cliquez pour copier)</translation>
|
||||
<translation>Votre Tox ID (cliquez pour copier)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identitysettings.ui" line="98"/>
|
||||
|
@ -1033,7 +1033,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<location filename="../src/widget/form/settings/identitysettings.ui" line="151"/>
|
||||
<source>This is useful to remain safe on public computers</source>
|
||||
<comment>delete profile button tooltip</comment>
|
||||
<translation>Util pour sécuriser sur un ordinateur public</translation>
|
||||
<translation>Utile pour rester en sécurité sur un ordinateur public</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identitysettings.ui" line="165"/>
|
||||
|
@ -1045,7 +1045,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<location filename="../src/widget/form/settings/identitysettings.ui" line="175"/>
|
||||
<source>New Tox ID</source>
|
||||
<comment>new profile button</comment>
|
||||
<translation>Nouvel ID Tox</translation>
|
||||
<translation>Nouvel Tox ID</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -1093,12 +1093,12 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<message>
|
||||
<location filename="../src/mainwindow.ui" line="1101"/>
|
||||
<source>Add friends</source>
|
||||
<translation>Ajouter des amis</translation>
|
||||
<translation>Ajouter des contacts</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.ui" line="1139"/>
|
||||
<source>Create a group chat</source>
|
||||
<translation>Creer un groupe</translation>
|
||||
<translation>Créer un groupe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.ui" line="1174"/>
|
||||
|
@ -1125,7 +1125,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<message>
|
||||
<location filename="../src/widget/netcamview.cpp" line="28"/>
|
||||
<source>Tox video</source>
|
||||
<translation>Vidéo tox</translation>
|
||||
<translation>Vidéo Tox</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -1145,7 +1145,7 @@ Voulez-vous essayer un mot de passe différent?</translation>
|
|||
<source>You already have history log file encrypted with different password
|
||||
Do you want to delete old history file?</source>
|
||||
<translation>Vous avez déjà un historique chiffré avec un autre mot de passe
|
||||
Voulez vous supprimer l'ancien historique?</translation>
|
||||
Voulez vous supprimer l'ancien historique ?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -1192,7 +1192,7 @@ Voulez vous supprimer l'ancien historique?</translation>
|
|||
<location filename="../src/widget/toxsave.cpp" line="64"/>
|
||||
<source>Warning: you've chosen a file that is not a Tox save file; ignoring.</source>
|
||||
<comment>popup text</comment>
|
||||
<translation>Attention: Vous avez sélectionné un fichier qui n'est pas une sauvegarde Tox: il sera ignoré.</translation>
|
||||
<translation>Attention: Vous avez sélectionné un fichier qui n'est pas une sauvegarde Tox, il sera ignoré.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/toxsave.cpp" line="70"/>
|
||||
|
@ -1233,12 +1233,12 @@ Voulez vous supprimer l'ancien historique?</translation>
|
|||
<source>An update is available, do you want to download it now ?
|
||||
It will be installed when qTox restarts.</source>
|
||||
<translation>Une mise à jour est disponible, voulez vous la télécharger maintenant ?
|
||||
Elle sera installée au prochain démarrage de qTox</translation>
|
||||
Elle sera installée au prochain démarrage de qTox.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/main.cpp" line="68"/>
|
||||
<source>Tox URI to parse</source>
|
||||
<translation>URI Tox à utiliser</translation>
|
||||
<translation>URL Tox à utiliser</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -1255,7 +1255,7 @@ Elle sera installée au prochain démarrage de qTox</translation>
|
|||
<message>
|
||||
<location filename="../src/widget/form/setpassworddialog.ui" line="37"/>
|
||||
<source>Repeat Password</source>
|
||||
<translation>Répetez le mot de passe</translation>
|
||||
<translation>Retapez le mot de passe</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -1270,13 +1270,13 @@ Elle sera installée au prochain démarrage de qTox</translation>
|
|||
<location filename="../src/toxdns.cpp" line="70"/>
|
||||
<source>This address does not exist</source>
|
||||
<comment>The DNS gives the Tox ID associated to toxme.se addresses</comment>
|
||||
<translation>Cette addresse n'existe pas</translation>
|
||||
<translation>Cette adresse n'existe pas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/toxdns.cpp" line="75"/>
|
||||
<source>Error while looking up DNS</source>
|
||||
<comment>The DNS gives the Tox ID associated to toxme.se addresses</comment>
|
||||
<translation>Erreur en consultant le serveur DNS</translation>
|
||||
<translation>Une erreur s'est produite en consultant le serveur DNS</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/toxdns.cpp" line="82"/>
|
||||
|
@ -1316,22 +1316,22 @@ Elle sera installée au prochain démarrage de qTox</translation>
|
|||
<location filename="../src/widget/toxuri.cpp" line="80"/>
|
||||
<source>Add a friend</source>
|
||||
<comment>Title of the window to add a friend through Tox URI</comment>
|
||||
<translation>Ajouter un ami</translation>
|
||||
<translation>Ajouter un contact</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/toxuri.cpp" line="82"/>
|
||||
<source>Do you want to add %1 as a friend ?</source>
|
||||
<translation>Voulez-vous ajouter %1 à vos amis ?</translation>
|
||||
<translation>Voulez-vous ajouter %1 à vos contacts ?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/toxuri.cpp" line="83"/>
|
||||
<source>User ID:</source>
|
||||
<translation>ID utilisateur:</translation>
|
||||
<translation>ID d'utilisateur:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/toxuri.cpp" line="87"/>
|
||||
<source>Friend request message:</source>
|
||||
<translation>Message de demande d'ami:</translation>
|
||||
<translation>Associer un message à cette demande:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/toxuri.cpp" line="92"/>
|
||||
|
@ -1354,7 +1354,7 @@ Elle sera installée au prochain démarrage de qTox</translation>
|
|||
</message>
|
||||
<message>
|
||||
<source>away</source>
|
||||
<translation type="vanished">indisponnible</translation>
|
||||
<translation type="vanished">absent</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>busy</source>
|
||||
|
@ -1368,7 +1368,7 @@ Elle sera installée au prochain démarrage de qTox</translation>
|
|||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="77"/>
|
||||
<source>Away</source>
|
||||
<translation>Indisponible</translation>
|
||||
<translation>Absent</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="80"/>
|
||||
|
@ -1383,7 +1383,7 @@ Elle sera installée au prochain démarrage de qTox</translation>
|
|||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="86"/>
|
||||
<source>Change status to:</source>
|
||||
<translation>Changer le status en:</translation>
|
||||
<translation>Changer le status par:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="155"/>
|
||||
|
@ -1395,7 +1395,7 @@ Elle sera installée au prochain démarrage de qTox</translation>
|
|||
<location filename="../src/widget/widget.cpp" line="157"/>
|
||||
<source>Away</source>
|
||||
<comment>Button to set your status to 'Away'</comment>
|
||||
<translation>Indisponible</translation>
|
||||
<translation>Absent</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="159"/>
|
||||
|
@ -1443,18 +1443,18 @@ Elle sera installée au prochain démarrage de qTox</translation>
|
|||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="477"/>
|
||||
<source>Toxcore failed to start, the application will terminate after you close this message.</source>
|
||||
<translation>Toxcore n'as pas pu démarrer correctement, l'application va quitter quand vous fermerez ce message.</translation>
|
||||
<translation>ToxCore n'as pas pu démarrer correctement, l'application va s'arrêter quand vous fermerez cette alerte.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="486"/>
|
||||
<source>toxcore failed to start with your proxy settings. qTox cannot run; please modify your settings and restart.</source>
|
||||
<comment>popup text</comment>
|
||||
<translation>Toxcore n'as pas pu démarrer avec ces paramètres de proxy, qTox ne peut pas continuer; merci de modifier vos paramètres et redémarrer.</translation>
|
||||
<translation>ToxCore n'as pas pu démarrer avec ces paramètres proxy. Merci de modifier ou désactiver vos paramètres et redémarrer l'application.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="521"/>
|
||||
<source>Add friend</source>
|
||||
<translation>Ajouter un ami</translation>
|
||||
<translation>Ajouter un contact</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="533"/>
|
||||
|
@ -1469,13 +1469,13 @@ Elle sera installée au prochain démarrage de qTox</translation>
|
|||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="656"/>
|
||||
<source>Couldn't request friendship</source>
|
||||
<translation>Impossible de demander en ami</translation>
|
||||
<translation>Impossible d'envoyer la demande de contact</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="684"/>
|
||||
<source>away</source>
|
||||
<comment>contact status</comment>
|
||||
<translation>indisponnible</translation>
|
||||
<translation>absent</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="686"/>
|
||||
|
@ -1487,7 +1487,7 @@ Elle sera installée au prochain démarrage de qTox</translation>
|
|||
<location filename="../src/widget/widget.cpp" line="688"/>
|
||||
<source>offline</source>
|
||||
<comment>contact status</comment>
|
||||
<translation>déconnecté</translation>
|
||||
<translation>hors ligne</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="690"/>
|
||||
|
@ -1510,7 +1510,7 @@ Elle sera installée au prochain démarrage de qTox</translation>
|
|||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="1091"/>
|
||||
<source>Message failed to send</source>
|
||||
<translation>Le message n'as pas pu être envoyé</translation>
|
||||
<translation>Le message n'as pu être envoyé</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
4
translations/i18n.pri
vendored
|
@ -6,12 +6,14 @@ TRANSLATIONS = translations/es.ts \
|
|||
translations/fi.ts \
|
||||
translations/fr.ts \
|
||||
translations/it.ts \
|
||||
translations/lt.ts \
|
||||
translations/mannol.ts \
|
||||
translations/pirate.ts \
|
||||
translations/pl.ts \
|
||||
translations/ru.ts \
|
||||
translations/sv.ts \
|
||||
translations/uk.ts
|
||||
translations/uk.ts \
|
||||
translations/pt.ts
|
||||
|
||||
#rules to generate ts
|
||||
isEmpty(QMAKE_LUPDATE) {
|
||||
|
|
243
translations/it.ts
vendored
|
@ -12,12 +12,12 @@
|
|||
<context>
|
||||
<name>AVSettings</name>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="105"/>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="112"/>
|
||||
<source>Video Settings</source>
|
||||
<translation>Impostazioni Video</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="116"/>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="123"/>
|
||||
<source>Resolution</source>
|
||||
<translation>Risoluzione</translation>
|
||||
</message>
|
||||
|
@ -52,22 +52,27 @@
|
|||
<translation>Cerca dispositivi audio</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="133"/>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="102"/>
|
||||
<source>Filter audio</source>
|
||||
<translation>Filtra audio</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="140"/>
|
||||
<source>Hue</source>
|
||||
<translation>Colore</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="147"/>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="154"/>
|
||||
<source>Brightness</source>
|
||||
<translation>Luminoistà</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="161"/>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="168"/>
|
||||
<source>Saturation</source>
|
||||
<translation>Saturazione</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="175"/>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="182"/>
|
||||
<source>Contrast</source>
|
||||
<translation>Contrasto</translation>
|
||||
</message>
|
||||
|
@ -182,62 +187,72 @@ Ignorare le impostazioni del proxy e connettersi direttamente alla rete Tox?</tr
|
|||
<context>
|
||||
<name>ChatForm</name>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="66"/>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="75"/>
|
||||
<source>Load History...</source>
|
||||
<translation>Carica log...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="137"/>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="162"/>
|
||||
<source>Send a file</source>
|
||||
<translation>Invia un file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="145"/>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="170"/>
|
||||
<source>File not read</source>
|
||||
<translation>Impossibile leggere il file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="145"/>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="170"/>
|
||||
<source>qTox wasn't able to open %1</source>
|
||||
<translation>qTox non è riuscito ad aprire %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="150"/>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="175"/>
|
||||
<source>Bad Idea</source>
|
||||
<translation>Pessima idea</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="150"/>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="175"/>
|
||||
<source>You're trying to send a special (sequential) file, that's not going to work!</source>
|
||||
<translation>Stai cercando di inviare un file speciale (sequenziale), questo non funzionerà!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="257"/>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="283"/>
|
||||
<source>%1 is calling</source>
|
||||
<translation>%1 ti sta chiamando</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="326"/>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="356"/>
|
||||
<source>%1 stopped calling</source>
|
||||
<translation>%1 ha fermato la chiamata</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="382"/>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="413"/>
|
||||
<source>Calling to %1</source>
|
||||
<translation>Stai chiamando %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="808"/>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="705"/>
|
||||
<source>Failed to send file "%1"</source>
|
||||
<translation>Invio del file "%1" fallito</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="839"/>
|
||||
<source>Call with %1 ended. %2</source>
|
||||
<translation>Chiamata con %1 terminata. %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="827"/>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="858"/>
|
||||
<source>Call duration: </source>
|
||||
<translation>Durata chiamata: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="523"/>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="905"/>
|
||||
<source>is typing...</source>
|
||||
<translation>sta scrivendo...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="554"/>
|
||||
<source>Call rejected</source>
|
||||
<translation>Chiamata rifiutata</translation>
|
||||
</message>
|
||||
|
@ -253,105 +268,105 @@ Ignorare le impostazioni del proxy e connettersi direttamente alla rete Tox?</tr
|
|||
<context>
|
||||
<name>Core</name>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="225"/>
|
||||
<location filename="../src/core.cpp" line="234"/>
|
||||
<source>Toxing on qTox</source>
|
||||
<translation>Toxing on qTox</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="226"/>
|
||||
<location filename="../src/core.cpp" line="235"/>
|
||||
<source>qTox User</source>
|
||||
<translation>qTox User</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="730"/>
|
||||
<location filename="../src/core.cpp" line="739"/>
|
||||
<source>Friend is already added</source>
|
||||
<translation>Questo contatto è già presente nella tua lista</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1171"/>
|
||||
<location filename="../src/core.cpp" line="1180"/>
|
||||
<source>Encryption error</source>
|
||||
<translation>Errore crittografia</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1171"/>
|
||||
<location filename="../src/core.cpp" line="1180"/>
|
||||
<source>The .tox file is encrypted, but encryption was not checked, continuing regardless.</source>
|
||||
<translation>Il Tox datafile è criptato, ma la crittografia non è abilitata nelle impostazioni.
|
||||
Continuo ignorando le impostazioni.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1178"/>
|
||||
<location filename="../src/core.cpp" line="1187"/>
|
||||
<source>Tox datafile decryption password</source>
|
||||
<translation>Password per decriptare il Tox datafile</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1180"/>
|
||||
<location filename="../src/core.cpp" line="1192"/>
|
||||
<location filename="../src/core.cpp" line="1256"/>
|
||||
<location filename="../src/core.cpp" line="1189"/>
|
||||
<location filename="../src/core.cpp" line="1201"/>
|
||||
<location filename="../src/core.cpp" line="1265"/>
|
||||
<source>Password error</source>
|
||||
<translation>Errore password</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1180"/>
|
||||
<location filename="../src/core.cpp" line="1256"/>
|
||||
<location filename="../src/core.cpp" line="1189"/>
|
||||
<location filename="../src/core.cpp" line="1265"/>
|
||||
<source>Failed to setup password.
|
||||
Empty password.</source>
|
||||
<translation>Impossibile impostare la password.
|
||||
Password vuota.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1188"/>
|
||||
<location filename="../src/core.cpp" line="1197"/>
|
||||
<source>Try Again</source>
|
||||
<translation>Riprova</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1189"/>
|
||||
<location filename="../src/core.cpp" line="1198"/>
|
||||
<source>Change profile</source>
|
||||
<translation>Cambia profilo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1190"/>
|
||||
<location filename="../src/core.cpp" line="1199"/>
|
||||
<source>Reinit current profile</source>
|
||||
<translation>Reinizializza il profilo corrente</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1193"/>
|
||||
<location filename="../src/core.cpp" line="1202"/>
|
||||
<source>Wrong password has been entered</source>
|
||||
<translation>È stata inserita una password sbagliata</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1254"/>
|
||||
<location filename="../src/core.cpp" line="1263"/>
|
||||
<source>History Log decryption password</source>
|
||||
<translation>Password per decriptare i log</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1261"/>
|
||||
<location filename="../src/core.cpp" line="1270"/>
|
||||
<source>Encrypted log</source>
|
||||
<translation>Log criptato</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1262"/>
|
||||
<location filename="../src/core.cpp" line="1271"/>
|
||||
<source>Your history is encrypted with different password.
|
||||
Do you want to try another password?</source>
|
||||
<translation>I log delle chat sono criptati con una password diversa.
|
||||
Vuoi provare ad inserire un'altra password?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1272"/>
|
||||
<location filename="../src/core.cpp" line="1281"/>
|
||||
<source>History</source>
|
||||
<translation>Chat Log</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1272"/>
|
||||
<location filename="../src/core.cpp" line="1281"/>
|
||||
<source>Due to incorret password history will be disabled.</source>
|
||||
<translation>Password errata, i log delle chat non saranno caricati.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1345"/>
|
||||
<location filename="../src/core.cpp" line="1354"/>
|
||||
<source>NO Password</source>
|
||||
<translation>Nessuna password</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1345"/>
|
||||
<location filename="../src/core.cpp" line="1354"/>
|
||||
<source>Will be saved without encryption!</source>
|
||||
<translation>Il Tox datafile sarà salvato senza password!</translation>
|
||||
</message>
|
||||
|
@ -538,17 +553,22 @@ Soprannome:</translation>
|
|||
<translation>Mostra icona nella traybar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="226"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="158"/>
|
||||
<source>Light icon</source>
|
||||
<translation>Icona brillante</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="217"/>
|
||||
<source>Set to 0 to disable</source>
|
||||
<translation>Imposta 0 per disabilitare</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="477"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="471"/>
|
||||
<source>Connection Settings</source>
|
||||
<translation>Impostazioni Connessione</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="489"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="483"/>
|
||||
<source>Enable IPv6 (recommended)</source>
|
||||
<extracomment>Text on a checkbox to enable IPv6</extracomment>
|
||||
<translation>Abilita IPv6 (consigliato)</translation>
|
||||
|
@ -590,143 +610,148 @@ Soprannome:</translation>
|
|||
<translation>Minimizza nella traybar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="164"/>
|
||||
<source>Tray icon displays user status</source>
|
||||
<translation>Mostra lo stato nell'icona della traybar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="167"/>
|
||||
<source>This is a temporary work around until proper systray status icons are available.</source>
|
||||
<translation>Questo è un workaround temporaneo fino a quando non saranno disponibili icone di stato adeguate.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="177"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="168"/>
|
||||
<source>Show contacts' status changes</source>
|
||||
<translation>Mostra quando i contatti cambiano stato</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="184"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="175"/>
|
||||
<source>Check for updates on startup (unstable)</source>
|
||||
<translation>Controlla aggiornamenti all'avvio (unstable)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="191"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="182"/>
|
||||
<source>Focus qTox when a message is received</source>
|
||||
<translation>Dai il focus a qTox quando arriva un messaggio</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="198"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="189"/>
|
||||
<source>Faux offline messaging</source>
|
||||
<translation>Falsi messaggi offline</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="207"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="198"/>
|
||||
<source>Provided in minutes</source>
|
||||
<translation>Espresso in minuti</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="213"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="204"/>
|
||||
<source>Auto away after (0 to disable)</source>
|
||||
<translation>Imposta assenza dopo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="229"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="223"/>
|
||||
<source> minutes</source>
|
||||
<translation> minuti</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="249"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="240"/>
|
||||
<source>You can set this on a per-friend basis by right clicking them.</source>
|
||||
<comment>autoaccept cb tooltip</comment>
|
||||
<translation>Puoi impostare questa preferenza per ogni singolo contatto usando il click destro sul suo nome.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="252"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="243"/>
|
||||
<source>Autoaccept files</source>
|
||||
<translation>Accetta automaticamente i trasferimenti di files</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="261"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="252"/>
|
||||
<source>Save files in</source>
|
||||
<translation>Salva i files in</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="274"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="265"/>
|
||||
<source>PushButton</source>
|
||||
<translation>Sfoglia</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="294"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="285"/>
|
||||
<source>Theme</source>
|
||||
<translation>Impostazioni Tema</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="300"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="291"/>
|
||||
<source>Use emoticons</source>
|
||||
<translation>Usa emoticons</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="315"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="309"/>
|
||||
<source>Smiley Pack</source>
|
||||
<extracomment>Text on smiley pack label</extracomment>
|
||||
<translation>Emoticons</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="332"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="383"/>
|
||||
<source>Style</source>
|
||||
<translation>Stile</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="406"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="400"/>
|
||||
<source>Theme color</source>
|
||||
<translation>Colore</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="423"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="417"/>
|
||||
<source>Emoticon size</source>
|
||||
<translation>Dimensione emoticons</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="439"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="433"/>
|
||||
<source> px</source>
|
||||
<translation> px</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="455"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="449"/>
|
||||
<source>Timestamp format</source>
|
||||
<translation>Formato data/ora</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="496"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="490"/>
|
||||
<source>Disabling this allows, e.g., toxing over Tor. It adds load to the Tox network however, so uncheck only when necessary.</source>
|
||||
<extracomment>force tcp checkbox tooltip</extracomment>
|
||||
<translation>Disabilitando questo sarà possibile usare qTox con Tor. Tuttavia verrà aggiunto carico alla rete Tox, quindi disabilitare solo se necessario.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="499"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="493"/>
|
||||
<source>Enable UDP (recommended)</source>
|
||||
<extracomment>Text on checkbox to disable UDP</extracomment>
|
||||
<translation>Abilita UDP (consigliato)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="506"/>
|
||||
<source>Use proxy (SOCKS5)</source>
|
||||
<translation>Usa proxy (SOCKS5)</translation>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="502"/>
|
||||
<source>Proxy type</source>
|
||||
<translation>Proxy</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="518"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="516"/>
|
||||
<source>None</source>
|
||||
<translation>Nessuno</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="521"/>
|
||||
<source>SOCKS5</source>
|
||||
<translation>SOCKS 5</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="526"/>
|
||||
<source>HTTP</source>
|
||||
<translation>HTTP</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="541"/>
|
||||
<source>Address</source>
|
||||
<extracomment>Text on proxy addr label</extracomment>
|
||||
<translation>IP</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="528"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="551"/>
|
||||
<source>Port</source>
|
||||
<extracomment>Text on proxy port label</extracomment>
|
||||
<translation>Porta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="547"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="570"/>
|
||||
<source>Reconnect</source>
|
||||
<comment>reconnect button</comment>
|
||||
<translation>Riconnetti</translation>
|
||||
|
@ -735,43 +760,43 @@ Soprannome:</translation>
|
|||
<context>
|
||||
<name>GenericChatForm</name>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="65"/>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="68"/>
|
||||
<source>Send message</source>
|
||||
<translation>Invia messaggio</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="67"/>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="70"/>
|
||||
<source>Smileys</source>
|
||||
<translation>Emoticons</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="71"/>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="74"/>
|
||||
<source>Send file(s)</source>
|
||||
<translation>Invia file(s)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="74"/>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="77"/>
|
||||
<source>Audio call: RED means you're on a call</source>
|
||||
<translation>Chiamata audio: ROSSO significa che la chiamata è in corso</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="77"/>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="80"/>
|
||||
<source>Video call: RED means you're on a call</source>
|
||||
<translation>Videochiamata: ROSSO significa che la chiamata è in corso</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="80"/>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="83"/>
|
||||
<source>Toggle speakers volume: RED is OFF</source>
|
||||
<translation>Imposta volume altoparlanti: ROSSO è SPENTO</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="83"/>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="86"/>
|
||||
<source>Toggle microphone: RED is OFF</source>
|
||||
<translation>Imposta microfono: ROSSO è SPENTO</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="149"/>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="191"/>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="192"/>
|
||||
<source>Save chat log</source>
|
||||
<translation>Salva il log della chat</translation>
|
||||
</message>
|
||||
|
@ -781,7 +806,7 @@ Soprannome:</translation>
|
|||
<translation>Rimuovi messaggi visualizzati</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="290"/>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="297"/>
|
||||
<source>Cleared</source>
|
||||
<translation>Pulito</translation>
|
||||
</message>
|
||||
|
@ -927,42 +952,44 @@ Nome gruppo:</translation>
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="199"/>
|
||||
<source>Are you sure you want to delete this profile?</source>
|
||||
<source>Are you sure you want to delete this profile?
|
||||
Associated friend information and chat logs will be deleted as well.</source>
|
||||
<comment>deletion confirmation text</comment>
|
||||
<translation>Sei sicuro di voler eliminare questo profilo?</translation>
|
||||
<translation>Sei sicuro di voler eliminare questo profilo?
|
||||
I contatti e i log delle chat associati ad esso, saranno eliminati.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="211"/>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="218"/>
|
||||
<source>Import profile</source>
|
||||
<comment>import dialog title</comment>
|
||||
<translation>Importa profilo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="213"/>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="220"/>
|
||||
<source>Tox save file (*.tox)</source>
|
||||
<comment>import dialog filter</comment>
|
||||
<translation>Tox save file (*.tox)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="223"/>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="230"/>
|
||||
<source>Ignoring non-Tox file</source>
|
||||
<comment>popup title</comment>
|
||||
<translation>File ignorato</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="224"/>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="231"/>
|
||||
<source>Warning: you've chosen a file that is not a Tox save file; ignoring.</source>
|
||||
<comment>popup text</comment>
|
||||
<translation>Attenzione: hai scelto un file che non contiente un profilo Tox.\nQuesto file verrà ignorato.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="230"/>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="237"/>
|
||||
<source>Profile already exists</source>
|
||||
<comment>import confirm title</comment>
|
||||
<translation>Profilo già esistente</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="231"/>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="238"/>
|
||||
<source>A profile named "%1" already exists. Do you want to erase it?</source>
|
||||
<comment>import confirm text</comment>
|
||||
<translation>Un profilo chiamato "%1" esiste già. Vuoi sovrascriverlo?</translation>
|
||||
|
@ -1151,8 +1178,8 @@ Vuoi eliminare il vecchio file?</translation>
|
|||
<name>PrivacySettings</name>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/privacysettings.ui" line="50"/>
|
||||
<source>Typing Notification</source>
|
||||
<translation>Notifica quando qualcuno sta scrivendo</translation>
|
||||
<source>Send Typing Notifications</source>
|
||||
<translation>Permetti ai miei contatti di vedere quando sto scrivendo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/privacysettings.ui" line="60"/>
|
||||
|
@ -1233,13 +1260,13 @@ Vuoi eliminare il vecchio file?</translation>
|
|||
<translation>%1.tox è stato importato con successo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/autoupdate.cpp" line="430"/>
|
||||
<location filename="../src/autoupdate.cpp" line="457"/>
|
||||
<source>Update</source>
|
||||
<comment>The title of a message box</comment>
|
||||
<translation>Nuova versione</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/autoupdate.cpp" line="431"/>
|
||||
<location filename="../src/autoupdate.cpp" line="458"/>
|
||||
<source>An update is available, do you want to download it now?
|
||||
It will be installed when qTox restarts.</source>
|
||||
<translation>È disponibile una nuova versione di qTox, vuoi scaricarla adesso?
|
||||
|
@ -1350,6 +1377,15 @@ Verrà installata al riavvio del programma.</translation>
|
|||
<comment>Error with the DNS</comment>
|
||||
<translation>La risposta del server DNS non contiene un Tox ID valido</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/toxdns.cpp" line="223"/>
|
||||
<location filename="../src/toxdns.cpp" line="267"/>
|
||||
<source>It appears that qTox has to use the old tox1 protocol.
|
||||
Unfortunately tox1 is not secure. Should it be used anyway?</source>
|
||||
<translation>Sembra che qTox debba usare il vecchio protocollo tox1.
|
||||
Sfortunatamente il protocollo tox1 non è sicuro.
|
||||
Usare comunque il protocollo tox1?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ToxURIDialog</name>
|
||||
|
@ -1409,11 +1445,6 @@ Verrà installata al riavvio del programma.</translation>
|
|||
<source>&Quit</source>
|
||||
<translation>&Esci</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="104"/>
|
||||
<source>Change status to:</source>
|
||||
<translation>Cambia stato in:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="173"/>
|
||||
<source>Online</source>
|
||||
|
|
1579
translations/lt.ts
vendored
Normal file
1578
translations/pt.ts
vendored
Normal file
414
translations/ru.ts
vendored
|
@ -12,12 +12,12 @@
|
|||
<context>
|
||||
<name>AVSettings</name>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="98"/>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="112"/>
|
||||
<source>Video Settings</source>
|
||||
<translation>Настройки видео</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="109"/>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="123"/>
|
||||
<source>Resolution</source>
|
||||
<translation>Разрешение</translation>
|
||||
</message>
|
||||
|
@ -47,22 +47,32 @@
|
|||
<translation>Устройство записи</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="126"/>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="95"/>
|
||||
<source>Rescan audio devices</source>
|
||||
<translation>Повторить поиск аудиоустройств</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="102"/>
|
||||
<source>Filter audio</source>
|
||||
<translation>Фильтрация звука</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="140"/>
|
||||
<source>Hue</source>
|
||||
<translation>Тон</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="140"/>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="154"/>
|
||||
<source>Brightness</source>
|
||||
<translation>Яркость</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="154"/>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="168"/>
|
||||
<source>Saturation</source>
|
||||
<translation>Насыщенность</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="168"/>
|
||||
<location filename="../src/widget/form/settings/avsettings.ui" line="182"/>
|
||||
<source>Contrast</source>
|
||||
<translation>Контраст</translation>
|
||||
</message>
|
||||
|
@ -113,8 +123,14 @@
|
|||
<message>
|
||||
<location filename="../src/widget/form/addfriendform.cpp" line="100"/>
|
||||
<source>qTox needs to use the Tox DNS, but can't do it through a proxy.
|
||||
Ignore the proxy and connect to the Internet directly ?</source>
|
||||
Ignore the proxy and connect to the Internet directly?</source>
|
||||
<translation>qTox необходимо воспользоваться Tox DNS, но это нельзя сделать через прокси.
|
||||
Игнорировать прокси и подлючиться напрямую через интернет?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>qTox needs to use the Tox DNS, but can't do it through a proxy.
|
||||
Ignore the proxy and connect to the Internet directly ?</source>
|
||||
<translation type="vanished">qTox необходимо воспользоваться Tox DNS, но это нельзя сделать через прокси.
|
||||
Игнорировать прокси и подлючиться напрямую через интернет?</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -152,7 +168,7 @@ Ignore the proxy and connect to the Internet directly ?</source>
|
|||
<message>
|
||||
<location filename="../src/widget/form/settings/advancedsettings.ui" line="14"/>
|
||||
<source>Form</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Form</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/advancedsettings.ui" line="35"/>
|
||||
|
@ -183,48 +199,68 @@ Ignore the proxy and connect to the Internet directly ?</source>
|
|||
<translation>Загрузить историю...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="135"/>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="137"/>
|
||||
<source>Send a file</source>
|
||||
<translation>Отправить файл</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="145"/>
|
||||
<source>File not read</source>
|
||||
<translation>Файл не прочитать</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="145"/>
|
||||
<source>qTox wasn't able to open %1</source>
|
||||
<translatorcomment>Паравозик не смог. Не сможешь и ты!</translatorcomment>
|
||||
<translation>qTox не смог открыть %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="150"/>
|
||||
<source>Bad Idea</source>
|
||||
<translation>Плохая идея</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="145"/>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="150"/>
|
||||
<source>You're trying to send a special (sequential) file, that's not going to work!</source>
|
||||
<translatorcomment>...передаёте последовательный файл и получаете te-le-fun-ken. И переводчик работает по другой линии. По линии «Библиотека».</translatorcomment>
|
||||
<translation>Вы пытаетесь отправить специальный (последовательный) файл. Это так не работает!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="251"/>
|
||||
<source>%1 calling</source>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="257"/>
|
||||
<source>%1 is calling</source>
|
||||
<translation>%1 звонит</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="320"/>
|
||||
<source>%1 calling</source>
|
||||
<translation type="vanished">%1 звонит</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="328"/>
|
||||
<source>%1 stopped calling</source>
|
||||
<translation>%1 прекратил звонить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="376"/>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="384"/>
|
||||
<source>Calling to %1</source>
|
||||
<translation>Звоним %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="517"/>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="525"/>
|
||||
<source>Call rejected</source>
|
||||
<translation>Звонок отклонён</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="801"/>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="676"/>
|
||||
<source>Failed to send file "%1"</source>
|
||||
<translation>Не удалось отправить файл «%1»</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="810"/>
|
||||
<source>Call with %1 ended. %2</source>
|
||||
<translation>Разговор с %1 завершился. %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="820"/>
|
||||
<location filename="../src/widget/form/chatform.cpp" line="829"/>
|
||||
<source>Call duration: </source>
|
||||
<translation>Длительность разговора:</translation>
|
||||
</message>
|
||||
|
@ -240,106 +276,120 @@ Ignore the proxy and connect to the Internet directly ?</source>
|
|||
<context>
|
||||
<name>Core</name>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="226"/>
|
||||
<location filename="../src/core.cpp" line="228"/>
|
||||
<source>Toxing on qTox</source>
|
||||
<translatorcomment>Как-то так. Может, можно ещё что-нибудь придумать?</translatorcomment>
|
||||
<translation type="unfinished">Всем привет из qTox'а</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="227"/>
|
||||
<location filename="../src/core.cpp" line="229"/>
|
||||
<source>qTox User</source>
|
||||
<translation>Пользователь qTox</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="727"/>
|
||||
<location filename="../src/core.cpp" line="733"/>
|
||||
<source>Friend is already added</source>
|
||||
<translation>Друг уже добавлен</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1168"/>
|
||||
<location filename="../src/core.cpp" line="1174"/>
|
||||
<source>Encryption error</source>
|
||||
<translation>Ошибка шифрования</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1168"/>
|
||||
<location filename="../src/core.cpp" line="1174"/>
|
||||
<source>The .tox file is encrypted, but encryption was not checked, continuing regardless.</source>
|
||||
<translation>Файл .tox зашифрован, однако шифрование в настройках включено не было. Продолжаем вопреки.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1175"/>
|
||||
<location filename="../src/core.cpp" line="1181"/>
|
||||
<source>Tox datafile decryption password</source>
|
||||
<translation>Пароль для расшифровки файла данных Tox</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1177"/>
|
||||
<location filename="../src/core.cpp" line="1189"/>
|
||||
<location filename="../src/core.cpp" line="1253"/>
|
||||
<location filename="../src/core.cpp" line="1183"/>
|
||||
<location filename="../src/core.cpp" line="1195"/>
|
||||
<location filename="../src/core.cpp" line="1259"/>
|
||||
<source>Password error</source>
|
||||
<translation>Ошибка пароля</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1177"/>
|
||||
<location filename="../src/core.cpp" line="1253"/>
|
||||
<location filename="../src/core.cpp" line="1183"/>
|
||||
<location filename="../src/core.cpp" line="1259"/>
|
||||
<source>Failed to setup password.
|
||||
Empty password.</source>
|
||||
<translation>Не удалось установить пароль.
|
||||
Пустой пароль.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1185"/>
|
||||
<location filename="../src/core.cpp" line="1191"/>
|
||||
<source>Try Again</source>
|
||||
<translation>Попробуйте ещё</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1186"/>
|
||||
<location filename="../src/core.cpp" line="1192"/>
|
||||
<source>Change profile</source>
|
||||
<translation>Сменить профиль</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1187"/>
|
||||
<location filename="../src/core.cpp" line="1193"/>
|
||||
<source>Reinit current profile</source>
|
||||
<translatorcomment>Увы, никто не знает, что разработчики имели в виду. Ту би транслейтед.</translatorcomment>
|
||||
<translation>Сбросить данные текущего профиля</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1190"/>
|
||||
<location filename="../src/core.cpp" line="1196"/>
|
||||
<source>Wrong password has been entered</source>
|
||||
<translation>Введён неправильный пароль</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1251"/>
|
||||
<location filename="../src/core.cpp" line="1257"/>
|
||||
<source>History Log decryption password</source>
|
||||
<translation>Пароль для расшифровки журнала переписки</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1258"/>
|
||||
<location filename="../src/core.cpp" line="1264"/>
|
||||
<source>Encrypted log</source>
|
||||
<translation>Зашифрованный журнал</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1259"/>
|
||||
<source>Your history is encrypted with different password
|
||||
<location filename="../src/core.cpp" line="1265"/>
|
||||
<source>Your history is encrypted with different password.
|
||||
Do you want to try another password?</source>
|
||||
<translation>Ваша переписка зашифрована другим паролем
|
||||
<translation>Ваша переписка зашифрована другим паролем.
|
||||
Ходите попробовать другой пароль?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1275"/>
|
||||
<source>History</source>
|
||||
<translation>История</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1275"/>
|
||||
<source>Due to incorret password history will be disabled.</source>
|
||||
<translation>Из-за некорректного пароля журналирование будет отключено.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Your history is encrypted with different password
|
||||
Do you want to try another password?</source>
|
||||
<translation type="vanished">Ваша переписка зашифрована другим паролем
|
||||
Ходите попробовать другой пароль?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1269"/>
|
||||
<source>Loggin</source>
|
||||
<translation>Журналирование</translation>
|
||||
<translation type="vanished">Журналирование</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1269"/>
|
||||
<source>Due to incorret password logging will be disabled</source>
|
||||
<translation>Из-за некорректного пароля журналирование будет отключено</translation>
|
||||
<translation type="vanished">Из-за некорректного пароля журналирование будет отключено</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1342"/>
|
||||
<location filename="../src/core.cpp" line="1348"/>
|
||||
<source>NO Password</source>
|
||||
<translation>БЕЗ пароля</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/core.cpp" line="1342"/>
|
||||
<location filename="../src/core.cpp" line="1348"/>
|
||||
<source>Will be saved without encryption!</source>
|
||||
<translation>Будет сохранено без шифрования!</translation>
|
||||
</message>
|
||||
|
@ -466,14 +516,20 @@ Do you want to try another password?</source>
|
|||
<translation>Выбрать папку для автоматического приёма</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/friendwidget.cpp" line="226"/>
|
||||
<location filename="../src/widget/friendwidget.cpp" line="238"/>
|
||||
<source>User alias</source>
|
||||
<translation>Псевдоним пользователя</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/friendwidget.cpp" line="226"/>
|
||||
<location filename="../src/widget/friendwidget.cpp" line="238"/>
|
||||
<source>You can also set this by clicking the chat form name.
|
||||
Alias:</source>
|
||||
<translation>Можно также установить, щёлкнув по имени вверху окна чата.
|
||||
Псевдоним:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Alias:</source>
|
||||
<translation>Новый псевдоним:</translation>
|
||||
<translation type="obsolete">Новый псевдоним:</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -484,25 +540,25 @@ Do you want to try another password?</source>
|
|||
<translation>Общие</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalform.cpp" line="73"/>
|
||||
<location filename="../src/widget/form/settings/generalform.cpp" line="79"/>
|
||||
<location filename="../src/widget/form/settings/generalform.cpp" line="81"/>
|
||||
<location filename="../src/widget/form/settings/generalform.cpp" line="87"/>
|
||||
<source>None</source>
|
||||
<translation>Отсутствует</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalform.cpp" line="223"/>
|
||||
<location filename="../src/widget/form/settings/generalform.cpp" line="242"/>
|
||||
<source>Choose an auto accept directory</source>
|
||||
<comment>popup title</comment>
|
||||
<translation>Выбрать папку для автоматического приёма</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalform.cpp" line="280"/>
|
||||
<location filename="../src/widget/form/settings/generalform.cpp" line="299"/>
|
||||
<source>Call active</source>
|
||||
<comment>popup title</comment>
|
||||
<translation>Идёт звонок</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalform.cpp" line="281"/>
|
||||
<location filename="../src/widget/form/settings/generalform.cpp" line="300"/>
|
||||
<source>You can't disconnect while a call is active!</source>
|
||||
<comment>popup text</comment>
|
||||
<translation>Нельзя отключиться пока идёт звонок!</translation>
|
||||
|
@ -522,130 +578,140 @@ Do you want to try another password?</source>
|
|||
<translation>Перевод не изменится до перезапуска qTox.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="101"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="99"/>
|
||||
<source>System tray integration</source>
|
||||
<translation>Настройки трея</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="108"/>
|
||||
<source>Show system tray icon</source>
|
||||
<translation>Показывать иконку в трее</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="127"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="136"/>
|
||||
<source>Close to tray</source>
|
||||
<translation>Сворачивать в трей при закрытии</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="140"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="149"/>
|
||||
<source>Minimize to tray</source>
|
||||
<translation>Сворачивать в трей</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="156"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="158"/>
|
||||
<source>Light icon</source>
|
||||
<translation>Светлая иконка</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="175"/>
|
||||
<source>Check for updates on startup (unstable)</source>
|
||||
<translation>Проверять на наличие обновлений (нестабильно)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="163"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="182"/>
|
||||
<source>Focus qTox when a message is received</source>
|
||||
<translation>Захватывать фокус при приёме сообщений</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="170"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="189"/>
|
||||
<source>Faux offline messaging</source>
|
||||
<translation>Имитация офлайнового обмена сообщениями</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="185"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="204"/>
|
||||
<source>Auto away after (0 to disable)</source>
|
||||
<translation>Менять статус на «Отошёл» после (0 — не менять)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="198"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="217"/>
|
||||
<source>Set to 0 to disable</source>
|
||||
<translation>Укажите 0, чтобы отключить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="221"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="240"/>
|
||||
<source>You can set this on a per-friend basis by right clicking them.</source>
|
||||
<comment>autoaccept cb tooltip</comment>
|
||||
<translation>Можно настроить отдельно для каждого друга (щёлкнув правой кнопкой мыши по другу и выбрав соответствующий пункт меню).</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="272"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="291"/>
|
||||
<source>Use emoticons</source>
|
||||
<translation>Использовать смайлики</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="281"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="306"/>
|
||||
<source>Smiley Pack</source>
|
||||
<extracomment>Text on smiley pack label</extracomment>
|
||||
<translation>Набор смайликов</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="359"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="323"/>
|
||||
<source>Style</source>
|
||||
<translation>Стиль</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="380"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="397"/>
|
||||
<source>Theme color</source>
|
||||
<translation>Цвет темы</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="401"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="414"/>
|
||||
<source>Emoticon size</source>
|
||||
<translation>Размер смайликов</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="417"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="430"/>
|
||||
<source> px</source>
|
||||
<translatorcomment>По аналогии с Мпикс. Хотя, может лучше принять http://ilyabirman.ru/meanwhile/all/px/?</translatorcomment>
|
||||
<translation> пикс</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="437"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="446"/>
|
||||
<source>Timestamp format</source>
|
||||
<translation>Формат времени</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="459"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="468"/>
|
||||
<source>Connection Settings</source>
|
||||
<translation>Настройки соединения</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="471"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="480"/>
|
||||
<source>Enable IPv6 (recommended)</source>
|
||||
<extracomment>Text on a checkbox to enable IPv6</extracomment>
|
||||
<translation>Включить IPv6 (рекомендуется)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="478"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="487"/>
|
||||
<source>Disabling this allows, e.g., toxing over Tor. It adds load to the Tox network however, so uncheck only when necessary.</source>
|
||||
<extracomment>force tcp checkbox tooltip</extracomment>
|
||||
<translation>Отключение позволяет, например, использовать Tox поверх Tor. Однако это добавляет нагрузку на сеть Tox, так что отключайте только в случае необходимости.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="481"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="490"/>
|
||||
<source>Enable UDP (recommended)</source>
|
||||
<extracomment>Text on checkbox to disable UDP</extracomment>
|
||||
<translation>Включить UDP (рекомендуется)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="488"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="497"/>
|
||||
<source>Use proxy (SOCKS5)</source>
|
||||
<translation>Использовать прокси (SOCKS5)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="500"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="509"/>
|
||||
<source>Address</source>
|
||||
<extracomment>Text on proxy addr label</extracomment>
|
||||
<translation>Адрес</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="510"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="519"/>
|
||||
<source>Port</source>
|
||||
<extracomment>Text on proxy port label</extracomment>
|
||||
<translation>Порт</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="529"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="538"/>
|
||||
<source>Reconnect</source>
|
||||
<comment>reconnect button</comment>
|
||||
<translation>Переподключиться</translation>
|
||||
|
@ -667,42 +733,42 @@ Do you want to try another password?</source>
|
|||
<translation>Портативный режим</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="114"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="123"/>
|
||||
<source>Start in tray</source>
|
||||
<translation>Запускать свёрнутым в трей</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="149"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="168"/>
|
||||
<source>Show contacts' status changes</source>
|
||||
<translation>Показывать изменения статусов контактов</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="179"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="198"/>
|
||||
<source>Provided in minutes</source>
|
||||
<translation>Выставлено в минутах</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="204"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="220"/>
|
||||
<source> minutes</source>
|
||||
<translation> минут</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="224"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="243"/>
|
||||
<source>Autoaccept files</source>
|
||||
<translation>Автоматически принимать файлы</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="233"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="252"/>
|
||||
<source>Save files in</source>
|
||||
<translation>Сохранять в</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="246"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="265"/>
|
||||
<source>PushButton</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="266"/>
|
||||
<location filename="../src/widget/form/settings/generalsettings.ui" line="285"/>
|
||||
<source>Theme</source>
|
||||
<translation>Тема</translation>
|
||||
</message>
|
||||
|
@ -710,53 +776,53 @@ Do you want to try another password?</source>
|
|||
<context>
|
||||
<name>GenericChatForm</name>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="62"/>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="65"/>
|
||||
<source>Send message</source>
|
||||
<translation>Отправить сообщение</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="64"/>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="67"/>
|
||||
<source>Smileys</source>
|
||||
<translation>Смайлики</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="68"/>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="71"/>
|
||||
<source>Send file(s)</source>
|
||||
<translation>Отправить файл(ы)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="71"/>
|
||||
<source>Audio call: RED means you're on a call</source>
|
||||
<translation>Позвонить, только аудио (красная кнопка значит что вы на связи)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="74"/>
|
||||
<source>Video call: RED means you're on a call</source>
|
||||
<translation>Видеозвонок (красная кнопка значит что вы на связи)</translation>
|
||||
<source>Audio call: RED means you're on a call</source>
|
||||
<translation>Позвонить, только аудио (красная кнопка означает что вы на связи)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="77"/>
|
||||
<source>Toggle speakers volume: RED is OFF</source>
|
||||
<translation>Включить или выключить звук (красная кнопка значит что звук выключен)</translation>
|
||||
<source>Video call: RED means you're on a call</source>
|
||||
<translation>Видеозвонок (красная кнопка означает что вы на связи)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="80"/>
|
||||
<source>Toggle microphone: RED is OFF</source>
|
||||
<translation>Включить или выключить микрофон (красная кнопка значит что микрофон выключен)</translation>
|
||||
<source>Toggle speakers volume: RED is OFF</source>
|
||||
<translation>Включить или выключить звук (красная кнопка означает что звук выключен)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="146"/>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="188"/>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="83"/>
|
||||
<source>Toggle microphone: RED is OFF</source>
|
||||
<translation>Включить или выключить микрофон (красная кнопка означает что микрофон выключен)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="149"/>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="192"/>
|
||||
<source>Save chat log</source>
|
||||
<translation>Сохранить журнал чата</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="147"/>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="150"/>
|
||||
<source>Clear displayed messages</source>
|
||||
<translation>Очистить показываемые сообщения</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="305"/>
|
||||
<location filename="../src/widget/form/genericchatform.cpp" line="296"/>
|
||||
<source>Cleared</source>
|
||||
<translation>Очищено</translation>
|
||||
</message>
|
||||
|
@ -764,13 +830,13 @@ Do you want to try another password?</source>
|
|||
<context>
|
||||
<name>GroupChatForm</name>
|
||||
<message>
|
||||
<location filename="../src/widget/form/groupchatform.cpp" line="58"/>
|
||||
<location filename="../src/widget/form/groupchatform.cpp" line="57"/>
|
||||
<source>%1 users in chat</source>
|
||||
<comment>Number of users in chat</comment>
|
||||
<translation>%1 пользователей в чате</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/groupchatform.cpp" line="109"/>
|
||||
<location filename="../src/widget/form/groupchatform.cpp" line="108"/>
|
||||
<source>%1 users in chat</source>
|
||||
<translation>%1 пользователей в чате</translation>
|
||||
</message>
|
||||
|
@ -778,23 +844,40 @@ Do you want to try another password?</source>
|
|||
<context>
|
||||
<name>GroupWidget</name>
|
||||
<message>
|
||||
<location filename="../src/widget/groupwidget.cpp" line="53"/>
|
||||
<location filename="../src/widget/groupwidget.cpp" line="55"/>
|
||||
<source>Quit group</source>
|
||||
<comment>Menu to quit a groupchat</comment>
|
||||
<translation>Покинуть группу</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/groupwidget.cpp" line="42"/>
|
||||
<location filename="../src/widget/groupwidget.cpp" line="64"/>
|
||||
<location filename="../src/widget/groupwidget.cpp" line="43"/>
|
||||
<location filename="../src/widget/groupwidget.cpp" line="80"/>
|
||||
<source>%1 users in chat</source>
|
||||
<translation>%1 пользователей в чате</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/groupwidget.cpp" line="44"/>
|
||||
<location filename="../src/widget/groupwidget.cpp" line="66"/>
|
||||
<location filename="../src/widget/groupwidget.cpp" line="45"/>
|
||||
<location filename="../src/widget/groupwidget.cpp" line="82"/>
|
||||
<source>0 users in chat</source>
|
||||
<translation>Ни одного пользователя в чате</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/groupwidget.cpp" line="54"/>
|
||||
<source>Set title...</source>
|
||||
<translation>Установить заголовок...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/groupwidget.cpp" line="67"/>
|
||||
<source>Group title</source>
|
||||
<translation>Заголовок группы</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/groupwidget.cpp" line="67"/>
|
||||
<source>You can also set this by clicking the chat form name.
|
||||
Title:</source>
|
||||
<translation>Можно также установить, щёлкнув по заголовку вверху окна чата.
|
||||
Заголовок:</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>IdentityForm</name>
|
||||
|
@ -885,42 +968,49 @@ Do you want to try another password?</source>
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="199"/>
|
||||
<source>Are you sure you want to delete this profile?</source>
|
||||
<source>Are you sure you want to delete this profile?
|
||||
Associated friend information and chat logs will be deleted as well.</source>
|
||||
<comment>deletion confirmation text</comment>
|
||||
<translation>Вы действительно хотите удалить этот профиль?</translation>
|
||||
<translation>Вы действительно хотите удалить этот профиль?
|
||||
Связанная с ним информация о друзьях и история переписки будут также удалены.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="211"/>
|
||||
<source>Are you sure you want to delete this profile?</source>
|
||||
<comment>deletion confirmation text</comment>
|
||||
<translation type="vanished">Вы действительно хотите удалить этот профиль?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="218"/>
|
||||
<source>Import profile</source>
|
||||
<comment>import dialog title</comment>
|
||||
<translation>Импортировать профиль</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="213"/>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="220"/>
|
||||
<source>Tox save file (*.tox)</source>
|
||||
<comment>import dialog filter</comment>
|
||||
<translation>Файл Tox (*.tox)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="223"/>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="230"/>
|
||||
<source>Ignoring non-Tox file</source>
|
||||
<comment>popup title</comment>
|
||||
<translation>Выбран не файл Tox</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="224"/>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="231"/>
|
||||
<source>Warning: you've chosen a file that is not a Tox save file; ignoring.</source>
|
||||
<comment>popup text</comment>
|
||||
<translation>Внимание: вы выбрали не файл Tox; игнорирование.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="230"/>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="237"/>
|
||||
<source>Profile already exists</source>
|
||||
<comment>import confirm title</comment>
|
||||
<translation>Профиль уже существует</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="231"/>
|
||||
<location filename="../src/widget/form/settings/identityform.cpp" line="238"/>
|
||||
<source>A profile named "%1" already exists. Do you want to erase it?</source>
|
||||
<comment>import confirm text</comment>
|
||||
<translation>Профиль с именем «%1» уже существует. Перезаписать?</translation>
|
||||
|
@ -1151,16 +1241,22 @@ Do you want to delete old history file?</source>
|
|||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<location filename="../src/autoupdate.cpp" line="431"/>
|
||||
<location filename="../src/autoupdate.cpp" line="430"/>
|
||||
<source>Update</source>
|
||||
<comment>The title of a message box</comment>
|
||||
<translation>Обновление</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/autoupdate.cpp" line="432"/>
|
||||
<location filename="../src/autoupdate.cpp" line="431"/>
|
||||
<source>An update is available, do you want to download it now?
|
||||
It will be installed when qTox restarts.</source>
|
||||
<translation>Обновление доступно, не желаете ли скачать его прямо сейчас?
|
||||
Оно будет установлено после того, как qTox будет перезапущен.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An update is available, do you want to download it now ?
|
||||
It will be installed when qTox restarts.</source>
|
||||
<translation>Обновление доступно, не желаете ли скачать его прамо сейчас?
|
||||
<translation type="vanished">Обновление доступно, не желаете ли скачать его прамо сейчас?
|
||||
Оно будет установлено после того, как qTox будет перезапущен.</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -1209,6 +1305,18 @@ It will be installed when qTox restarts.</source>
|
|||
<translatorcomment>Без перевода, так как весь остальной CLI на английском</translatorcomment>
|
||||
<translation>Tox URI to parse</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/main.cpp" line="69"/>
|
||||
<source>Starts new instance and loads specified profile.</source>
|
||||
<translatorcomment>Без перевода, так как весь остальной CLI на английском</translatorcomment>
|
||||
<translation>Starts new instance and loads specified profile.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/main.cpp" line="69"/>
|
||||
<source>profile</source>
|
||||
<translatorcomment>Без перевода, так как весь остальной CLI на английском</translatorcomment>
|
||||
<translation>profile</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/misc/style.cpp" line="72"/>
|
||||
<source>Default</source>
|
||||
|
@ -1309,8 +1417,12 @@ It will be installed when qTox restarts.</source>
|
|||
<translation>Добавить друга</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/toxuri.cpp" line="82"/>
|
||||
<source>Do you want to add %1 as a friend ?</source>
|
||||
<translation type="vanished">Хотите добавить %1 в друзья?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/toxuri.cpp" line="82"/>
|
||||
<source>Do you want to add %1 as a friend?</source>
|
||||
<translation>Хотите добавить %1 в друзья?</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -1339,160 +1451,160 @@ It will be installed when qTox restarts.</source>
|
|||
<context>
|
||||
<name>Widget</name>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="75"/>
|
||||
<location filename="../src/widget/widget.cpp" line="92"/>
|
||||
<source>Online</source>
|
||||
<translation>В сети</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="78"/>
|
||||
<location filename="../src/widget/widget.cpp" line="95"/>
|
||||
<source>Away</source>
|
||||
<translation>Отошёл</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="81"/>
|
||||
<location filename="../src/widget/widget.cpp" line="98"/>
|
||||
<source>Busy</source>
|
||||
<translation>Занят</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="84"/>
|
||||
<location filename="../src/widget/widget.cpp" line="101"/>
|
||||
<source>&Quit</source>
|
||||
<translation>В&ыход</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="87"/>
|
||||
<location filename="../src/widget/widget.cpp" line="104"/>
|
||||
<source>Change status to:</source>
|
||||
<translation>Сменить статус на:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="161"/>
|
||||
<location filename="../src/widget/widget.cpp" line="174"/>
|
||||
<source>Online</source>
|
||||
<comment>Button to set your status to 'Online'</comment>
|
||||
<translation>В сети</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="163"/>
|
||||
<location filename="../src/widget/widget.cpp" line="176"/>
|
||||
<source>Away</source>
|
||||
<comment>Button to set your status to 'Away'</comment>
|
||||
<translatorcomment>Вероятно, это не столь долгое путешествие</translatorcomment>
|
||||
<translation>Отошёл</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="165"/>
|
||||
<location filename="../src/widget/widget.cpp" line="178"/>
|
||||
<source>Busy</source>
|
||||
<comment>Button to set your status to 'Busy'</comment>
|
||||
<translation>Занят</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="397"/>
|
||||
<location filename="../src/widget/widget.cpp" line="430"/>
|
||||
<source>Choose a profile</source>
|
||||
<translation>Выберите профиль</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="398"/>
|
||||
<location filename="../src/widget/widget.cpp" line="431"/>
|
||||
<source>Please choose which identity to use</source>
|
||||
<translation>Выберите личность, которую хотите использовать</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="419"/>
|
||||
<location filename="../src/widget/widget.cpp" line="452"/>
|
||||
<source>Choose a profile picture</source>
|
||||
<translation>Выбрать картинку для профиля</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="426"/>
|
||||
<location filename="../src/widget/widget.cpp" line="433"/>
|
||||
<location filename="../src/widget/widget.cpp" line="454"/>
|
||||
<location filename="../src/widget/widget.cpp" line="459"/>
|
||||
<location filename="../src/widget/widget.cpp" line="466"/>
|
||||
<location filename="../src/widget/widget.cpp" line="487"/>
|
||||
<source>Error</source>
|
||||
<translation>Ошибка</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="426"/>
|
||||
<location filename="../src/widget/widget.cpp" line="459"/>
|
||||
<source>Unable to open this file</source>
|
||||
<translation>Невозможно открыть файл</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="433"/>
|
||||
<location filename="../src/widget/widget.cpp" line="466"/>
|
||||
<source>Unable to read this image</source>
|
||||
<translation>Невозможно прочесть это изображение</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="454"/>
|
||||
<location filename="../src/widget/widget.cpp" line="487"/>
|
||||
<source>This image is too big</source>
|
||||
<translation>Это изображение слишком большое</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="481"/>
|
||||
<location filename="../src/widget/widget.cpp" line="527"/>
|
||||
<source>Toxcore failed to start, the application will terminate after you close this message.</source>
|
||||
<translation>Не удалось запустить toxcore, приложение будет завершено после того как вы закроете это сообщение.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="490"/>
|
||||
<location filename="../src/widget/widget.cpp" line="536"/>
|
||||
<source>toxcore failed to start with your proxy settings. qTox cannot run; please modify your settings and restart.</source>
|
||||
<comment>popup text</comment>
|
||||
<translation>Не удалось запустить toxcore с вашими настройками прокси, qTox не может работать; измените ваши настройки и перезапустите его.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="530"/>
|
||||
<location filename="../src/widget/widget.cpp" line="575"/>
|
||||
<source>Add friend</source>
|
||||
<translation>Добавить друга</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="542"/>
|
||||
<location filename="../src/widget/widget.cpp" line="587"/>
|
||||
<source>File transfers</source>
|
||||
<translation>Передачи файлов</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="567"/>
|
||||
<location filename="../src/widget/widget.cpp" line="615"/>
|
||||
<source>Settings</source>
|
||||
<translation>Настройки</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="666"/>
|
||||
<location filename="../src/widget/widget.cpp" line="715"/>
|
||||
<source>Couldn't request friendship</source>
|
||||
<translation type="unfinished">Не удалось запросить добавление в друзья</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="694"/>
|
||||
<location filename="../src/widget/widget.cpp" line="743"/>
|
||||
<source>away</source>
|
||||
<comment>contact status</comment>
|
||||
<translation>отсутствует</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="696"/>
|
||||
<location filename="../src/widget/widget.cpp" line="745"/>
|
||||
<source>busy</source>
|
||||
<comment>contact status</comment>
|
||||
<translation>занят</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="698"/>
|
||||
<location filename="../src/widget/widget.cpp" line="747"/>
|
||||
<source>offline</source>
|
||||
<comment>contact status</comment>
|
||||
<translation>офлайн</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="700"/>
|
||||
<location filename="../src/widget/widget.cpp" line="749"/>
|
||||
<source>online</source>
|
||||
<comment>contact status</comment>
|
||||
<translation>в сети</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="703"/>
|
||||
<location filename="../src/widget/widget.cpp" line="752"/>
|
||||
<source>%1 is now %2</source>
|
||||
<comment>e.g. "Dubslow is now online"</comment>
|
||||
<translation>%1 сейчас %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="937"/>
|
||||
<location filename="../src/widget/widget.cpp" line="989"/>
|
||||
<source><Unknown></source>
|
||||
<comment>Placeholder when we don't know someone's name in a group chat</comment>
|
||||
<translation><Неизвестный></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="960"/>
|
||||
<location filename="../src/widget/widget.cpp" line="1014"/>
|
||||
<source>%1 has set the title to %2</source>
|
||||
<translation>%1 сменил заголовок на %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/widget/widget.cpp" line="1109"/>
|
||||
<location filename="../src/widget/widget.cpp" line="1165"/>
|
||||
<source>Message failed to send</source>
|
||||
<translation>Не удалось отправить сообщение</translation>
|
||||
</message>
|
||||
|
|
422
translations/uk.ts
vendored
|
@ -1,3 +1,9 @@
|
|||
QLineEdit {
|
||||
color: @black;
|
||||
background: white;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
#nameLabel {
|
||||
color: @black;
|
||||
font: @mediumBold;
|
||||
|
|
|
@ -34,7 +34,7 @@ div.date_me {
|
|||
}
|
||||
|
||||
span.quote {
|
||||
color: #6bc260;
|
||||
color: #279419;
|
||||
}
|
||||
|
||||
div.green {
|
||||
|
@ -87,3 +87,7 @@ div.button {
|
|||
margin-left: 0px;
|
||||
color: @white;
|
||||
}
|
||||
|
||||
a {
|
||||
color: blue;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ QPushButton#green
|
|||
background-repeat: none;
|
||||
border: none;
|
||||
width: 25px;
|
||||
height: 20px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
QPushButton#green:hover
|
||||
|
@ -20,7 +20,7 @@ QPushButton#red
|
|||
background-repeat: none;
|
||||
border: none;
|
||||
width: 25px;
|
||||
height: 20px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
QPushButton:focus {
|
||||
|
|
Before Width: | Height: | Size: 637 B After Width: | Height: | Size: 624 B |
Before Width: | Height: | Size: 597 B After Width: | Height: | Size: 590 B |
Before Width: | Height: | Size: 629 B After Width: | Height: | Size: 617 B |