diff --git a/INSTALL.md b/INSTALL.md
index 63cefe8a1..b03f17c7e 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -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 | |
@@ -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
diff --git a/README.md b/README.md
index 26bd66749..2c55936ed 100644
--- a/README.md
+++ b/README.md
@@ -37,6 +37,6 @@ This client runs on Windows, Linux and Mac natively.
##Developer overview:
-[GitStats](http://207.12.89.155/index.html)
+[GitStats](http://104.219.184.93/index.html)
[Mac & Linux jenkins](https://jenkins.libtoxcore.so/user/tux3/my-views/view/qTox/)
-[Windows jenkins](http://207.12.89.155:8080)
+[Windows jenkins](http://104.219.184.93:8080)
diff --git a/bootstrap.sh b/bootstrap.sh
index 3188d9ecc..d705a02c0 100755
--- a/bootstrap.sh
+++ b/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
diff --git a/img/taskbar/taskbar_busy.png b/img/taskbar/dark/taskbar_busy.png
similarity index 100%
rename from img/taskbar/taskbar_busy.png
rename to img/taskbar/dark/taskbar_busy.png
diff --git a/img/taskbar/taskbar_busy_2x.png b/img/taskbar/dark/taskbar_busy_2x.png
similarity index 100%
rename from img/taskbar/taskbar_busy_2x.png
rename to img/taskbar/dark/taskbar_busy_2x.png
diff --git a/img/taskbar/taskbar_idle.png b/img/taskbar/dark/taskbar_idle.png
similarity index 100%
rename from img/taskbar/taskbar_idle.png
rename to img/taskbar/dark/taskbar_idle.png
diff --git a/img/taskbar/taskbar_idle_2x.png b/img/taskbar/dark/taskbar_idle_2x.png
similarity index 100%
rename from img/taskbar/taskbar_idle_2x.png
rename to img/taskbar/dark/taskbar_idle_2x.png
diff --git a/img/taskbar/taskbar_invisible.png b/img/taskbar/dark/taskbar_invisible.png
similarity index 100%
rename from img/taskbar/taskbar_invisible.png
rename to img/taskbar/dark/taskbar_invisible.png
diff --git a/img/taskbar/taskbar_invisible_2x.png b/img/taskbar/dark/taskbar_invisible_2x.png
similarity index 100%
rename from img/taskbar/taskbar_invisible_2x.png
rename to img/taskbar/dark/taskbar_invisible_2x.png
diff --git a/img/taskbar/taskbar_offline.png b/img/taskbar/dark/taskbar_offline.png
similarity index 100%
rename from img/taskbar/taskbar_offline.png
rename to img/taskbar/dark/taskbar_offline.png
diff --git a/img/taskbar/taskbar_offline_2x.png b/img/taskbar/dark/taskbar_offline_2x.png
similarity index 100%
rename from img/taskbar/taskbar_offline_2x.png
rename to img/taskbar/dark/taskbar_offline_2x.png
diff --git a/img/taskbar/taskbar_online.png b/img/taskbar/dark/taskbar_online.png
similarity index 100%
rename from img/taskbar/taskbar_online.png
rename to img/taskbar/dark/taskbar_online.png
diff --git a/img/taskbar/taskbar_online_2x.png b/img/taskbar/dark/taskbar_online_2x.png
similarity index 100%
rename from img/taskbar/taskbar_online_2x.png
rename to img/taskbar/dark/taskbar_online_2x.png
diff --git a/img/taskbar/light/taskbar_busy.png b/img/taskbar/light/taskbar_busy.png
new file mode 100644
index 000000000..6408db92a
Binary files /dev/null and b/img/taskbar/light/taskbar_busy.png differ
diff --git a/img/taskbar/light/taskbar_busy_2x.png b/img/taskbar/light/taskbar_busy_2x.png
new file mode 100644
index 000000000..248e05860
Binary files /dev/null and b/img/taskbar/light/taskbar_busy_2x.png differ
diff --git a/img/taskbar/light/taskbar_idle.png b/img/taskbar/light/taskbar_idle.png
new file mode 100644
index 000000000..fae60333e
Binary files /dev/null and b/img/taskbar/light/taskbar_idle.png differ
diff --git a/img/taskbar/light/taskbar_idle_2x.png b/img/taskbar/light/taskbar_idle_2x.png
new file mode 100644
index 000000000..93b33eba4
Binary files /dev/null and b/img/taskbar/light/taskbar_idle_2x.png differ
diff --git a/img/taskbar/light/taskbar_invisible.png b/img/taskbar/light/taskbar_invisible.png
new file mode 100644
index 000000000..cc45ab1f4
Binary files /dev/null and b/img/taskbar/light/taskbar_invisible.png differ
diff --git a/img/taskbar/light/taskbar_invisible_2x.png b/img/taskbar/light/taskbar_invisible_2x.png
new file mode 100644
index 000000000..19a736b3b
Binary files /dev/null and b/img/taskbar/light/taskbar_invisible_2x.png differ
diff --git a/img/taskbar/light/taskbar_offline.png b/img/taskbar/light/taskbar_offline.png
new file mode 100644
index 000000000..61c18265e
Binary files /dev/null and b/img/taskbar/light/taskbar_offline.png differ
diff --git a/img/taskbar/light/taskbar_offline_2x.png b/img/taskbar/light/taskbar_offline_2x.png
new file mode 100644
index 000000000..db79070bb
Binary files /dev/null and b/img/taskbar/light/taskbar_offline_2x.png differ
diff --git a/img/taskbar/light/taskbar_online.png b/img/taskbar/light/taskbar_online.png
new file mode 100644
index 000000000..007f0d1c9
Binary files /dev/null and b/img/taskbar/light/taskbar_online.png differ
diff --git a/img/taskbar/light/taskbar_online_2x.png b/img/taskbar/light/taskbar_online_2x.png
new file mode 100644
index 000000000..247e2b217
Binary files /dev/null and b/img/taskbar/light/taskbar_online_2x.png differ
diff --git a/install_libfilteraudio.sh b/install_libfilteraudio.sh
new file mode 100755
index 000000000..010bcbbac
--- /dev/null
+++ b/install_libfilteraudio.sh
@@ -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."
diff --git a/osx/updater.go b/osx/updater.go
deleted file mode 100644
index 45232536f..000000000
--- a/osx/updater.go
+++ /dev/null
@@ -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()
-}
diff --git a/osx/updater/.gitignore b/osx/updater/.gitignore
new file mode 100644
index 000000000..836562412
--- /dev/null
+++ b/osx/updater/.gitignore
@@ -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
diff --git a/osx/updater/README.md b/osx/updater/README.md
new file mode 100644
index 000000000..66d65555f
--- /dev/null
+++ b/osx/updater/README.md
@@ -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).)
diff --git a/osx/updater/qtox_sudo.m b/osx/updater/qtox_sudo.m
new file mode 100644
index 000000000..f9de6bcc0
--- /dev/null
+++ b/osx/updater/qtox_sudo.m
@@ -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 .
+//
+
+#import
+
+#include
+#include
+#include
+#include
+
+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;
+}
diff --git a/osx/updater/updater.go b/osx/updater/updater.go
new file mode 100644
index 000000000..ae7b898d6
--- /dev/null
+++ b/osx/updater/updater.go
@@ -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")
+ }
+
+ }
+}
diff --git a/qtox.pro b/qtox.pro
index cbd4f3dc1..2bac68cec 100644
--- a/qtox.pro
+++ b/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 \
diff --git a/res.qrc b/res.qrc
index 40b6d28f2..a62fa5697 100644
--- a/res.qrc
+++ b/res.qrc
@@ -37,10 +37,14 @@
img/status/dot_online.pngimg/status/dot_online_2x.pngimg/status/dot_online_notification.png
- img/taskbar/taskbar_online_2x.png
- img/taskbar/taskbar_idle_2x.png
- img/taskbar/taskbar_busy_2x.png
- img/taskbar/taskbar_offline_2x.png
+ img/taskbar/dark/taskbar_online_2x.png
+ img/taskbar/dark/taskbar_idle_2x.png
+ img/taskbar/dark/taskbar_busy_2x.png
+ img/taskbar/dark/taskbar_offline_2x.png
+ img/taskbar/light/taskbar_online_2x.png
+ img/taskbar/light/taskbar_idle_2x.png
+ img/taskbar/light/taskbar_busy_2x.png
+ img/taskbar/light/taskbar_offline_2x.pngimg/transfer.pngsmileys/cylgom/angel.pngsmileys/cylgom/angry.png
@@ -120,9 +124,11 @@
translations/fi.qmtranslations/fr.qmtranslations/it.qm
+ translations/lt.qmtranslations/mannol.qmtranslations/pirate.qmtranslations/pl.qm
+ translations/pt.qmtranslations/ru.qmtranslations/sv.qmtranslations/uk.qm
diff --git a/res/settings.ini b/res/settings.ini
index e335c7c8d..46d3cc207 100644
--- a/res/settings.ini
+++ b/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
diff --git a/src/audio.cpp b/src/audio.cpp
index a394e72d4..64e0b0961 100644
--- a/src/audio.cpp
+++ b/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
#include
+#include
#include
std::atomic 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: "<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;
+}
diff --git a/src/audio.h b/src/audio.h
index 9c4f87353..6fb8e7107 100644
--- a/src/audio.h
+++ b/src/audio.h
@@ -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 userCount;
+ static ALCdevice* alOutDev, *alInDev;
+ static QMutex* audioInLock, *audioOutLock;
};
#endif // AUDIO_H
diff --git a/src/audiofilterer.cpp b/src/audiofilterer.cpp
new file mode 100644
index 000000000..2253a6f60
--- /dev/null
+++ b/src/audiofilterer.cpp
@@ -0,0 +1,53 @@
+/*
+ Copyright (C) 2014 by Project Tox
+
+ This file is part of qTox, a Qt-based graphical interface for Tox.
+
+ This program is libre software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ See the COPYING file for more details.
+*/
+
+
+#ifdef QTOX_FILTER_AUDIO
+
+#include "audiofilterer.h"
+extern "C"{
+#include
+}
+
+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
diff --git a/src/audiofilterer.h b/src/audiofilterer.h
new file mode 100644
index 000000000..3a61d4e9f
--- /dev/null
+++ b/src/audiofilterer.h
@@ -0,0 +1,41 @@
+/*
+ Copyright (C) 2014 by Project Tox
+
+ This file is part of qTox, a Qt-based graphical interface for Tox.
+
+ This program is libre software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ See the COPYING file for more details.
+*/
+
+#ifdef QTOX_FILTER_AUDIO
+#ifndef AUDIOFILTERER_H
+#define AUDIOFILTERER_H
+#include
+
+#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
diff --git a/src/autoupdate.cpp b/src/autoupdate.cpp
index 8c2a2ef02..4d6dbb87e 100644
--- a/src/autoupdate.cpp
+++ b/src/autoupdate.cpp
@@ -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 newFlist = parseFlist(newFlistData);
QList diff = genUpdateDiff(newFlist);
+ if (abortFlag)
+ return false;
+
qDebug() << "AutoUpdater: Need to update "< updateFlist = parseFlist(updateFlistData);
QList 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;
+}
diff --git a/src/autoupdate.h b/src/autoupdate.h
index 4462db105..3937e3b20 100644
--- a/src/autoupdate.h
+++ b/src/autoupdate.h
@@ -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
diff --git a/src/core.cpp b/src/core.cpp
index 05ce62261..cfdfa422f 100644
--- a/src/core.cpp
+++ b/src/core.cpp
@@ -49,6 +49,8 @@ QList Core::fileRecvQueue;
QHash 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 cMessages = splitMessage(message);
+ QList 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 cMessages = splitMessage(message);
+ QList 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 Core::splitMessage(const QString &message)
+QList Core::splitMessage(const QString &message, int maxLen)
{
QList 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 {
diff --git a/src/core.h b/src/core.h
index 2f323bca2..5f55a73cf 100644
--- a/src/core.h
+++ b/src/core.h
@@ -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 splitMessage(const QString &message);
+ static QList splitMessage(const QString &message, int maxLen);
QString getPeerName(const ToxID& id) const;
@@ -283,6 +286,9 @@ private:
int dhtServerId;
static QList fileSendQueue, fileRecvQueue;
static ToxCall calls[TOXAV_MAX_CALLS];
+#ifdef QTOX_FILTER_AUDIO
+ static AudioFilterer * filterer[TOXAV_MAX_CALLS];
+#endif
static QHash groupCalls; // Maps group IDs to ToxGroupCalls
QMutex fileSendMutex, messageSendMutex;
bool ready;
diff --git a/src/coreav.cpp b/src/coreav.cpp
index a00d54ae6..b26be579c 100644
--- a/src/coreav.cpp
+++ b/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
#include
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)->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);
-
-// int friendId = toxav_get_peer_id(toxav, call_index, 0);
-// if (friendId < 0)
-// {
-// qWarning() << "Core: Received invalid AV starting";
-// return;
-// }
-
-// ToxAvCSettings* transSettings = new ToxAvCSettings;
-// int err = toxav_get_peer_csettings(toxav, call_index, 0, transSettings);
-// if (err != ErrorNone)
-// {
-// qWarning() << "Core::onAvStarting: error getting call type";
-// delete transSettings;
-// return;
-// }
-
-// if (transSettings->call_type == TypeVideo)
-// {
-// qDebug() << QString("Core: AV starting from %1 with video").arg(friendId);
-// prepareCall(friendId, call_index, toxav, true);
-// emit static_cast(core)->avStarting(friendId, call_index, true);
-// }
-// else
-// {
-// qDebug() << QString("Core: AV starting from %1 without video").arg(friendId);
-// prepareCall(friendId, call_index, toxav, false);
-// emit static_cast(core)->avStarting(friendId, call_index, false);
-// }
-
-// delete transSettings;
-//}
-
-//void Core::onAvEnding(void* _toxav, int32_t call_index, void* core)
-//{
-// ToxAv* toxav = static_cast(_toxav);
-
-// int friendId = toxav_get_peer_id(toxav, call_index, 0);
-// if (friendId < 0)
-// {
-// qWarning() << "Core: Received invalid AV ending";
-// return;
-// }
-// qDebug() << QString("Core: AV ending from %1").arg(friendId);
-
-// cleanupCall(call_index);
-
-// emit static_cast(core)->avEnding(friendId, call_index);
-//}
-
void Core::onAvRequestTimeout(void* _toxav, int32_t call_index, void* core)
{
ToxAv* toxav = static_cast(_toxav);
@@ -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 "<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";
diff --git a/src/group.cpp b/src/group.cpp
index 6a5ff4d8f..a75d933a2 100644
--- a/src/group.cpp
+++ b/src/group.cpp
@@ -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)
diff --git a/src/main.cpp b/src/main.cpp
index 3ecb63d1c..ef378bfbc 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -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);
diff --git a/src/mainwindow.ui b/src/mainwindow.ui
index 221ef052d..ed58ca986 100644
--- a/src/mainwindow.ui
+++ b/src/mainwindow.ui
@@ -1034,7 +1034,7 @@ QSplitter:handle{
00284
- 401
+ 399
@@ -1665,7 +1665,7 @@ QSplitter:handle{
0
- 57
+ 0
@@ -1775,7 +1775,7 @@ QSplitter:handle{
00775
- 19
+ 21
diff --git a/src/misc/settings.cpp b/src/misc/settings.cpp
index 3f1635028..87fab140d 100644
--- a/src/misc/settings.cpp
+++ b/src/misc/settings.cpp
@@ -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(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(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(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;
diff --git a/src/misc/settings.h b/src/misc/settings.h
index 34d495888..3c19f5717 100644
--- a/src/misc/settings.h
+++ b/src/misc/settings.h
@@ -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
{
diff --git a/src/misc/smileypack.cpp b/src/misc/smileypack.cpp
index 1ec70f954..c640fffb4 100644
--- a/src/misc/smileypack.cpp
+++ b/src/misc/smileypack.cpp
@@ -69,9 +69,9 @@ QList > SmileyPack::listSmileyPacks(const QStringList &p
if (relPath.leftRef(2) == "..")
{
- if(!smileyPacks.contains(QPair(packageName, absPath)))
+ if (!smileyPacks.contains(QPair(packageName, absPath)))
smileyPacks << QPair(packageName, absPath);
- else if(!smileyPacks.contains(QPair(packageName, relPath)))
+ else if (!smileyPacks.contains(QPair(packageName, relPath)))
smileyPacks << QPair(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);
}
diff --git a/src/platform/timer_win.cpp b/src/platform/timer_win.cpp
index e860a5ac6..31542f76f 100644
--- a/src/platform/timer_win.cpp
+++ b/src/platform/timer_win.cpp
@@ -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;
}
diff --git a/src/platform/timer_x11.cpp b/src/platform/timer_x11.cpp
index 5c9ac1b20..263a3b9b6 100644
--- a/src/platform/timer_x11.cpp
+++ b/src/platform/timer_x11.cpp
@@ -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;
diff --git a/src/toxdns.cpp b/src/toxdns.cpp
index 1a5e3b0c5..5afdc73a0 100644
--- a/src/toxdns.cpp
+++ b/src/toxdns.cpp
@@ -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
diff --git a/src/toxdns.h b/src/toxdns.h
index a7a644041..91b907d5a 100644
--- a/src/toxdns.h
+++ b/src/toxdns.h
@@ -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
{
diff --git a/src/video/cameraworker.cpp b/src/video/cameraworker.cpp
index 8671d6568..da98e58f4 100644
--- a/src/video/cameraworker.cpp
+++ b/src/video/cameraworker.cpp
@@ -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;
diff --git a/src/widget/chatareawidget.cpp b/src/widget/chatareawidget.cpp
index 22886ba8c..aeb138014 100644
--- a/src/widget/chatareawidget.cpp
+++ b/src/widget/chatareawidget.cpp
@@ -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);
diff --git a/src/widget/form/addfriendform.cpp b/src/widget/form/addfriendform.cpp
index e0623efa7..efacf17e8 100644
--- a/src/widget/form/addfriendform.cpp
+++ b/src/widget/form/addfriendform.cpp
@@ -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);
diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp
index 50b455289..b39126be6 100644
--- a/src/widget/form/chatform.cpp
+++ b/src/widget/form/chatform.cpp
@@ -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(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 splittedMsg = Core::splitMessage(msg);
+ QList 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();
diff --git a/src/widget/form/chatform.h b/src/widget/form/chatform.h
index 6f6505a8b..a86cf7f81 100644
--- a/src/widget/form/chatform.h
+++ b/src/widget/form/chatform.h
@@ -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 ftransWidgets;
void startCounter();
@@ -107,6 +110,7 @@ private:
QString secondsToDHMS(quint32 duration);
QHash receipts;
QMap undeliveredMsgs;
+ bool isTyping;
};
#endif // CHATFORM_H
diff --git a/src/widget/form/genericchatform.cpp b/src/widget/form/genericchatform.cpp
index 176e3c876..411af8350 100644
--- a/src/widget/form/genericchatform.cpp
+++ b/src/widget/form/genericchatform.cpp
@@ -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)
diff --git a/src/widget/form/loadhistorydialog.cpp b/src/widget/form/loadhistorydialog.cpp
index 3d7e36535..33c33bcc5 100644
--- a/src/widget/form/loadhistorydialog.cpp
+++ b/src/widget/form/loadhistorydialog.cpp
@@ -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;
}
diff --git a/src/widget/form/settings/avform.cpp b/src/widget/form/settings/avform.cpp
index a506b287a..31f9b6dd9 100644
--- a/src/widget/form/settings/avform.cpp
+++ b/src/widget/form/settings/avform.cpp
@@ -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);
+}
diff --git a/src/widget/form/settings/avform.h b/src/widget/form/settings/avform.h
index 2d1e873ad..64b34d410 100644
--- a/src/widget/form/settings/avform.h
+++ b/src/widget/form/settings/avform.h
@@ -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);
diff --git a/src/widget/form/settings/avsettings.ui b/src/widget/form/settings/avsettings.ui
index f7e1afc8d..e46c7d43f 100644
--- a/src/widget/form/settings/avsettings.ui
+++ b/src/widget/form/settings/avsettings.ui
@@ -30,8 +30,8 @@
00
- 810
- 496
+ 808
+ 618
@@ -96,6 +96,13 @@
+
+
+
+ Filter audio
+
+
+
diff --git a/src/widget/form/settings/generalform.cpp b/src/widget/form/settings/generalform.cpp
index 69b9cb88b..f70704387 100644
--- a/src/widget/form/settings/generalform.cpp
+++ b/src/widget/form/settings/generalform.cpp
@@ -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(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;
diff --git a/src/widget/form/settings/generalform.h b/src/widget/form/settings/generalform.h
index bd711cfa9..40739b616 100644
--- a/src/widget/form/settings/generalform.h
+++ b/src/widget/form/settings/generalform.h
@@ -37,6 +37,7 @@ private slots:
void onSetShowSystemTray();
void onSetAutostartInTray();
void onSetCloseToTray();
+ void onSetLightTrayIcon();
void onSmileyBrowserIndexChanged(int index);
void onUDPUpdated();
void onProxyAddrEdited();
diff --git a/src/widget/form/settings/generalsettings.ui b/src/widget/form/settings/generalsettings.ui
index a52aa1ffc..dd30309c0 100644
--- a/src/widget/form/settings/generalsettings.ui
+++ b/src/widget/form/settings/generalsettings.ui
@@ -38,12 +38,12 @@
0
- 0
- 509
- 849
+ -173
+ 511
+ 797
-
+ 9
@@ -109,7 +109,7 @@
-
+
@@ -152,6 +152,13 @@
+
+
+
+ Light icon
+
+
+
@@ -216,6 +223,9 @@
Set to 0 to disable
+
+ true
+ minutes
@@ -225,9 +235,6 @@
2147483647
-
- true
-
@@ -294,6 +301,9 @@
+
+ QFormLayout::AllNonFixedFieldsGrow
+ 0
@@ -317,23 +327,6 @@
-
-
-
- Style
-
-
-
-
-
-
-
- 0
- 0
-
-
-
-
@@ -391,6 +384,23 @@
+
+
+
+ Style
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+
@@ -462,7 +472,7 @@
-
+ Connection Settings
@@ -492,11 +502,40 @@
-
-
- Use proxy (SOCKS5)
-
-
+
+
+
+
+ Proxy type
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+
+ None
+
+
+
+
+ SOCKS5
+
+
+
+
+ HTTP
+
+
+
+
+
diff --git a/src/widget/form/settings/privacysettings.ui b/src/widget/form/settings/privacysettings.ui
index 84b4aecda..72262c327 100644
--- a/src/widget/form/settings/privacysettings.ui
+++ b/src/widget/form/settings/privacysettings.ui
@@ -43,11 +43,11 @@
-
- false
+
+
- Typing Notification
+ Send Typing Notifications
diff --git a/src/widget/form/tabcompleter.cpp b/src/widget/form/tabcompleter.cpp
index 73d3ffeef..2fbaa48c7 100644
--- a/src/widget/form/tabcompleter.cpp
+++ b/src/widget/form/tabcompleter.cpp
@@ -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;
diff --git a/src/widget/friendlistwidget.cpp b/src/widget/friendlistwidget.cpp
index 176850e82..667143b3d 100644
--- a/src/widget/friendlistwidget.cpp
+++ b/src/widget/friendlistwidget.cpp
@@ -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(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(s));
if (res != layouts.end())
@@ -61,8 +61,11 @@ QLayout* FriendListWidget::getFriendLayout(Status s)
return layouts[static_cast(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);
}
diff --git a/src/widget/friendlistwidget.h b/src/widget/friendlistwidget.h
index ec44ba717..1dbddd45c 100644
--- a/src/widget/friendlistwidget.h
+++ b/src/widget/friendlistwidget.h
@@ -21,7 +21,7 @@
#include
#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 layouts;
- QLayout *groupLayout;
+ QHash layouts;
+ QVBoxLayout *groupLayout;
QGridLayout *mainLayout;
};
diff --git a/src/widget/maskablepixmapwidget.cpp b/src/widget/maskablepixmapwidget.cpp
index f0015d6d0..5f8d2ea99 100644
--- a/src/widget/maskablepixmapwidget.cpp
+++ b/src/widget/maskablepixmapwidget.cpp
@@ -130,6 +130,6 @@ void MaskablePixmapWidget::paintEvent(QPaintEvent *)
void MaskablePixmapWidget::mousePressEvent(QMouseEvent*)
{
- if(clickable)
+ if (clickable)
emit clicked();
}
diff --git a/src/widget/tool/chatactions/messageaction.cpp b/src/widget/tool/chatactions/messageaction.cpp
index 06f27ef1d..93b8271ee 100644
--- a/src/widget/tool/chatactions/messageaction.cpp
+++ b/src/widget/tool/chatactions/messageaction.cpp
@@ -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);
diff --git a/src/widget/widget.cpp b/src/widget/widget.cpp
index dcf6c67a4..1ee219bb1 100644
--- a/src/widget/widget.cpp
+++ b/src/widget/widget.cpp
@@ -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 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);
}
diff --git a/src/widget/widget.h b/src/widget/widget.h
index dd6bb3d94..ad6ad8b04 100644
--- a/src/widget/widget.h
+++ b/src/widget/widget.h
@@ -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);
diff --git a/translations/de.ts b/translations/de.ts
index 6636bf5de..49de50342 100644
--- a/translations/de.ts
+++ b/translations/de.ts
@@ -4,7 +4,7 @@
AVForm
-
+ Audio/VideoAudio/Video
@@ -42,32 +42,37 @@
Erneut nach Audiogeräten suchen
-
+
+ Filter audio
+ Audiofilter
+
+
+ Video SettingsVideo Einstellungen
-
+ ResolutionAuflösung
-
+ HueFarbton
-
+ BrightnessHelligkeit
-
+ SaturationSättigung
-
+ ContrastKontrast
@@ -117,8 +122,8 @@
qTox needs to use the Tox DNS, but can't do it through a proxy.
-Ignore the proxy and connect to the Internet directly ?
- qTox muss Tox DNS nutzen, dies klappt allerdings nicht über einen Proxy.
+Ignore the proxy and connect to the Internet directly?
+ qTox muss das Tox DNS nutzen, dies klappt allerdings nicht über einen Proxy.
Soll der Proxy ignoriert und eine direkte Internetverbindung genutzt werden?
@@ -127,31 +132,6 @@ Soll der Proxy ignoriert und eine direkte Internetverbindung genutzt werden?DNS error
Tox ID existiert nicht
-
- Error while looking up DNS
- The DNS gives the Tox ID associated to toxme.se addresses
- Fehler beim Auflösen des DNS
-
-
- Unexpected number of text records
- Error with the DNS
- Unererwartete Anzahl von Texteinträgen
-
-
- Unexpected number of values in text record
- Error with the DNS
- Unerwartete Anzahl von Werten innerhalb des Texteintrages
-
-
- The DNS lookup does not contain any Tox ID
- Error with the DNS
- Der DNS Eintrag enthält keine Tox ID
-
-
- The DNS lookup does not contain a valid Tox ID
- Error with the DNS
- Der DNS Eintrag enthält keine gültige Tox ID
- AdvancedForm
@@ -201,18 +181,7 @@ Soll der Proxy ignoriert und eine direkte Internetverbindung genutzt werden?
<html><head/><body><p><a href="http://www.sqlite.org/pragma.html#pragma_synchronous"><span style=" text-decoration: underline; color:#0000ff;">Synchronous writing to DB</span></a></p></body></html>
- Synchrones Schreiben in die DB
-
-
-
- Camera
-
- Camera eror
- Kamerafehler
-
-
- Camera format %1 not supported, can't use the camera
- Kameraformat %1 wird nicht unterstützt. Die Kamera kann nicht verwendet werden
+ <html><head/><body><p><a href="http://www.sqlite.org/pragma.html#pragma_synchronous"><span style=" text-decoration: underline; color:#0000ff;">Synchrones Schreiben in die DB</span></a></p></body></html>
@@ -223,59 +192,65 @@ Soll der Proxy ignoriert und eine direkte Internetverbindung genutzt werden?Historie laden...
-
+ Send a fileDatei versenden
-
+
+ File not read
+ Datei nicht gelesen
+
+
+
+ qTox wasn't able to open %1
+ qTox konnte %1 nicht öffnen
+
+
+ Bad IdeaSchlechte Idee
-
+ You're trying to send a special (sequential) file, that's not going to work!Sie versuchen eine spezielle (sequentielle) Datei zu senden, das funktioniert nicht!
-
+ %1 is calling%1 ruft an
-
+ %1 stopped calling%1 hat den Anruf beendet
-
+ Calling to %1Rufe %1 an
-
+ Call rejectedAnruf abgewiesen
- Failed to send file
- Fehler beim Senden der Datei
+ Failed to send file "%1"
+ Senden der Datei "%1" fehlgeschlagen
-
+ Call with %1 ended. %2Anruf zu %1 beendet. %2
-
+ Call duration: Anrufdauer:
-
- Save chat log
- Chatverlauf speichern
- ChatTextEdit
@@ -285,109 +260,107 @@ Soll der Proxy ignoriert und eine direkte Internetverbindung genutzt werden?Nachricht hier eingeben...
-
- CopyableElideLabel
-
- Copy
- Kopieren
-
-Core
-
+ Toxing on qToxToxen mit qTox
-
+ qTox UserqTox Benutzer
-
+ Friend is already addedFreund wurde schon hinzugefügt
-
+ Encryption errorVerschlüsselungsfehler
-
+ The .tox file is encrypted, but encryption was not checked, continuing regardless.Die .tox Datei ist verschlüsselt, aber die Verschlüsselung wurde nicht geprüft, Vorgang wird trotzdem fortgesetzt.
-
+ Tox datafile decryption passwordEntschlüsselungspasswort für Tox Datendatei
-
-
-
+
+
+ Password errorPasswortfehler
-
-
+
+ Failed to setup password.
Empty password.
- Fehler beim Setzen des Passwortes.
+ Setzen des Passwortes fehlgeschlagen.
Leeres Passwort.
-
+ Try AgainNochmal versuchen
-
+ Change profileProfil ändern
-
+ Reinit current profile
- Aktuelles Profil neu starten
+ Aktuelles Profil erneut starten
-
+ Wrong password has been enteredEs wurde ein falsches Passwort eingegeben
-
+ History Log decryption passwordPasswort zur Entschlüsselung der Historie
-
+ Encrypted logVerschlüsselte Logdatei
-
+ Your history is encrypted with different password.
Do you want to try another password?Ihre Historie wurde mit einem anderen Passwort verschlüsselt.
-Wollen Sie ein anderes probieren?
+Wollen Sie ein weiteres probieren?
-
+ Due to incorret password history will be disabled.Falsches Passwort, Historie wird deaktiviert.
-
+
+ History
+ Historie
+
+
+ NO PasswordKEIN Passwort
-
+ Will be saved without encryption!Wird ohne Verschlüsselung gespeichert!
@@ -395,37 +368,29 @@ Wollen Sie ein anderes probieren?
FileTransferInstance
-
+ Save a fileTitle of the file saving dialogDatei speichern
-
+ Location not writableTitle of permissions popupOrt schreibgeschützt
-
+ You do not have permission to write that location. Choose another, or cancel the save dialog.text of permissions popupSie haben keine Erlaubnis, die Datei in diesen Ort zu speichern. Wählen Sie einen anderen Ort oder beenden Sie den Dialog.
-
+ ETAETA
-
- FileTransfertWidget
-
- Save a file
- Title of the file saving dialog
- Datei speichern
-
-FilesForm
@@ -456,7 +421,7 @@ Wollen Sie ein anderes probieren?
Someone wants to make friends with you
- Es hat Ihnen jemand eine Freundschaftsanfrage gesendet
+ Jemand möchte Ihr Freund werden
@@ -513,19 +478,16 @@ Wollen Sie ein anderes probieren?
Wähle ein Verzeichnis für die automatische Dateiannahme
-
+ User aliasBenutzeralias
-
- Alias:
- Alias:
-
-
- Invite in group
- Menu to invite a friend in a groupchat
- In Gruppe einladen
+
+ You can also set this by clicking the chat form name.
+Alias:
+ Sie können diesen auch durch Klick auf den Namen des Chatfensters festlegen.
+Alias:
@@ -542,38 +504,30 @@ Wollen Sie ein anderes probieren?
Allgemein
-
-
+
+ None
- Keine
+ Kein
-
+ Choose an auto accept directorypopup titleWählen Sie ein Verzeichnis
-
+ Call activepopup titleAnwahl aktiviert
-
+ You can't disconnect while a call is active!popup textAbbruch während der Anwahl nicht möglich!
-
- GeneralPage
-
- Enable IPv6 (recommended)
- Text on a checkbox to enable IPv6
- IPv6 aktivieren (empfohlen)
-
-GeneralSettings
@@ -601,7 +555,7 @@ Wollen Sie ein anderes probieren?
Make Tox portable
- Mache Tox portabel
+ Macht Tox portabel
@@ -629,143 +583,154 @@ Wollen Sie ein anderes probieren?
Ins Tray minimieren
-
+
+ Light icon
+ Helles Icon
+
+
+ Show contacts' status changesZeigt Statusänderungen der Kontakte
-
+ Check for updates on startup (unstable)
- Beim Start auf Updates prüfen (nicht stabil)
+ Prüft beim Start auf Updates (nicht stabil)
-
+ Focus qTox when a message is receivedBringt qTox in den Vordergrund, wenn eine Nachricht eintrifft
-
+ Faux offline messaging
-
+ Imitiert Offline Benachrichtigung
-
+ Provided in minutesAngabe in Minuten
-
+ Auto away after (0 to disable)Automatisch abwesend nach (0 deaktiviert)
-
+ Set to 0 to disableZum Deaktivieren auf 0 setzen
-
+
+ You can set this on a per-friend basis by right clicking them.
+ autoaccept cb tooltip
+ Sie können dies durch Rechtsklick auf den jeweiligen Freund festlegen.
+
+
+ Use emoticonsEmoticons benutzen
-
+ Smiley PackText on smiley pack labelEmoticon Paket
-
+ StyleStil
-
+ Theme colorFarbe
-
+ Emoticon sizeEmoticon Größe
-
+ px Pixel
-
+ Timestamp formatZeitformat
-
+ Disabling this allows, e.g., toxing over Tor. It adds load to the Tox network however, so uncheck only when necessary.force tcp checkbox tooltip
- Wenn deaktiviert, kann z.B. über Tor getoxt werden. Dies belastet das Tox Netzwerk zusätzlich und sollte nur deaktiviert werden wenn notwendig.
+ Wenn deaktiviert kann z.B. über Tor getoxt werden. Dies belastet das Tox Netzwerk zusätzlich und sollte nur deaktiviert werden wenn notwendig.
-
+ Enable UDP (recommended)Text on checkbox to disable UDPUDP aktivieren (empfohlen)
-
+ Reconnectreconnect button
- Neu verbinden
+ Erneut verbinden
-
+ minutes Minuten
-
+ Autoaccept filesDateien automatisch annehmen
-
+ Save files inSpeichern unter
-
+ PushButtonSchaltfläche
-
+ ThemeBenutzeroberfläche
-
+ Connection SettingsVerbindungseinstellungen
-
+ Enable IPv6 (recommended)Text on a checkbox to enable IPv6IPv6 aktivieren (empfohlen)
-
+ Use proxy (SOCKS5)Proxy benutzen (SOCKS5)
-
+ AddressText on proxy addr labelAdresse
-
+ PortText on proxy port labelPort
@@ -774,53 +739,53 @@ Wollen Sie ein anderes probieren?
GenericChatForm
-
+ Send messageNachricht senden
-
+ SmileysSmileys
-
+ Send file(s)Datei(en) senden
-
+ Audio call: RED means you're on a callSprachanruf: ROT bedeutet verbunden
-
+ Video call: RED means you're on a callVideoanruf: ROT bedeutet verbunden
-
+ Toggle speakers volume: RED is OFFSchaltet den Lautsprecher ein/aus: ROT ist AUS
-
+ Toggle microphone: RED is OFFSchaltet das Mikrofon ein/aus: ROT ist AUS
-
-
+
+ Save chat logChatverlauf speichern
-
+ Clear displayed messagesAngezeigte Nachrichten ausblenden
-
+ ClearedAusgeblendet
@@ -828,45 +793,54 @@ Wollen Sie ein anderes probieren?
GroupChatForm
-
+ %1 users in chatNumber of users in chat%1 Teilnehmer im Chat
-
- <Unknown>
- <Unbekannt>
- %1 users in chat%1 Teilnehmer im Chat
-
- Save chat log
- Chatverlauf speichern
- GroupWidget
-
-
+
+ %1 users in chat%1 Teilnehmer im Chat
-
-
+
+ 0 users in chatkein Teilnehmer im Chat
-
+
+ Set title...
+ Titel festlegen...
+
+
+ Quit groupMenu to quit a groupchatGruppe verlassen
+
+
+ Group title
+ Gruppentitel
+
+
+
+ You can also set this by clicking the chat form name.
+Title:
+ Sie können diesen auch durch Klick auf den Namen des Chatfensters festlegen.
+Titel:
+ IdentityForm
@@ -920,7 +894,7 @@ Wollen Sie ein anderes probieren?
Failed to remove file
- Die Datei konnte nicht entfernt werden
+ Entfernen der Datei fehlgeschlagen
@@ -930,7 +904,7 @@ Wollen Sie ein anderes probieren?
Failed to copy file
- Die Datei konnte nicht kopiert werden
+ Kopieren der Datei fehlgeschlagen
@@ -953,68 +927,53 @@ Wollen Sie ein anderes probieren?
Deletion imminent!deletion confirmation title
- Löschen steht an!
+ Löschen steht bevor!
- Are you sure you want to delete this profile?
+ Are you sure you want to delete this profile?
+Associated friend information and chat logs will be deleted as well.deletion confirmation text
- Sind Sie sicher, dass dieses Profil gelöscht werden soll?
+ Wollen Sie dieses Profil wirklich löschen?
+Dazugehörige Informationen und Chatprotokolle werden ebenfalls gelöscht.
-
+ Import profileimport dialog titleProfil importieren
-
+ Tox save file (*.tox)import dialog filterToxdatei speichern (*.tox)
-
+ Ignoring non-Tox filepopup titleKeine Toxdatei, wird ignoriert
-
+ Warning: you've chosen a file that is not a Tox save file; ignoring.popup textWarnung: Sie haben eine Datei gewählt, die keine Toxdatei ist, wird ignoriert.
-
+ Profile already existsimport confirm titleProfil existiert bereits
-
+ A profile named "%1" already exists. Do you want to erase it?import confirm textEin Profil mit dem Namen "%1" existiert bereits. Wollen Sie es löschen?
-
- IdentityPage
-
- Name
- Username/nick
- Benutzername
-
-
- Status
- Status message
- Status
-
-
- Tox ID
- Tox ID
-
-IdentitySettings
@@ -1143,17 +1102,17 @@ Wollen Sie ein anderes probieren?
Add friends
- Freund hinzufügen
+ Freunde hinzufügenCreate a group chat
- Gruppenchat erstellen
+ Gruppenchat anlegenView completed file transfers
- Alle Dateiübertragungen anzeigen
+ Vollendete Dateiübertragungen anzeigen
@@ -1165,10 +1124,6 @@ Wollen Sie ein anderes probieren?
CloseSchließen
-
- Ctrl+Q
- Strg+Q
- NetCamView
@@ -1202,7 +1157,7 @@ Soll die alte Historiedatei gelöscht werden?
PrivacySettings
- Typing Notification
+ Send Typing NotificationsTippen anzeigen
@@ -1244,14 +1199,14 @@ Soll die alte Historiedatei gelöscht werden?
QObject
-
+ UpdateThe title of a message boxUpdate
-
- An update is available, do you want to download it now ?
+
+ An update is available, do you want to download it now?
It will be installed when qTox restarts.Ein Update steht zur Verfügung, soll es heruntergeladen werden?
Es wird beim Neustart von qTox installiert.
@@ -1261,6 +1216,16 @@ Es wird beim Neustart von qTox installiert.
Tox URI to parseTox URI parsen
+
+
+ Starts new instance and loads specified profile.
+ Startet eine neue Instanz und lädt das festgelegte Profil.
+
+
+
+ profile
+ Profil
+ Default
@@ -1327,14 +1292,6 @@ Es wird beim Neustart von qTox installiert.
Lass uns toxen!
-
- SelfCamView
-
- Tox video test
- Title of the window to test the video/webcam
- Tox Video testen
-
-SetPasswordDialog
@@ -1348,34 +1305,6 @@ Es wird beim Neustart von qTox installiert.
Passworteingabe wiederholen
-
- SettingsForm
-
- User Settings
- "Headline" of the window
- Einstellungen
-
-
- Name
- Username/nick
- Benutzername
-
-
- Status
- Status message
- Status
-
-
- Test video
- Text on a button to test the video/webcam
- Video testen
-
-
- Enable IPv6 (recommended)
- Text on a checkbox to enable IPv6
- IPv6 aktivieren (empfohlen)
-
-ToxDNS
@@ -1438,7 +1367,7 @@ Es wird beim Neustart von qTox installiert.
- Do you want to add %1 as a friend ?
+ Do you want to add %1 as a friend?Wollen Sie %1 als Freund hinzufügen?
@@ -1467,181 +1396,161 @@ Es wird beim Neustart von qTox installiert.
Widget
- Tox
- Tox
-
-
- Your name
- Ihr Name
-
-
- Your status
- Ihr Status
-
-
- Close
- Schließen
-
-
- Ctrl+Q
- Strg+Q
-
-
-
+ OnlineOnline
-
+ AwayAbwesend
-
+ BusyBeschäftigt
-
+ &Quit&Beenden
-
+ Change status to:
- Ändern Sie den Status zu:
+ Ändert den Status in:
-
+ OnlineButton to set your status to 'Online'Online
-
+ AwayButton to set your status to 'Away'Abwesend
-
+ BusyButton to set your status to 'Busy'Beschäftigt
-
+ Choose a profileWählen Sie ein Profil
-
+ Please choose which identity to useWählen Sie die Identität, die benutzt werden soll
-
+ Choose a profile picture
- Wähle ein Profilbild
+ Wählen Sie ein Profilbild
-
-
+
+ ErrorFehler
-
+ Unable to open this fileKann diese Datei nicht öffnen
-
+ Unable to read this imageKann dieses Bild nicht einlesen
-
+ This image is too bigDieses Bild ist zu groß
-
+ Toxcore failed to start, the application will terminate after you close this message.Tox startet nicht, die Anwendung wird nach Schließen dieses Fensters beendet.
-
+ toxcore failed to start with your proxy settings. qTox cannot run; please modify your settings and restart.popup text
- Tox startet mit ihren Proxy-Einstellungen nicht. qTox funktioniert nicht, ändern Sie bitte Ihre Einstellungen und starten qTox neu.
+ Tox startet nicht mit ihren Proxy-Einstellungen. qTox funktioniert nicht, ändern Sie bitte Ihre Einstellungen und starten qTox neu.
-
+ Add friendFreund hinzufügen
-
+ File transfersDateiübertragungen
-
+ SettingsEinstellungen
-
+ Couldn't request friendshipFreundschaftsanfrage fehlgeschlagen
-
+ awaycontact statusAbwesend
-
+ busycontact statusBeschäftigt
-
+ offlinecontact statusOffline
-
+ onlinecontact statusOnline
-
+ %1 is now %2e.g. "Dubslow is now online"%1 ist nun %2
-
+ <Unknown>Placeholder when we don't know someone's name in a group chat<Unbekannt>
-
+ %1 has set the title to %2%1 hat den Titel auf %2 gesetzt
-
+ Message failed to sendSenden der Nachricht fehlgeschlagen
-
\ No newline at end of file
+
diff --git a/translations/fr.ts b/translations/fr.ts
index 206cf9356..48cc108ea 100644
--- a/translations/fr.ts
+++ b/translations/fr.ts
@@ -76,13 +76,13 @@
Add Friends
- Ajouter des amis
+ Ajouter des contactsTox IDTox ID of the person you're sending a friend request to
- ID Tox
+ Tox ID
@@ -93,25 +93,25 @@
Send friend request
- Envoyer la demande d'ami
+ Envoyer la demande de contactTox me maybe?Default message in friend requests if the field is left blank. Write something appropriate!
- Je souhaiterais vous ajouter à mes contacts
+ Je souhaiterais vous ajouter à mes contacts.Please fill in a valid Tox IDTox ID of the friend you're sending a friend request to
- Merci de remplir un ID Tox valide
+ Merci d'entrer un Tox ID valideYou can't add yourself as a friend!When trying to add your own Tox ID as friend
- Vous ne pouvez pas vous ajouter vous même en temps qu'ami!
+ Vous ne pouvez pas vous ajouter vous-même !
@@ -123,19 +123,19 @@ Ignorer le proxy et se connecter directement à Internet ?
qTox needs to use the Tox DNS, but can't do it through a proxy
Ignore the proxy and connect to the Internet directly ?
- qTox as besoin d'utiliser le DNS Tox, mais ne peut pas le faire avec un proxy
+ 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 ?This Tox ID does not existDNS error
- Cet ID Tox n'existe pas
+ Ce Tox ID n'existe pasThis address does not existThe DNS gives the Tox ID associated to toxme.se addresses
- Cette addresse n'existe pas
+ Cette adresse n'existe pasError while looking up DNS
@@ -178,22 +178,22 @@ Ignorer le proxy et se connecter directement à Internet ?
Bad Idea
- Mauvaise Idée
+ Mauvaise idéeYou're trying to send a special (sequential) file, that's not going to work!
- Vous êtes en train d'essayer d'envoyer un fichier spécial (sequentiel), ça ne marchera pas!
+ Vous êtes en train d'essayer d'envoyer un fichier spécial (sequentiel), ça ne fonctionnera pas !%1 calling
- %1 appelle
+ %1 appel%1 stopped calling
- %1a arreté l'appel
+ %1 a arreté l'appel
@@ -229,7 +229,7 @@ Ignorer le proxy et se connecter directement à Internet ?
Toxing on qTox
- Toxer avec qTox
+ Je Tox sur qTox
@@ -239,7 +239,7 @@ Ignorer le proxy et se connecter directement à Internet ?
Friend is already added
- Cet ami est déjà dans cos contact
+ Ce contact est déjà dans vos contacts
@@ -249,7 +249,7 @@ Ignorer le proxy et se connecter directement à Internet ?
The .tox file is encrypted, but encryption was not checked, continuing regardless.
- Le fichier .tox est chiffré, mais l'encryption n'as pas été activée. Le problème sera ignoré.
+ Le fichier .tox est chiffré, mais le chiffrement n'a pas été activé. Le problème sera ignoré.
@@ -261,14 +261,14 @@ Ignorer le proxy et se connecter directement à Internet ?
Password error
- Mod de passe invalide
+ Mot de passe invalideFailed to setup password.
Empty password.
- Impossible de mettre ne place le mot de passe.
+ Impossible de mettre en place le mot de passe.
Le mot de passe est vide.
@@ -289,7 +289,7 @@ Le mot de passe est vide.
Wrong password has been entered
- Un mauvais mot de passe à été entré
+ Un mauvais mot de passe a été entré
@@ -316,7 +316,7 @@ Voulez-vous essayer un mot de passe différent?
Due to incorret password logging will be disabled
- À cause d'un mauvais mot de passe, l'historique sera désactivé
+ Due à l'utilisation d'un mauvais mot de passe, l'historique sera désactivé
@@ -326,7 +326,7 @@ Voulez-vous essayer un mot de passe différent?
Will be saved without encryption!
- L'historique sera sauvegardé sans être chiffré!
+ L'historique sera sauvegardé sans être chiffré !
@@ -380,12 +380,12 @@ Voulez-vous essayer un mot de passe différent?
Friend requestTitle of the window to aceept/deny a friend request
- Demande d'ami
+ Demande de contactSomeone wants to make friends with you
- Quelqu'un veut devenir votre ami
+ Quelqu'un vient de vous ajouter dans sa liste de contacts
@@ -395,7 +395,7 @@ Voulez-vous essayer un mot de passe différent?
Friend request message:
- Message de demande d'ami:
+ Message au sujet de la demande:
@@ -422,7 +422,7 @@ Voulez-vous essayer un mot de passe différent?
Copy friend IDMenu to copy the Tox ID of that friend
- Copier l'ID ami
+ Copier l'ID du contact
@@ -458,7 +458,7 @@ Voulez-vous essayer un mot de passe différent?
Disable global auto acceptcontext menu entry
- Désactiver l'acceptation automatique de fichier
+ Désactiver le téléchargement automatique de fichiers
@@ -470,7 +470,7 @@ Voulez-vous essayer un mot de passe différent?
Remove friendMenu to remove the friend from our friendlist
- Supprimer ami
+ Supprimer ce contact
@@ -502,7 +502,7 @@ Voulez-vous essayer un mot de passe différent?
You can't disconnect while a call is active!popup text
- Vous ne pouvez pas vous déconnecter avec un appel en cours!
+ Vous ne pouvez pas vous déconnecter avec un appel en cours !
@@ -520,7 +520,7 @@ Voulez-vous essayer un mot de passe différent?
The translation may not load until qTox restarts.
- La translation peut ne pas se charger jusqu'à ce que qTox redémarre.
+ La traduction peut ne pas prendre effet immédiatement. Redémarrez qTox si ce n'est pas le cas.Translation:
@@ -550,7 +550,7 @@ Voulez-vous essayer un mot de passe différent?
Minimize to tray
- Minimizer dans la barre d'état
+ Minimiser dans la barre d'état
@@ -564,7 +564,7 @@ Voulez-vous essayer un mot de passe différent?
Auto away after (0 to disable):
- Auto-absent après (0 pour désactiver):
+ Se rendre absent après (0 pour désactiver):
@@ -620,7 +620,7 @@ Voulez-vous essayer un mot de passe différent?
Reconnectreconnect button
- Reconnection
+ Se reconnecter
@@ -640,7 +640,7 @@ Voulez-vous essayer un mot de passe différent?
Focus qTox when a message is received
- Montrer qTox quand un message est reçu
+ Montrer la fênetre qTox quand un message est reçu
@@ -713,7 +713,7 @@ Voulez-vous essayer un mot de passe différent?
This allows, e.g., toxing over Tor. It adds load to the Tox network however, so use only when necessary.force tcp checkbox tooltip
- Permet par exemple d'utiliser Tox à travers Tor, mais ce n'est à utiliser que si nécessaire, car cela ralenti le réseau Tox.
+ Permet par exemple d'utiliser Tox à travers Tor, mais ce n'est à utiliser que si nécessaire car cela ralenti le réseau Tox.Disable UDP (not recommended)
@@ -748,7 +748,7 @@ Voulez-vous essayer un mot de passe différent?
Smileys
- Emoticones
+ Émoticônes
@@ -768,7 +768,7 @@ Voulez-vous essayer un mot de passe différent?
Toggle speakers volume
- Couper les haut parleurs
+ Couper les haut-parleurs
@@ -818,7 +818,7 @@ Voulez-vous essayer un mot de passe différent?
0 users in chat
- 0 personnes
+ Le groupe est vide
@@ -844,7 +844,7 @@ Voulez-vous essayer un mot de passe différent?
You can't switch profiles while a call is active!popup text
- Vous ne pouvez pas changer de profil quand un appel est en cours!
+ Vous ne pouvez pas changer de profil quand un appel est en cours !
@@ -894,7 +894,7 @@ Voulez-vous essayer un mot de passe différent?
The file you chose could not be written to.
- Le fichier que vous avez choisi n'as pas pu être écrit.
+ Le fichier que vous avez choisi n'es pas disponible en écriture.
@@ -912,7 +912,7 @@ Voulez-vous essayer un mot de passe différent?
Deletion imminent!deletion confirmation title
- Suppression imminente!
+ Suppression imminente !
@@ -936,13 +936,13 @@ Voulez-vous essayer un mot de passe différent?
Ignoring non-Tox filepopup title
- Fichier non-Tox ignoré
+ Fichier incompatible avec Tox ignoréWarning: you've chosen a file that is not a Tox save file; ignoring.popup text
- Attention: Vous avez sélectionné un fichier qui n'est pas une sauvegarde Tox: il sera ignoré.
+ Attention: Vous avez sélectionné un fichier qui n'est pas une sauvegarde Tox, il sera ignoré.
@@ -986,7 +986,7 @@ Voulez-vous essayer un mot de passe différent?
Your Tox ID (click to copy)
- Votre ID Tox (cliquez pour copier)
+ Votre Tox ID (cliquez pour copier)
@@ -1033,7 +1033,7 @@ Voulez-vous essayer un mot de passe différent?
This is useful to remain safe on public computersdelete profile button tooltip
- Util pour sécuriser sur un ordinateur public
+ Utile pour rester en sécurité sur un ordinateur public
@@ -1045,7 +1045,7 @@ Voulez-vous essayer un mot de passe différent?
New Tox IDnew profile button
- Nouvel ID Tox
+ Nouvel Tox ID
@@ -1093,12 +1093,12 @@ Voulez-vous essayer un mot de passe différent?
Add friends
- Ajouter des amis
+ Ajouter des contactsCreate a group chat
- Creer un groupe
+ Créer un groupe
@@ -1125,7 +1125,7 @@ Voulez-vous essayer un mot de passe différent?
Tox video
- Vidéo tox
+ Vidéo Tox
@@ -1145,7 +1145,7 @@ Voulez-vous essayer un mot de passe différent?
You already have history log file encrypted with different password
Do you want to delete old history file?Vous avez déjà un historique chiffré avec un autre mot de passe
-Voulez vous supprimer l'ancien historique?
+Voulez vous supprimer l'ancien historique ?
@@ -1192,7 +1192,7 @@ Voulez vous supprimer l'ancien historique?
Warning: you've chosen a file that is not a Tox save file; ignoring.popup text
- Attention: Vous avez sélectionné un fichier qui n'est pas une sauvegarde Tox: il sera ignoré.
+ Attention: Vous avez sélectionné un fichier qui n'est pas une sauvegarde Tox, il sera ignoré.
@@ -1233,12 +1233,12 @@ Voulez vous supprimer l'ancien historique?
An update is available, do you want to download it now ?
It will be installed when qTox restarts.Une mise à jour est disponible, voulez vous la télécharger maintenant ?
-Elle sera installée au prochain démarrage de qTox
+Elle sera installée au prochain démarrage de qTox.
Tox URI to parse
- URI Tox à utiliser
+ URL Tox à utiliser
@@ -1255,7 +1255,7 @@ Elle sera installée au prochain démarrage de qTox
Repeat Password
- Répetez le mot de passe
+ Retapez le mot de passe
@@ -1270,13 +1270,13 @@ Elle sera installée au prochain démarrage de qTox
This address does not existThe DNS gives the Tox ID associated to toxme.se addresses
- Cette addresse n'existe pas
+ Cette adresse n'existe pasError while looking up DNSThe DNS gives the Tox ID associated to toxme.se addresses
- Erreur en consultant le serveur DNS
+ Une erreur s'est produite en consultant le serveur DNS
@@ -1316,22 +1316,22 @@ Elle sera installée au prochain démarrage de qTox
Add a friendTitle of the window to add a friend through Tox URI
- Ajouter un ami
+ Ajouter un contactDo you want to add %1 as a friend ?
- Voulez-vous ajouter %1 à vos amis ?
+ Voulez-vous ajouter %1 à vos contacts ?User ID:
- ID utilisateur:
+ ID d'utilisateur:Friend request message:
- Message de demande d'ami:
+ Associer un message à cette demande:
@@ -1354,7 +1354,7 @@ Elle sera installée au prochain démarrage de qTox
away
- indisponnible
+ absentbusy
@@ -1368,7 +1368,7 @@ Elle sera installée au prochain démarrage de qTox
Away
- Indisponible
+ Absent
@@ -1383,7 +1383,7 @@ Elle sera installée au prochain démarrage de qTox
Change status to:
- Changer le status en:
+ Changer le status par:
@@ -1395,7 +1395,7 @@ Elle sera installée au prochain démarrage de qTox
AwayButton to set your status to 'Away'
- Indisponible
+ Absent
@@ -1443,18 +1443,18 @@ Elle sera installée au prochain démarrage de qTox
Toxcore failed to start, the application will terminate after you close this message.
- Toxcore n'as pas pu démarrer correctement, l'application va quitter quand vous fermerez ce message.
+ ToxCore n'as pas pu démarrer correctement, l'application va s'arrêter quand vous fermerez cette alerte.toxcore failed to start with your proxy settings. qTox cannot run; please modify your settings and restart.popup text
- 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.
+ 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.Add friend
- Ajouter un ami
+ Ajouter un contact
@@ -1469,13 +1469,13 @@ Elle sera installée au prochain démarrage de qTox
Couldn't request friendship
- Impossible de demander en ami
+ Impossible d'envoyer la demande de contactawaycontact status
- indisponnible
+ absent
@@ -1487,7 +1487,7 @@ Elle sera installée au prochain démarrage de qTox
offlinecontact status
- déconnecté
+ hors ligne
@@ -1510,7 +1510,7 @@ Elle sera installée au prochain démarrage de qTox
Message failed to send
- Le message n'as pas pu être envoyé
+ Le message n'as pu être envoyé
diff --git a/translations/i18n.pri b/translations/i18n.pri
index 668a89f07..d13f328e2 100644
--- a/translations/i18n.pri
+++ b/translations/i18n.pri
@@ -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) {
diff --git a/translations/it.ts b/translations/it.ts
index 87cfae823..116745236 100644
--- a/translations/it.ts
+++ b/translations/it.ts
@@ -12,12 +12,12 @@
AVSettings
-
+ Video SettingsImpostazioni Video
-
+ ResolutionRisoluzione
@@ -52,22 +52,27 @@
Cerca dispositivi audio
-
+
+ Filter audio
+ Filtra audio
+
+
+ HueColore
-
+ BrightnessLuminoistà
-
+ SaturationSaturazione
-
+ ContrastContrasto
@@ -182,62 +187,72 @@ Ignorare le impostazioni del proxy e connettersi direttamente alla rete Tox?
ChatForm
-
+ Load History...Carica log...
-
+ Send a fileInvia un file
-
+ File not readImpossibile leggere il file
-
+ qTox wasn't able to open %1qTox non è riuscito ad aprire %1
-
+ Bad IdeaPessima idea
-
+ You're trying to send a special (sequential) file, that's not going to work!Stai cercando di inviare un file speciale (sequenziale), questo non funzionerà!
-
+ %1 is calling%1 ti sta chiamando
-
+ %1 stopped calling%1 ha fermato la chiamata
-
+ Calling to %1Stai chiamando %1
-
+
+ Failed to send file "%1"
+ Invio del file "%1" fallito
+
+
+ Call with %1 ended. %2Chiamata con %1 terminata. %2
-
+ Call duration: Durata chiamata:
-
+
+ is typing...
+ sta scrivendo...
+
+
+ Call rejectedChiamata rifiutata
@@ -253,105 +268,105 @@ Ignorare le impostazioni del proxy e connettersi direttamente alla rete Tox?
Core
-
+ Toxing on qToxToxing on qTox
-
+ qTox UserqTox User
-
+ Friend is already addedQuesto contatto è già presente nella tua lista
-
+ Encryption errorErrore crittografia
-
+ The .tox file is encrypted, but encryption was not checked, continuing regardless.Il Tox datafile è criptato, ma la crittografia non è abilitata nelle impostazioni.
Continuo ignorando le impostazioni.
-
+ Tox datafile decryption passwordPassword per decriptare il Tox datafile
-
-
-
+
+
+ Password errorErrore password
-
-
+
+ Failed to setup password.
Empty password.Impossibile impostare la password.
Password vuota.
-
+ Try AgainRiprova
-
+ Change profileCambia profilo
-
+ Reinit current profileReinizializza il profilo corrente
-
+ Wrong password has been enteredÈ stata inserita una password sbagliata
-
+ History Log decryption passwordPassword per decriptare i log
-
+ Encrypted logLog criptato
-
+ Your history is encrypted with different password.
Do you want to try another password?I log delle chat sono criptati con una password diversa.
Vuoi provare ad inserire un'altra password?
-
+ HistoryChat Log
-
+ Due to incorret password history will be disabled.Password errata, i log delle chat non saranno caricati.
-
+ NO PasswordNessuna password
-
+ Will be saved without encryption!Il Tox datafile sarà salvato senza password!
@@ -538,17 +553,22 @@ Soprannome:
Mostra icona nella traybar
-
+
+ Light icon
+ Icona brillante
+
+
+ Set to 0 to disableImposta 0 per disabilitare
-
+ Connection SettingsImpostazioni Connessione
-
+ Enable IPv6 (recommended)Text on a checkbox to enable IPv6Abilita IPv6 (consigliato)
@@ -590,143 +610,148 @@ Soprannome:
Minimizza nella traybar
-
- Tray icon displays user status
- Mostra lo stato nell'icona della traybar
-
-
-
- This is a temporary work around until proper systray status icons are available.
- Questo è un workaround temporaneo fino a quando non saranno disponibili icone di stato adeguate.
-
-
-
+ Show contacts' status changesMostra quando i contatti cambiano stato
-
+ Check for updates on startup (unstable)Controlla aggiornamenti all'avvio (unstable)
-
+ Focus qTox when a message is receivedDai il focus a qTox quando arriva un messaggio
-
+ Faux offline messagingFalsi messaggi offline
-
+ Provided in minutesEspresso in minuti
-
+ Auto away after (0 to disable)Imposta assenza dopo
-
+ minutes minuti
-
+ You can set this on a per-friend basis by right clicking them.autoaccept cb tooltipPuoi impostare questa preferenza per ogni singolo contatto usando il click destro sul suo nome.
-
+ Autoaccept filesAccetta automaticamente i trasferimenti di files
-
+ Save files inSalva i files in
-
+ PushButtonSfoglia
-
+ ThemeImpostazioni Tema
-
+ Use emoticonsUsa emoticons
-
+ Smiley PackText on smiley pack labelEmoticons
-
+ StyleStile
-
+ Theme colorColore
-
+ Emoticon sizeDimensione emoticons
-
+ px px
-
+ Timestamp formatFormato data/ora
-
+ Disabling this allows, e.g., toxing over Tor. It adds load to the Tox network however, so uncheck only when necessary.force tcp checkbox tooltipDisabilitando questo sarà possibile usare qTox con Tor. Tuttavia verrà aggiunto carico alla rete Tox, quindi disabilitare solo se necessario.
-
+ Enable UDP (recommended)Text on checkbox to disable UDPAbilita UDP (consigliato)
-
- Use proxy (SOCKS5)
- Usa proxy (SOCKS5)
+
+ Proxy type
+ Proxy
-
+
+ None
+ Nessuno
+
+
+
+ SOCKS5
+ SOCKS 5
+
+
+
+ HTTP
+ HTTP
+
+
+ AddressText on proxy addr labelIP
-
+ PortText on proxy port labelPorta
-
+ Reconnectreconnect buttonRiconnetti
@@ -735,43 +760,43 @@ Soprannome:
GenericChatForm
-
+ Send messageInvia messaggio
-
+ SmileysEmoticons
-
+ Send file(s)Invia file(s)
-
+ Audio call: RED means you're on a callChiamata audio: ROSSO significa che la chiamata è in corso
-
+ Video call: RED means you're on a callVideochiamata: ROSSO significa che la chiamata è in corso
-
+ Toggle speakers volume: RED is OFFImposta volume altoparlanti: ROSSO è SPENTO
-
+ Toggle microphone: RED is OFFImposta microfono: ROSSO è SPENTO
-
+ Save chat logSalva il log della chat
@@ -781,7 +806,7 @@ Soprannome:
Rimuovi messaggi visualizzati
-
+ ClearedPulito
@@ -927,42 +952,44 @@ Nome gruppo:
- Are you sure you want to delete this profile?
+ Are you sure you want to delete this profile?
+Associated friend information and chat logs will be deleted as well.deletion confirmation text
- Sei sicuro di voler eliminare questo profilo?
+ Sei sicuro di voler eliminare questo profilo?
+I contatti e i log delle chat associati ad esso, saranno eliminati.
-
+ Import profileimport dialog titleImporta profilo
-
+ Tox save file (*.tox)import dialog filterTox save file (*.tox)
-
+ Ignoring non-Tox filepopup titleFile ignorato
-
+ Warning: you've chosen a file that is not a Tox save file; ignoring.popup textAttenzione: hai scelto un file che non contiente un profilo Tox.\nQuesto file verrà ignorato.
-
+ Profile already existsimport confirm titleProfilo già esistente
-
+ A profile named "%1" already exists. Do you want to erase it?import confirm textUn profilo chiamato "%1" esiste già. Vuoi sovrascriverlo?
@@ -1151,8 +1178,8 @@ Vuoi eliminare il vecchio file?
PrivacySettings
- Typing Notification
- Notifica quando qualcuno sta scrivendo
+ Send Typing Notifications
+ Permetti ai miei contatti di vedere quando sto scrivendo
@@ -1233,13 +1260,13 @@ Vuoi eliminare il vecchio file?
%1.tox è stato importato con successo
-
+ UpdateThe title of a message boxNuova versione
-
+ An update is available, do you want to download it now?
It will be installed when qTox restarts.È disponibile una nuova versione di qTox, vuoi scaricarla adesso?
@@ -1350,6 +1377,15 @@ Verrà installata al riavvio del programma.Error with the DNSLa risposta del server DNS non contiene un Tox ID valido
+
+
+
+ It appears that qTox has to use the old tox1 protocol.
+Unfortunately tox1 is not secure. Should it be used anyway?
+ Sembra che qTox debba usare il vecchio protocollo tox1.
+Sfortunatamente il protocollo tox1 non è sicuro.
+Usare comunque il protocollo tox1?
+ ToxURIDialog
@@ -1409,11 +1445,6 @@ Verrà installata al riavvio del programma.
&Quit&Esci
-
-
- Change status to:
- Cambia stato in:
- Online
diff --git a/translations/lt.ts b/translations/lt.ts
new file mode 100644
index 000000000..c907a1ae7
--- /dev/null
+++ b/translations/lt.ts
@@ -0,0 +1,1579 @@
+
+
+
+
+ AVForm
+
+
+ Audio/Video
+ Garsas ir vaizdas
+
+
+
+ AVSettings
+
+
+ Audio Settings
+ Garso įrenginiai
+
+
+
+ Microphone
+ Įrašymas
+
+
+
+ Playback
+ Išvestis
+
+
+
+ Playback device
+ Išvesties įrenginys
+
+
+
+ Capture device
+ Įrašymo įrenginys
+
+
+
+ Rescan audio devices
+ Aptikti garso įrenginius iš naujo
+
+
+
+ Filter audio
+ Filtruoti garso signalą
+
+
+
+ Video Settings
+ Vaizdo nustatymai
+
+
+
+ Resolution
+ Raiška
+
+
+
+ Hue
+ Atspalviai
+
+
+
+ Brightness
+ Ryškumas
+
+
+
+ Saturation
+ Sodrumas
+
+
+
+ Contrast
+ Kontrastas
+
+
+
+ AddFriendForm
+
+
+ Add Friends
+ Pridėti kontaktą
+
+
+
+ Tox ID
+ Tox ID of the person you're sending a friend request to
+ Tox ID
+
+
+
+ Message
+ The message you send in friend requests
+ Prisistatymo žinutė
+
+
+
+ Send friend request
+ Siųsti užklausą
+
+
+
+ Tox me maybe?
+ Default message in friend requests if the field is left blank. Write something appropriate!
+ Gal susirašinėjam per Tox?
+
+
+
+ Please fill in a valid Tox ID
+ Tox ID of the friend you're sending a friend request to
+ Įveskite tinkamą kontakto Tox ID
+
+
+
+ You can't add yourself as a friend!
+ When trying to add your own Tox ID as friend
+ Negalite naudoti savo Tox ID!
+
+
+
+ qTox needs to use the Tox DNS, but can't do it through a proxy.
+Ignore the proxy and connect to the Internet directly?
+ qTox naudoja Tox DNS, bet tai neįmanoma per įgaliotąjį (proxy) serverį.
+Ignoruoti įgaliotąjį serverį ir jungtis prie interneto tiesiogiai?
+
+
+
+ This Tox ID does not exist
+ DNS error
+ Tokio Tox ID nėra
+
+
+
+ AdvancedForm
+
+
+ Advanced
+ Kita
+
+
+
+ FULL - very safe, slowest (recommended)
+ VISADA – saugiai, bet lėtai (rekomenduojama)
+
+
+
+ NORMAL - almost as safe as FULL, about 20% faster than FULL
+ ĮPRASTAI – beveik taip pat saugiai, bet 20 % greičiau
+
+
+
+ OFF - disables all safety, when something goes wrong your history may be lost, fastest (not recommended)
+ NELAUKTI – apsauga išjungta: kilus problemoms gali dingti pokalbių žurnalas – greičiausia (nerekomenduojama)
+
+
+
+ AdvancedSettings
+
+
+ Form
+ Forma
+
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#ff0000;">IMPORTANT NOTE</span></p><p><span style=" color:#ff0000;">Unless you </span><span style=" font-weight:600; color:#ff0000;">really</span><span style=" color:#ff0000;"> know what you are doing, please do </span><span style=" font-weight:600; color:#ff0000;">not</span><span style=" color:#ff0000;"> change anything here. Changes made here may lead to problems with qTox, and even to loss of your data, e.g. history.</span></p></body></html>
+ <html><head/><body><p><span style=" font-weight:600; color:#ff0000;">SVARBUS PRANEŠIMAS</span></p><p><span style=" color:#ff0000;">Nebent </span><span style=" font-weight:600; color:#ff0000;">tikrai</span><span style=" color:#ff0000;"> išmanote kaip elgtis, </span><span style=" font-weight:600; color:#ff0000;">nieko</span><span style=" color:#ff0000;"> čia nekeiskite. Pakeitimai gali sukelti problemų naudotis qTox bei net duomenų (pvz., pokalbių žurnalo) praradimą.</span></p></body></html>
+
+
+
+ Reset to default settings
+ Atstatyti pradinius nustatymus
+
+
+
+ History
+ Pokalbių žurnalas
+
+
+
+ <html><head/><body><p><a href="http://www.sqlite.org/pragma.html#pragma_synchronous"><span style=" text-decoration: underline; color:#0000ff;">Synchronous writing to DB</span></a></p></body></html>
+ <html><head/><body><p><a href="http://www.sqlite.org/pragma.html#pragma_synchronous"><span style=" text-decoration: underline; color:#0000ff;">Laukti, kol pildoma duomenų bazė</span></a></p></body></html>
+
+
+
+ ChatForm
+
+
+ Load History...
+ Įkelti pokalbių žurnalą...
+
+
+
+ Send a file
+ Siųsti failą
+
+
+
+ File not read
+ Failas neperskaitomas
+
+
+
+ qTox wasn't able to open %1
+ qTox nepavyko atidaryti %1
+
+
+
+ Bad Idea
+ Bloga mintis
+
+
+
+ You're trying to send a special (sequential) file, that's not going to work!
+ Bandote siųsti ypatingą (nuoseklųjį) failą, tai nepavyks!
+
+
+
+ %1 is calling
+ %1 skambina
+
+
+
+ %1 stopped calling
+ %1 nutraukė skambutį
+
+
+
+ Calling to %1
+ Skambiname: %1
+
+
+
+ Call rejected
+ Skambutis atmestas
+
+
+
+ Failed to send file "%1"
+ Nepavyko nusiųsti failo „%1“
+
+
+
+ Call with %1 ended. %2
+ Pokalbis su %1 baigėsi. %2
+
+
+
+ Call duration:
+ Pokalbio trukmė:
+
+
+
+ is typing...
+ rašo žinutę...
+
+
+
+ ChatTextEdit
+
+
+ Type your message here...
+ Įveskite čia savo žinutę...
+
+
+
+ Core
+
+
+ Toxing on qTox
+ Naudoju qTox
+
+
+
+ qTox User
+ qTox naudotojas
+
+
+
+ Friend is already added
+ Toks kontaktas jau pridėtas
+
+
+
+ Encryption error
+ Šifro klaida
+
+
+
+ The .tox file is encrypted, but encryption was not checked, continuing regardless.
+ .tox failas užšifruotas: nors šifras nepatikrintas, tęsiame darbą.
+
+
+
+ Tox datafile decryption password
+ Slaptažodis Tox duomenų failui iššifruoti
+
+
+
+
+
+ Password error
+ Slaptažodis netinka
+
+
+
+
+ Failed to setup password.
+Empty password.
+ Nepavyko nustatyti slaptažodžio.
+Slaptažodis tuščias.
+
+
+
+ Try Again
+ Bandykite dar kartą
+
+
+
+ Change profile
+ Pakeisti profilį
+
+
+
+ Reinit current profile
+ Išvalyti dabartinį profilį
+
+
+
+ Wrong password has been entered
+ Įvestas slaptažodis netinka
+
+
+
+ History Log decryption password
+ Pokalbių žurnalo šifro slaptažodis
+
+
+
+ Encrypted log
+ Žurnalas užšifruotas
+
+
+
+ Your history is encrypted with different password.
+Do you want to try another password?
+ Jūsų pokalbių žurnalas užšifruotas kitu slaptažodžiu.
+Norite išmėginti kitą slaptažodį?
+
+
+
+ History
+ Žurnalas
+
+
+
+ Due to incorret password history will be disabled.
+ Dėl netinkamo slaptažodžio pokalbių žurnalas išjungtas.
+
+
+
+ NO Password
+ NĖRA slaptažodžio
+
+
+
+ Will be saved without encryption!
+ Bus saugojama be šifro!
+
+
+
+ FileTransferInstance
+
+
+ Save a file
+ Title of the file saving dialog
+ Išsaugoti failą
+
+
+
+ Location not writable
+ Title of permissions popup
+ Įrašyti failo čia neleidžiama
+
+
+
+ You do not have permission to write that location. Choose another, or cancel the save dialog.
+ text of permissions popup
+ Nėra teisių įrašyti failą šioje vietoje. Bandykite įrašyti kitur arba atšaukite dialogo langą.
+
+
+
+ ETA
+ Liko
+
+
+
+ FilesForm
+
+
+ Transfered Files
+ "Headline" of the window
+ Baigti siųsti failai
+
+
+
+ Downloads
+ Parsiųsti
+
+
+
+ Uploads
+ Nusiųsti
+
+
+
+ FriendRequestDialog
+
+
+ Friend request
+ Title of the window to aceept/deny a friend request
+ Kontakto užklausa
+
+
+
+ Someone wants to make friends with you
+ Kažkas nori su Jumis bendrauti
+
+
+
+ User ID:
+ Naudojo ID:
+
+
+
+ Friend request message:
+ Prisistatymo žinutė:
+
+
+
+ Accept
+ Accept a friend request
+ Priimti kontaktą
+
+
+
+ Reject
+ Reject a friend request
+ Atmesti kontaktą
+
+
+
+ FriendWidget
+
+
+ Invite to group
+ Menu to invite a friend to a groupchat
+ Pakviesti į grupės pokalbį
+
+
+
+ Copy friend ID
+ Menu to copy the Tox ID of that friend
+ Nukopijuoti kontakto ID
+
+
+
+ Set alias...
+ Nustatyti slapyvardį...
+
+
+
+ Auto accept files from this friend
+ context menu entry
+ Automatiškai priimti failus iš šio kontakto
+
+
+
+ Remove friend
+ Menu to remove the friend from our friendlist
+ Pašalinti kontaktą
+
+
+
+ Choose an auto accept directory
+ popup title
+ Pasirinkite priimamų failų katalogą
+
+
+
+ User alias
+ Naudotojo slapyvardis
+
+
+
+ You can also set this by clicking the chat form name.
+Alias:
+ Slapyvardį pakeisti galima ir spustelėjus pokalbių lange.
+Slapyvardis:
+
+
+
+ GeneralForm
+
+
+ General
+ Bendrosios
+
+
+
+
+ None
+ Nėra
+
+
+
+ Choose an auto accept directory
+ popup title
+ Pasirinkite priimamų failų katalogą
+
+
+
+ Call active
+ popup title
+ Vyksta pokalbis
+
+
+
+ You can't disconnect while a call is active!
+ popup text
+ Vykstant pokalbiui atsijungti negalite!
+
+
+
+ GeneralSettings
+
+
+ General Settings
+ Bendrosios nuostatos
+
+
+
+
+ The translation may not load until qTox restarts.
+ Vertimas gali nepasirodyti, kol nepaleisite qTox iš naujo.
+
+
+
+ Translation
+ Vertimas
+
+
+
+ Save settings to the working directory instead of the usual conf dir
+ describes makeToxPortable checkbox
+ Nuostatas saugoti veikiamajame kataloge, o ne įprastame nuostatų kataloge
+
+
+
+ Make Tox portable
+ Leisti persinešti Tox programą
+
+
+
+ System tray integration
+ Sistemos juostelės integracija
+
+
+
+ Show system tray icon
+ Rodyti sistemos juostelėje
+
+
+
+ Start in tray
+ Paleidžiant paslėpti juostelėje
+
+
+
+ Close to tray
+ Uždarant paslėpti juostelėje
+
+
+
+ Minimize to tray
+ Sumažinant paslėpti juostelėje
+
+
+
+ Light icon
+ Šviesi piktograma
+
+
+
+ Show contacts' status changes
+ Rodyti kontaktų būsenos pokyčius
+
+
+
+ Check for updates on startup (unstable)
+ Ieškoti atnaujinimų paleidžiant (nestabili funkcija)
+
+
+
+ Focus qTox when a message is received
+ Sufokusuoti qTox gavus žinutę
+
+
+
+ Faux offline messaging
+ Kaupti žinutes atsijungus adresatui
+
+
+
+ Provided in minutes
+ Laikas minutėmis
+
+
+
+ Auto away after (0 to disable)
+ Automatiškai „pasitraukęs“ po („0“ išjungia)
+
+
+
+ Set to 0 to disable
+ Išjungsite nustatydami „0“
+
+
+
+ minutes
+ minučių
+
+
+
+ You can set this on a per-friend basis by right clicking them.
+ autoaccept cb tooltip
+ Galite nustatyti individualiai ant bet kurio kontakto spustelėję dešiniuoju pelės klavišu.
+
+
+
+ Autoaccept files
+ Automatiškai priimti failus
+
+
+
+ Save files in
+ Išsaugoti failus
+
+
+
+ PushButton
+ PushButton
+
+
+
+ Theme
+ Apipavidalinimas
+
+
+
+ Use emoticons
+ Naudoti jaustukus
+
+
+
+ Smiley Pack
+ Text on smiley pack label
+ Jaustukų rinkinys
+
+
+
+ Style
+ Stilius
+
+
+
+ Theme color
+ Apipavidalinimo spalva
+
+
+
+ Emoticon size
+ Jaustukų dydis
+
+
+
+ px
+ px
+
+
+
+ Timestamp format
+ Laiko formatas
+
+
+
+ Connection Settings
+ Ryšio nuostatos
+
+
+
+ Enable IPv6 (recommended)
+ Text on a checkbox to enable IPv6
+ Įjungti IPv6 (rekomenduojama)
+
+
+
+ Disabling this allows, e.g., toxing over Tor. It adds load to the Tox network however, so uncheck only when necessary.
+ force tcp checkbox tooltip
+ Išjungus galima naudotis Tox protokolu per Tor. Tox tinklas dėl to yra papildomai apkraunamas, todėl atžymėkite tik tada, kai reikia.
+
+
+
+ Enable UDP (recommended)
+ Text on checkbox to disable UDP
+ Įjungti UDP (rekomenduojama)
+
+
+
+ Proxy type
+ Įgaliotojo serverio tipas
+
+
+
+ None
+ Nėra
+
+
+
+ SOCKS5
+ SOCKS5
+
+
+
+ HTTP
+ HTTP
+
+
+
+ Address
+ Text on proxy addr label
+ Adresas
+
+
+
+ Port
+ Text on proxy port label
+ Prievadas
+
+
+
+ Reconnect
+ reconnect button
+ Prisijungti iš naujo
+
+
+
+ GenericChatForm
+
+
+ Send message
+ Siųsti žinutę
+
+
+
+ Smileys
+ Jaustukai
+
+
+
+ Send file(s)
+ Siųsti failą (-us)
+
+
+
+ Audio call: RED means you're on a call
+ Pokalbis su garsu: RAUDONA reiškia, kad vyksta pokalbis
+
+
+
+ Video call: RED means you're on a call
+ Pokalbis su vaizdu: RAUDONA reiškia, kad vyksta pokalbis
+
+
+
+ Toggle speakers volume: RED is OFF
+ Garsiakalbiai: RAUDONA reiškia IŠJUNGTA
+
+
+
+ Toggle microphone: RED is OFF
+ Mikrofonas: RAUDONA reiškia IŠJUNGTA
+
+
+
+
+ Save chat log
+ Išsaugoti pokalbio žurnalą
+
+
+
+ Clear displayed messages
+ Išvalyti rodomas žinutes
+
+
+
+ Cleared
+ Išvalyta
+
+
+
+ GroupChatForm
+
+
+ %1 users in chat
+ Number of users in chat
+ Pokalbyje %1 žmonių
+
+
+
+ %1 users in chat
+ Pokalbyje %1 žmonių
+
+
+
+ GroupWidget
+
+
+
+ %1 users in chat
+ Pokalbyje %1 žmonių
+
+
+
+
+ 0 users in chat
+ Pokalbyje žmonių nėra
+
+
+
+ Set title...
+ Nustatyti pavadinimą...
+
+
+
+ Quit group
+ Menu to quit a groupchat
+ Palikti grupės pokalbį
+
+
+
+ Group title
+ Grupės pavadinimas
+
+
+
+ You can also set this by clicking the chat form name.
+Title:
+ Pavadinimą pakeisti galima ir spustelėjus pokalbių lange.
+Pavadinimas:
+
+
+
+ IdentityForm
+
+
+ Identity
+ Tapatybė
+
+
+
+ Call active
+ popup title
+ Vyksta pokalbis
+
+
+
+ You can't switch profiles while a call is active!
+ popup text
+ Vykstant pokalbiui profilių keisti negalima!
+
+
+
+ Rename "%1"
+ renaming a profile
+ Pervadinti „%1“
+
+
+
+ Profile already exists
+ rename confirm title
+ Toks profilis jau yra
+
+
+
+ A profile named "%1" already exists. Do you want to erase it?
+ rename confirm text
+ Profilis „%1“ jau yra. Ar norite jį ištrinti?
+
+
+
+ Export profile
+ save dialog title
+ Eksportuoti profilį
+
+
+
+ Tox save file (*.tox)
+ save dialog filter
+ Tox failas (*.tox)
+
+
+
+ Failed to remove file
+ Failo ištrinti nepavyko
+
+
+
+ The file you chose to overwrite could not be removed first.
+ Perrašomo failo pirma ištrinti nepavyko.
+
+
+
+ Failed to copy file
+ Failo nukopijuoti nepavyko
+
+
+
+ The file you chose could not be written to.
+ Nepavyko įrašyti į pasirinktą failą.
+
+
+
+ Profile currently loaded
+ current profile deletion warning title
+ Profilis aktyvus
+
+
+
+ This profile is currently in use. Please load a different profile before deleting this one.
+ current profile deletion warning text
+ Šis profilis yra aktyvus. Prieš jį ištrindami turite įjungti kitą profilį.
+
+
+
+ Deletion imminent!
+ deletion confirmation title
+ Gresia ištrynimas!
+
+
+
+ Are you sure you want to delete this profile?
+Associated friend information and chat logs will be deleted as well.
+ deletion confirmation text
+ Ar tikrai norite ištrinti šį profilį?
+Susijusi kontaktų informacija bei pokalbių žurnalas bus taip pat ištrinti.
+
+
+
+ Import profile
+ import dialog title
+ Importuoti profilį
+
+
+
+ Tox save file (*.tox)
+ import dialog filter
+ Tox failas (*.tox)
+
+
+
+ Ignoring non-Tox file
+ popup title
+ Rodomi tik Tox failai
+
+
+
+ Warning: you've chosen a file that is not a Tox save file; ignoring.
+ popup text
+ Įspėjimas: pasirinktas failas nėra Tox failas – praleista.
+
+
+
+ Profile already exists
+ import confirm title
+ Toks profilis jau yra
+
+
+
+ A profile named "%1" already exists. Do you want to erase it?
+ import confirm text
+ Profilis „%1“ jau yra. Ar norite jį ištrinti?
+
+
+
+ IdentitySettings
+
+
+ Public Information
+ Vieša informacija
+
+
+
+ Name
+ Vardas
+
+
+
+ Status
+ Būsena
+
+
+
+ Tox ID
+ Tox ID
+
+
+
+ Your Tox ID (click to copy)
+ Jūsų Tox ID (spustelėję nukopijuosite)
+
+
+
+ Profiles
+ Profiliai
+
+
+
+ Available profiles:
+ Išsaugoti profiliai:
+
+
+
+
+ Switching profiles is disabled during calls
+ tooltip
+ Pokalbio metu keisti profilio negalima
+
+
+
+ Load
+ load profile button
+ Aktyvuoti
+
+
+
+ Rename
+ rename profile button
+ Pervadinti
+
+
+
+ Export
+ export profile button
+ Eksportuoti
+
+
+
+ This is useful to remain safe on public computers
+ delete profile button tooltip
+ Tai naudinga, jei norite likti saugūs prie viešai prieinamų kompiuterių
+
+
+
+ Delete
+ delete profile button
+ Ištrinti
+
+
+
+ Import a profile
+ import profile button
+ Importuoti profilį
+
+
+
+ New Tox ID
+ new profile button
+ Naujas Tox ID
+
+
+
+ InputPasswordDialog
+
+
+ Password Dialog
+ Slaptažodis
+
+
+
+ Input password:
+ Įveskite slaptažodį:
+
+
+
+ LoadHistoryDialog
+
+
+ Load History Dialog
+ Įkelti žurnalą
+
+
+
+ Load history from:
+ Įkelti pokalbių žurnalą nuo:
+
+
+
+ MainWindow
+
+
+ Your name
+ Jūsų vardas
+
+
+
+ Your status
+ Jūsų būsena
+
+
+
+ Add friends
+ Pridėti kontaktą
+
+
+
+ Create a group chat
+ Sukurti grupės pokalbį
+
+
+
+ View completed file transfers
+ Rodyti baigtus siųsti failus
+
+
+
+ Change your settings
+ Keisti nuostatas
+
+
+
+ Close
+ Uždaryti
+
+
+
+ NetCamView
+
+
+ Tox video
+ Tox vaizdas
+
+
+
+ PrivacyForm
+
+
+ Privacy
+ Privatumas
+
+
+
+ Encrypted log
+ Užšifruotas žurnalas
+
+
+
+ You already have history log file encrypted with different password
+Do you want to delete old history file?
+ Jau turite kitu slaptažodžiu šifruotą žurnalą
+Ar norite senąjį pokalbių žurnalą ištrinti?
+
+
+
+ PrivacySettings
+
+
+ Send Typing Notifications
+ Rodyti, kad rašote žinutę
+
+
+
+ Keep History (unstable)
+ Išsaugoti žurnalą (nestabili funkcija)
+
+
+
+ Encryption
+ Šifravimas
+
+
+
+ Encrypt Tox datafile
+ Šifruoti Tox duomenų failą
+
+
+
+ Encrypt History
+ Šifruoti pokalbių žurnalą
+
+
+
+ Nospam
+ Tox ID apsauga nuo nepageidaujamų kontaktų (nospam)
+
+
+
+ HHHHHHHH
+ HHHHHHHH
+
+
+
+ Generate random nospam
+ Sugeneruoti atsitiktinį
+
+
+
+ QObject
+
+
+ Update
+ The title of a message box
+ Atnaujinimas
+
+
+
+ An update is available, do you want to download it now?
+It will be installed when qTox restarts.
+ Rasta nauja programos versija, ar norite ją parsisiųsti?
+Ji bus įdiegta paleidus qTox iš naujo.
+
+
+
+ Tox URI to parse
+ analizuoti Tox URI
+
+
+
+ Starts new instance and loads specified profile.
+ Atidaro naują langą ir aktyvuoja nurodytą profilį.
+
+
+
+ profile
+ profilis
+
+
+
+ Default
+ Numatyta
+
+
+
+ Blue
+ Mėlyna
+
+
+
+ Olive
+ Alyvinė
+
+
+
+ Red
+ Raudona
+
+
+
+ Violet
+ Violetinė
+
+
+
+ Ignoring non-Tox file
+ popup title
+ Praleidžiamas failas
+
+
+
+ Warning: you've chosen a file that is not a Tox save file; ignoring.
+ popup text
+ Įspėjimas: pasirinktas failas nėra Tox failas – praleista.
+
+
+
+ Profile already exists
+ import confirm title
+ Toks profilis jau yra
+
+
+
+ A profile named "%1" already exists. Do you want to erase it?
+ import confirm text
+ Profilis „%1“ jau yra. Ar norite jį ištrinti?
+
+
+
+ Profile imported
+ Profilis importuotas
+
+
+
+ %1.tox was successfully imported
+ %1.tox sėkmingai importuotas
+
+
+
+ Tox me maybe?
+ Default message in Tox URI friend requests. Write something appropriate!
+ Gal susirašinėjam per Tox?
+
+
+
+ SetPasswordDialog
+
+
+ Type Password
+ Įveskite slaptažodį
+
+
+
+ Repeat Password
+ Pakartokite slaptažodį
+
+
+
+ ToxDNS
+
+
+ The connection timed out
+ The DNS gives the Tox ID associated to toxme.se addresses
+ Ryšio sudaryti nepavyko
+
+
+
+ This address does not exist
+ The DNS gives the Tox ID associated to toxme.se addresses
+ Tokio adreso nėra
+
+
+
+ Error while looking up DNS
+ The DNS gives the Tox ID associated to toxme.se addresses
+ Klaida gaunant DNS duomenis
+
+
+
+ No text record found
+ Error with the DNS
+ DNS įrašas nerastas
+
+
+
+ Unexpected number of values in text record
+ Error with the DNS
+ Netinkamas DNS įrašas
+
+
+
+ The version of Tox DNS used by this server is not supported
+ Error with the DNS
+ Šio serverio Tox DNS versija nepalaikoma
+
+
+
+ The DNS lookup does not contain any Tox ID
+ Error with the DNS
+ DNS atsake nėra Tox ID
+
+
+
+
+ The DNS lookup does not contain a valid Tox ID
+ Error with the DNS
+ DNS atsake nėra tinkamo Tox ID
+
+
+
+
+ It appears that qTox has to use the old tox1 protocol.
+Unfortunately tox1 is not secure. Should it be used anyway?
+ Panašu, kad qTox turi naudoti senąjį tox1 protokolą.
+Deja tox1 protokolas turi saugumo spragų. Tęsti?
+
+
+
+ ToxURIDialog
+
+
+ Add a friend
+ Title of the window to add a friend through Tox URI
+ Pridėti kontaktą
+
+
+
+ Do you want to add %1 as a friend?
+ Ar norite pridėti %1 į kontaktus?
+
+
+
+ User ID:
+ Naudotojo ID:
+
+
+
+ Friend request message:
+ Prisistatymo žinutė:
+
+
+
+ Send
+ Send a friend request
+ Siųsti
+
+
+
+ Cancel
+ Don't send a friend request
+ Atšaukti
+
+
+
+ Widget
+
+
+ Online
+ Prisijungęs
+
+
+
+ Away
+ Pasitraukęs
+
+
+
+ Busy
+ Užsiėmęs
+
+
+
+ &Quit
+ &Baigti
+
+
+
+ Online
+ Button to set your status to 'Online'
+ Prisijungęs
+
+
+
+ Away
+ Button to set your status to 'Away'
+ Pasitraukęs
+
+
+
+ Busy
+ Button to set your status to 'Busy'
+ Užsiėmęs
+
+
+
+ Choose a profile
+ Pasirinkti profilį
+
+
+
+ Please choose which identity to use
+ Pasirinkite, kurią tapatybę naudoti
+
+
+
+ Choose a profile picture
+ Pasirinkite profilio paveikslėlį
+
+
+
+
+
+ Error
+ Klaida
+
+
+
+ Unable to open this file
+ Nepavyko atidaryti failo
+
+
+
+ Unable to read this image
+ Nepavyko perskaityti paveikslėlio
+
+
+
+ This image is too big
+ Paveikslėlis per didelis
+
+
+
+ Toxcore failed to start, the application will terminate after you close this message.
+ Toxcore paleisti nepavyko: programa išsijungs uždarius šį pranešimą.
+
+
+
+ toxcore failed to start with your proxy settings. qTox cannot run; please modify your settings and restart.
+ popup text
+ Toxcore neprisijungia su Jūsų įgaliotojo serverio nustatymais. qTox negali dirbti – pakeiskite nustatymus ir prisijunkite iš naujo.
+
+
+
+ Add friend
+ Pridėti kontaktą
+
+
+
+ File transfers
+ Failų siuntimai
+
+
+
+ Settings
+ Nuostatos
+
+
+
+ Couldn't request friendship
+ Nepavyko nusiųsti užklausos
+
+
+
+ away
+ contact status
+ pasitraukęs (-usi)
+
+
+
+ busy
+ contact status
+ užsiėmęs (-usi)
+
+
+
+ offline
+ contact status
+ neprisijungęs (-usi)
+
+
+
+ online
+ contact status
+ prisijungęs (-usi)
+
+
+
+ %1 is now %2
+ e.g. "Dubslow is now online"
+ %1 dabar %2
+
+
+
+ <Unknown>
+ Placeholder when we don't know someone's name in a group chat
+ <Nepažįstamas>
+
+
+
+ %1 has set the title to %2
+ %1 nustatė pavadinimą „%2“
+
+
+
+ Message failed to send
+ Nepavyko nusiųsti žinutės
+
+
+
diff --git a/translations/pt.ts b/translations/pt.ts
new file mode 100644
index 000000000..47792278d
--- /dev/null
+++ b/translations/pt.ts
@@ -0,0 +1,1578 @@
+
+
+
+
+ AVForm
+
+
+ Audio/Video
+ Áudio/Vídeo
+
+
+
+ AVSettings
+
+
+ Audio Settings
+ Configurações de Áudio
+
+
+
+ Microphone
+ Volume do Microfone
+
+
+
+ Playback
+ Volume de Reprodução
+
+
+
+ Playback device
+ Dispositivo de Reprodução
+
+
+
+ Capture device
+ Dispositivo de Captura
+
+
+
+ Rescan audio devices
+ Atualizar dispositivos de áudio
+
+
+
+ Filter audio
+ Filtrar áudio
+
+
+
+ Video Settings
+ Configurações de Vídeo
+
+
+
+ Resolution
+ Resolução
+
+
+
+ Hue
+ Matiz
+
+
+
+ Brightness
+ Brilho
+
+
+
+ Saturation
+ Saturação
+
+
+
+ Contrast
+ Contraste
+
+
+
+ AddFriendForm
+
+
+ Add Friends
+ Adicionar Contatos
+
+
+
+ Tox ID
+ Tox ID of the person you're sending a friend request to
+ ID Tox
+
+
+
+ Message
+ The message you send in friend requests
+ Mensagem
+
+
+
+ Send friend request
+ Enviar requisição de contato
+
+
+
+ Tox me maybe?
+ Default message in friend requests if the field is left blank. Write something appropriate!
+ Olá! Gostaria de adicionar você aos meus contatos no Tox.
+
+
+
+ Please fill in a valid Tox ID
+ Tox ID of the friend you're sending a friend request to
+ Por favor preencha um ID Tox válido
+
+
+
+ You can't add yourself as a friend!
+ When trying to add your own Tox ID as friend
+ Você não pode adicionar a si mesmo como contato!
+
+
+
+ qTox needs to use the Tox DNS, but can't do it through a proxy.
+Ignore the proxy and connect to the Internet directly?
+ qTox precisa usar o DNS do Tox, mas não pe capaz de fazer isso através de um proxy.
+Deve-se ignorar as configurações de proxy e conectar diretamente à internet?
+
+
+
+ This Tox ID does not exist
+ DNS error
+ Este ID Tox não existe
+
+
+
+ AdvancedForm
+
+
+ Advanced
+ Avançado
+
+
+
+ FULL - very safe, slowest (recommended)
+ COMPLETO - muito seguro, lento (recomendado)
+
+
+
+ NORMAL - almost as safe as FULL, about 20% faster than FULL
+ NORMAL - praticamente tão seguro quanto o COMPLETO, cerca de 20% mais rápido que o completo
+
+
+
+ OFF - disables all safety, when something goes wrong your history may be lost, fastest (not recommended)
+ DESLIGADO - desabilita toda a segurança, quando algo de errado ocorre seu histórico pode ser perdido, é o mais rápido (não recomendado)
+
+
+
+ AdvancedSettings
+
+
+ Form
+ Avançado
+
+
+
+ <html><head/><body><p><span style=" font-weight:600; color:#ff0000;">IMPORTANT NOTE</span></p><p><span style=" color:#ff0000;">Unless you </span><span style=" font-weight:600; color:#ff0000;">really</span><span style=" color:#ff0000;"> know what you are doing, please do </span><span style=" font-weight:600; color:#ff0000;">not</span><span style=" color:#ff0000;"> change anything here. Changes made here may lead to problems with qTox, and even to loss of your data, e.g. history.</span></p></body></html>
+ <html><head/><body><p><span style=" font-weight:600; color:#ff0000;">IMPORTANTE</span></p><p><span style=" color:#ff0000;">A menos que você </span><span style=" font-weight:600; color:#ff0000;">realmente</span><span style=" color:#ff0000;"> saiba o que está fazendo, por favor </span><span style=" font-weight:600; color:#ff0000;">não</span><span style=" color:#ff0000;"> altere nada aqui. Alterações feitas aqui podem causar problemas ao qTox, e mesmo a perda de seus dados, com seu histórico, por exemplo.</span></p></body></html>
+
+
+
+ Reset to default settings
+ Restaurar às configurações padrão
+
+
+
+ History
+ Histórico
+
+
+
+ <html><head/><body><p><a href="http://www.sqlite.org/pragma.html#pragma_synchronous"><span style=" text-decoration: underline; color:#0000ff;">Synchronous writing to DB</span></a></p></body></html>
+ <html><head/><body><p><a href="http://www.sqlite.org/pragma.html#pragma_synchronous"><span style=" text-decoration: underline; color:#0000ff;">Escrita sincronizada no BD</span></a></p></body></html>
+
+
+
+ ChatForm
+
+
+ Load History...
+ Carregar Histórico...
+
+
+
+ Send a file
+ Enviar um arquivo
+
+
+
+ File not read
+ Arquivo não lido
+
+
+
+ qTox wasn't able to open %1
+ qTox não foi capaz de abrir %1
+
+
+
+ Bad Idea
+ Má Idéia
+
+
+
+ You're trying to send a special (sequential) file, that's not going to work!
+ Você está tentando enviar um arquivo especial (sequencial), isso não vai funcionar!
+
+
+
+ %1 is calling
+ %1 está chamando
+
+
+
+ %1 stopped calling
+ %1 cancelou a chamada
+
+
+
+ Calling to %1
+ Chamando %1
+
+
+
+ Call rejected
+ Chamada rejeitada
+
+
+
+ Failed to send file "%1"
+ Falha ao enviar o arquivo "%1"
+
+
+
+ Call with %1 ended. %2
+ Chamada para %1 terminada. %2
+
+
+
+ Call duration:
+ Duração da chamada:
+
+
+
+ is typing...
+ está digitando...
+
+
+
+ ChatTextEdit
+
+
+ Type your message here...
+ Digite sua mensagem aqui...
+
+
+
+ Core
+
+
+ Toxing on qTox
+ Toxing on qTox
+
+
+
+ qTox User
+ Usuário do qTox
+
+
+
+ Friend is already added
+ Contato já adicionado
+
+
+
+ Encryption error
+ Erro de criptografia
+
+
+
+ The .tox file is encrypted, but encryption was not checked, continuing regardless.
+ O arquivo .tox é criptografado, mas a critpografia não foi verificada, continuando mesmo assim.
+
+
+
+ Tox datafile decryption password
+ Senha de criptografia do arquivo de dados
+
+
+
+
+
+ Password error
+ Senha incorreta
+
+
+
+
+ Failed to setup password.
+Empty password.
+ Falha na definição da senha.
+Senha em branco.
+
+
+
+ Try Again
+ Tente novamente
+
+
+
+ Change profile
+ Mudar perfil
+
+
+
+ Reinit current profile
+ Reiniciar o perfil atual
+
+
+
+ Wrong password has been entered
+ Senha incorreta fornecida
+
+
+
+ History Log decryption password
+ Senha de criptografia do arquivo de histórico
+
+
+
+ Encrypted log
+ Histórico criptografado
+
+
+
+ Your history is encrypted with different password.
+Do you want to try another password?
+ Seu histórico foi criptografado com uma senha diferente.
+Você quer tentar outra senha?
+
+
+
+ History
+ Histórico
+
+
+
+ Due to incorret password history will be disabled.
+ Devido à senha incorreta, o histórico será desabilitado.
+
+
+
+ NO Password
+ SEM senha
+
+
+
+ Will be saved without encryption!
+ Será armazenado sem criptografia!
+
+
+
+ FileTransferInstance
+
+
+ Save a file
+ Title of the file saving dialog
+ Salvar arquivo
+
+
+
+ Location not writable
+ Title of permissions popup
+ Impossível gravar aqui
+
+
+
+ You do not have permission to write that location. Choose another, or cancel the save dialog.
+ text of permissions popup
+ Você não possui permissão de escrita aqui. Escolha outro local ou cancele a operação.
+
+
+
+ ETA
+ Tempo
+
+
+
+ FilesForm
+
+
+ Transfered Files
+ "Headline" of the window
+ Arquivos transferidos
+
+
+
+ Downloads
+ Recebidos
+
+
+
+ Uploads
+ Enviados
+
+
+
+ FriendRequestDialog
+
+
+ Friend request
+ Title of the window to aceept/deny a friend request
+ Solicitação de contato
+
+
+
+ Someone wants to make friends with you
+ Alguém quer adicionar você como contato
+
+
+
+ User ID:
+ ID do usuário:
+
+
+
+ Friend request message:
+ Mensagem de requisição contato:
+
+
+
+ Accept
+ Accept a friend request
+ Aceitar
+
+
+
+ Reject
+ Reject a friend request
+ Rejeitar
+
+
+
+ FriendWidget
+
+
+ Invite to group
+ Menu to invite a friend to a groupchat
+ Convidar para grupo
+
+
+
+ Copy friend ID
+ Menu to copy the Tox ID of that friend
+ Copiar ID do contato
+
+
+
+ Set alias...
+ Apelido...
+
+
+
+ Auto accept files from this friend
+ context menu entry
+ Aceitar arquivos automaticamente deste contato
+
+
+
+ Remove friend
+ Menu to remove the friend from our friendlist
+ Remover contato
+
+
+
+ Choose an auto accept directory
+ popup title
+ Escolher um diretório para aceitar arquivos automaticamente
+
+
+
+ User alias
+ Apelido do usuário
+
+
+
+ You can also set this by clicking the chat form name.
+Alias:
+ Também pode ser definido clicando no nome do chat.
+Apelido:
+
+
+
+ GeneralForm
+
+
+ General
+ Geral
+
+
+
+
+ None
+ Nenhum
+
+
+
+ Choose an auto accept directory
+ popup title
+ Escolher um diretório para aceitar arquivos automaticamente
+
+
+
+ Call active
+ popup title
+ Chamada ativa
+
+
+
+ You can't disconnect while a call is active!
+ popup text
+ Você não pode desconectar enquanto uma chamada estiver ativa!
+
+
+
+ GeneralSettings
+
+
+ General Settings
+ Configurações Gerais
+
+
+
+
+ The translation may not load until qTox restarts.
+ A tradução pode não ser atualizada antes do qTox ser reinicializado.
+
+
+
+ Translation
+ Idioma
+
+
+
+ Save settings to the working directory instead of the usual conf dir
+ describes makeToxPortable checkbox
+ Armazena as configurações no diretório de trabalho ao invés do diretório de configurações usual
+
+
+
+ Make Tox portable
+ Deixe o Tox portável
+
+
+
+ System tray integration
+ Integração com a bandeja do sistema
+
+
+
+ Show system tray icon
+ Mostrar ícone na bandeja
+
+
+
+ Start in tray
+ Inicializar na bandeja
+
+
+
+ Close to tray
+ Fechar para a bandeja
+
+
+
+ Minimize to tray
+ Minimizar para a bandeja
+
+
+
+ Light icon
+ Ícone claro
+
+
+
+ Show contacts' status changes
+ Mostar alterações no status dos contatos
+
+
+
+ Check for updates on startup (unstable)
+ Checar atualizações na inicialização (instável)
+
+
+
+ Focus qTox when a message is received
+ Destacar o qTox quando receber uma mensagem
+
+
+
+ Faux offline messaging
+ Envio de mensagens "offline" falso
+
+
+
+ Provided in minutes
+ Em minutos
+
+
+
+ Auto away after (0 to disable)
+ Ficar ausente após (0 para desativar)
+
+
+
+ Set to 0 to disable
+ Defina 0 para desativar
+
+
+
+ minutes
+ minutos
+
+
+
+ You can set this on a per-friend basis by right clicking them.
+ autoaccept cb tooltip
+ Você pode definir esta configuração por contato clicando com o botão direito sobre eles.
+
+
+
+ Autoaccept files
+ Aceitar arquivos automaticamente
+
+
+
+ Save files in
+ Armazenar arquivos em
+
+
+
+ PushButton
+ Clique
+
+
+
+ Theme
+ Tema
+
+
+
+ Use emoticons
+ Usar emoticons
+
+
+
+ Smiley Pack
+ Text on smiley pack label
+ Conjunto de emoticons
+
+
+
+ Style
+ Estilo
+
+
+
+ Theme color
+ Cor do tema
+
+
+
+ Emoticon size
+ Tamanho do emoticon
+
+
+
+ px
+ px
+
+
+
+ Timestamp format
+ Formato da hora
+
+
+
+ Connection Settings
+ Configuraçẽs da Conexão
+
+
+
+ Enable IPv6 (recommended)
+ Text on a checkbox to enable IPv6
+ Permitir IPv6 (recomendado)
+
+
+
+ Disabling this allows, e.g., toxing over Tor. It adds load to the Tox network however, so uncheck only when necessary.
+ force tcp checkbox tooltip
+ Desabilitar esta opção permite, por exemplo, utilizar a rede Tor. Ela adiciona mais dados à rede Tor no entanto, portanto desmarque apenas se necessário.
+
+
+
+ Enable UDP (recommended)
+ Text on checkbox to disable UDP
+ Permitir UDP (recomendado)
+
+
+
+ Proxy type
+ Tipo de proxy
+
+
+
+ None
+ Nenum
+
+
+
+ SOCKS5
+ SOCKS5
+
+
+
+ HTTP
+ HTTP
+
+
+
+ Address
+ Text on proxy addr label
+ Endereço
+
+
+
+ Port
+ Text on proxy port label
+ Porta
+
+
+
+ Reconnect
+ reconnect button
+ Reconectar
+
+
+
+ GenericChatForm
+
+
+ Send message
+ Enviar mensagem
+
+
+
+ Smileys
+ Emoticons
+
+
+
+ Send file(s)
+ Enviar arquivo(s)
+
+
+
+ Audio call: RED means you're on a call
+ Chamada e áudio: VERMELHO significa que você está em uma chamada
+
+
+
+ Video call: RED means you're on a call
+ Chamada e vídeo: VERMELHO significa que você está em uma chamada
+
+
+
+ Toggle speakers volume: RED is OFF
+ Alternar volume de saída: VERMELHO é desligado
+
+
+
+ Toggle microphone: RED is OFF
+ Alternar volume de entrada: VERMELHO é desligado
+
+
+
+
+ Save chat log
+ Armazenar histórico da conversa
+
+
+
+ Clear displayed messages
+ Remover mensagens
+
+
+
+ Cleared
+ Removidas
+
+
+
+ GroupChatForm
+
+
+ %1 users in chat
+ Number of users in chat
+ %1 usuários no grupo
+
+
+
+ %1 users in chat
+ %1 usuários no grupo
+
+
+
+ GroupWidget
+
+
+
+ %1 users in chat
+ %1 usuários no grupo
+
+
+
+
+ 0 users in chat
+ nenhum usuário no grupo
+
+
+
+ Set title...
+ Defina o título...
+
+
+
+ Quit group
+ Menu to quit a groupchat
+ Sair do grupo
+
+
+
+ Group title
+ Título do grupo
+
+
+
+ You can also set this by clicking the chat form name.
+Title:
+ É possível definir clicando no nome do grupo.
+Título:
+
+
+
+ IdentityForm
+
+
+ Identity
+ Identidade
+
+
+
+ Call active
+ popup title
+ Chamada ativa
+
+
+
+ You can't switch profiles while a call is active!
+ popup text
+ Não é possível trocar de perfil enquanto uma chamada estiver ativa!
+
+
+
+ Rename "%1"
+ renaming a profile
+ Renomear "%1"
+
+
+
+ Profile already exists
+ rename confirm title
+ O perfil já existe
+
+
+
+ A profile named "%1" already exists. Do you want to erase it?
+ rename confirm text
+ Um perfil chamado "%1" já existe. Deseja sobrescrevê-lo?
+
+
+
+ Export profile
+ save dialog title
+ Esportar perfil
+
+
+
+ Tox save file (*.tox)
+ save dialog filter
+ Armazenar arquivo Tox (*.tox)
+
+
+
+ Failed to remove file
+ Falha ao remover o arquivo
+
+
+
+ The file you chose to overwrite could not be removed first.
+ O arquivo escolhido para sobrescrever não pôde ser removido.
+
+
+
+ Failed to copy file
+ Falha ao copiar o arquivo
+
+
+
+ The file you chose could not be written to.
+ O arquivo que você escolheu não pôde ser escrito.
+
+
+
+ Profile currently loaded
+ current profile deletion warning title
+ Perfil carregado no momento
+
+
+
+ This profile is currently in use. Please load a different profile before deleting this one.
+ current profile deletion warning text
+ Esper perfil está atualmente em uso. Por favor carrege outro perfil antes de excluir este.
+
+
+
+ Deletion imminent!
+ deletion confirmation title
+ Exclusão iminente!
+
+
+
+ Are you sure you want to delete this profile?
+Associated friend information and chat logs will be deleted as well.
+ deletion confirmation text
+ Tem certeza que deseja excuir este perfil? As informações de contatos e histórico também serão removidos.
+
+
+
+ Import profile
+ import dialog title
+ Importar perfil
+
+
+
+ Tox save file (*.tox)
+ import dialog filter
+ Arquivo Tox (*.tox)
+
+
+
+ Ignoring non-Tox file
+ popup title
+ Ignorando arquivo não Tox
+
+
+
+ Warning: you've chosen a file that is not a Tox save file; ignoring.
+ popup text
+ Atenção: foi escolhido um arquivo que não é um arquivo Tox. Ignorando.
+
+
+
+ Profile already exists
+ import confirm title
+ O perfil já existe
+
+
+
+ A profile named "%1" already exists. Do you want to erase it?
+ import confirm text
+ Um perfil chamado "%1" já existe. Deseja sobrescrevê-lo?
+
+
+
+ IdentitySettings
+
+
+ Public Information
+ Informações Públicas
+
+
+
+ Name
+ Nome
+
+
+
+ Status
+ Status
+
+
+
+ Tox ID
+ ID Tox
+
+
+
+ Your Tox ID (click to copy)
+ Seu ID Tox (clique para copiar)
+
+
+
+ Profiles
+ Perfis
+
+
+
+ Available profiles:
+ Perfis disponíveis:
+
+
+
+
+ Switching profiles is disabled during calls
+ tooltip
+ alternar entre perfis não está habilitado durante chamadas
+
+
+
+ Load
+ load profile button
+ Carregar
+
+
+
+ Rename
+ rename profile button
+ Renomear
+
+
+
+ Export
+ export profile button
+ Exportar
+
+
+
+ This is useful to remain safe on public computers
+ delete profile button tooltip
+ Útil para ficar seguro em computadores públicos
+
+
+
+ Delete
+ delete profile button
+ Excluir
+
+
+
+ Import a profile
+ import profile button
+ Importar um perfil
+
+
+
+ New Tox ID
+ new profile button
+ Novo ID Tox
+
+
+
+ InputPasswordDialog
+
+
+ Password Dialog
+ Senha
+
+
+
+ Input password:
+ Digite sua Senha:
+
+
+
+ LoadHistoryDialog
+
+
+ Load History Dialog
+ Carregar Histórico
+
+
+
+ Load history from:
+ Carregar histórico de:
+
+
+
+ MainWindow
+
+
+ Your name
+ Seu nome
+
+
+
+ Your status
+ Seu status
+
+
+
+ Add friends
+ Adicionar contatos
+
+
+
+ Create a group chat
+ Criar um grupo
+
+
+
+ View completed file transfers
+ Ver transferências de arquivos completadas
+
+
+
+ Change your settings
+ Alterar suas configurações
+
+
+
+ Close
+ Fechar
+
+
+
+ NetCamView
+
+
+ Tox video
+ Vídeo Tox
+
+
+
+ PrivacyForm
+
+
+ Privacy
+ Privacidade
+
+
+
+ Encrypted log
+ Histórico criptografado
+
+
+
+ You already have history log file encrypted with different password
+Do you want to delete old history file?
+ Seu histórico foi criptografado com uma senha diferente.
+Você quer remover este arquivo de histórico antigo?
+
+
+
+ PrivacySettings
+
+
+ Send Typing Notifications
+ Enviar notificação de digitação
+
+
+
+ Keep History (unstable)
+ Manter histórico (instável)
+
+
+
+ Encryption
+ Criptografia
+
+
+
+ Encrypt Tox datafile
+ Criptografar os arquivos Tox
+
+
+
+ Encrypt History
+ Criptografar histórico
+
+
+
+ Nospam
+ Anti-span
+
+
+
+ HHHHHHHH
+ HHHHHHHH
+
+
+
+ Generate random nospam
+ Gerar um número anti-span aleatório
+
+
+
+ QObject
+
+
+ Update
+ The title of a message box
+ Atualizar
+
+
+
+ An update is available, do you want to download it now?
+It will be installed when qTox restarts.
+ Uma atualização está disponível, você deseja baixá-la agora?
+Ela será instalada quando o qTox for reiniciado.
+
+
+
+ Tox URI to parse
+ UTI Tox para interpretar
+
+
+
+ Starts new instance and loads specified profile.
+ Inicia uma nova instância e carrega o perfil especificado.
+
+
+
+ profile
+ perfil
+
+
+
+ Default
+ Padrão
+
+
+
+ Blue
+ Azul
+
+
+
+ Olive
+ Verde-oliva
+
+
+
+ Red
+ Vermelho
+
+
+
+ Violet
+ Violeta
+
+
+
+ Ignoring non-Tox file
+ popup title
+ Ignorando arquivo não Tox
+
+
+
+ Warning: you've chosen a file that is not a Tox save file; ignoring.
+ popup text
+ Atenção: foi escolhido um arquivo que não é um arquivo Tox. Ignorando.
+
+
+
+ Profile already exists
+ import confirm title
+ O perfil já existe
+
+
+
+ A profile named "%1" already exists. Do you want to erase it?
+ import confirm text
+ Um perfil chamado "%1" já existe. Deseja sobrescrevê-lo?
+
+
+
+ Profile imported
+ Perfil importado
+
+
+
+ %1.tox was successfully imported
+ %1.tox importado com sucesso
+
+
+
+ Tox me maybe?
+ Default message in Tox URI friend requests. Write something appropriate!
+ Olá! Gostaria de adicionar você aos meus contatos no Tox.
+
+
+
+ SetPasswordDialog
+
+
+ Type Password
+ Digite a Senha
+
+
+
+ Repeat Password
+ Repita a Senha
+
+
+
+ ToxDNS
+
+
+ The connection timed out
+ The DNS gives the Tox ID associated to toxme.se addresses
+ O tempo da conexão expirou
+
+
+
+ This address does not exist
+ The DNS gives the Tox ID associated to toxme.se addresses
+ Este endereço não existe
+
+
+
+ Error while looking up DNS
+ The DNS gives the Tox ID associated to toxme.se addresses
+ Erro ao consultar o DNS
+
+
+
+ No text record found
+ Error with the DNS
+ Nenhum registro encontrado
+
+
+
+ Unexpected number of values in text record
+ Error with the DNS
+ Número de entradas inesperado
+
+
+
+ The version of Tox DNS used by this server is not supported
+ Error with the DNS
+ A versão do DNS Tox utilizada por este servidor não é suportada
+
+
+
+ The DNS lookup does not contain any Tox ID
+ Error with the DNS
+ A resposta do DNS não contém nenhum ID Tox
+
+
+
+
+ The DNS lookup does not contain a valid Tox ID
+ Error with the DNS
+ A resposta do DNS não contém um ID Tox válido
+
+
+
+
+ It appears that qTox has to use the old tox1 protocol.
+Unfortunately tox1 is not secure. Should it be used anyway?
+ parece que o qTox está usando o protocolo tox1 antigo.
+Infelizmente o tox1 não é seguro. Deve ele ser usado mesmo assim?
+
+
+
+ ToxURIDialog
+
+
+ Add a friend
+ Title of the window to add a friend through Tox URI
+ Adicionar um contato
+
+
+
+ Do you want to add %1 as a friend?
+ Você deseja adicionar %1 como seu contato?
+
+
+
+ User ID:
+ ID do usuário:
+
+
+
+ Friend request message:
+ Mensagem de requisição contato:
+
+
+
+ Send
+ Send a friend request
+ Enviar
+
+
+
+ Cancel
+ Don't send a friend request
+ Cancelar
+
+
+
+ Widget
+
+
+ Online
+ Online
+
+
+
+ Away
+ Ausente
+
+
+
+ Busy
+ Ocupado
+
+
+
+ &Quit
+ &Sair
+
+
+
+ Online
+ Button to set your status to 'Online'
+ Online
+
+
+
+ Away
+ Button to set your status to 'Away'
+ Ausente
+
+
+
+ Busy
+ Button to set your status to 'Busy'
+ Ocupado
+
+
+
+ Choose a profile
+ Escolha um perfil
+
+
+
+ Please choose which identity to use
+ Por favor escolha qual identidade usar
+
+
+
+ Choose a profile picture
+ Escolha uma imagem para o perfil
+
+
+
+
+
+ Error
+ Erro
+
+
+
+ Unable to open this file
+ Não foi possível abrir este arquivo
+
+
+
+ Unable to read this image
+ Não foi possível ler esta imagem
+
+
+
+ This image is too big
+ Esta imagem é muito grande
+
+
+
+ Toxcore failed to start, the application will terminate after you close this message.
+ O Toxcore falhou ao inicializar, a aplicação será finalizada assim que esta mensagem for fechada.
+
+
+
+ toxcore failed to start with your proxy settings. qTox cannot run; please modify your settings and restart.
+ popup text
+ O Toxcore falhou ao inicializar suas configurações de proxy. O qTox não pode ser executado, por favor modifique suas configurações e reinicialize o aplicativo.
+
+
+
+ Add friend
+ Adicionar contato
+
+
+
+ File transfers
+ Transferências de arquivo
+
+
+
+ Settings
+ Configurações
+
+
+
+ Couldn't request friendship
+ Não foi possível adicionar o contato
+
+
+
+ away
+ contact status
+ ausente
+
+
+
+ busy
+ contact status
+ ocupado
+
+
+
+ offline
+ contact status
+ offline
+
+
+
+ online
+ contact status
+ online
+
+
+
+ %1 is now %2
+ e.g. "Dubslow is now online"
+ %1 agora é %2
+
+
+
+ <Unknown>
+ Placeholder when we don't know someone's name in a group chat
+ <Desconhecido>
+
+
+
+ %1 has set the title to %2
+ %1 alterou o título para %2
+
+
+
+ Message failed to send
+ Falha no envio da mensagem
+
+
+
diff --git a/translations/ru.ts b/translations/ru.ts
index c7d4fbd76..731d53ce2 100644
--- a/translations/ru.ts
+++ b/translations/ru.ts
@@ -12,12 +12,12 @@
AVSettings
-
+ Video SettingsНастройки видео
-
+ ResolutionРазрешение
@@ -47,22 +47,32 @@
Устройство записи
-
+
+ Rescan audio devices
+ Повторить поиск аудиоустройств
+
+
+
+ Filter audio
+ Фильтрация звука
+
+
+ HueТон
-
+ BrightnessЯркость
-
+ SaturationНасыщенность
-
+ ContrastКонтраст
@@ -113,8 +123,14 @@
qTox needs to use the Tox DNS, but can't do it through a proxy.
-Ignore the proxy and connect to the Internet directly ?
+Ignore the proxy and connect to the Internet directly?
qTox необходимо воспользоваться Tox DNS, но это нельзя сделать через прокси.
+Игнорировать прокси и подлючиться напрямую через интернет?
+
+
+ qTox needs to use the Tox DNS, but can't do it through a proxy.
+Ignore the proxy and connect to the Internet directly ?
+ qTox необходимо воспользоваться Tox DNS, но это нельзя сделать через прокси.
Игнорировать прокси и подлючиться напрямую через интернет?
@@ -152,7 +168,7 @@ Ignore the proxy and connect to the Internet directly ?
Form
-
+ Form
@@ -183,48 +199,68 @@ Ignore the proxy and connect to the Internet directly ?
Загрузить историю...
-
+ Send a fileОтправить файл
+ File not read
+ Файл не прочитать
+
+
+
+ qTox wasn't able to open %1
+ Паравозик не смог. Не сможешь и ты!
+ qTox не смог открыть %1
+
+
+ Bad IdeaПлохая идея
-
+ You're trying to send a special (sequential) file, that's not going to work!...передаёте последовательный файл и получаете te-le-fun-ken. И переводчик работает по другой линии. По линии «Библиотека».Вы пытаетесь отправить специальный (последовательный) файл. Это так не работает!
-
- %1 calling
+
+ %1 is calling%1 звонит
-
+ %1 calling
+ %1 звонит
+
+
+ %1 stopped calling%1 прекратил звонить
-
+ Calling to %1Звоним %1
-
+ Call rejectedЗвонок отклонён
-
+
+ Failed to send file "%1"
+ Не удалось отправить файл «%1»
+
+
+ Call with %1 ended. %2Разговор с %1 завершился. %2
-
+ Call duration: Длительность разговора:
@@ -240,106 +276,120 @@ Ignore the proxy and connect to the Internet directly ?
Core
-
+ Toxing on qToxКак-то так. Может, можно ещё что-нибудь придумать?Всем привет из qTox'а
-
+ qTox UserПользователь qTox
-
+ Friend is already addedДруг уже добавлен
-
+ Encryption errorОшибка шифрования
-
+ The .tox file is encrypted, but encryption was not checked, continuing regardless.Файл .tox зашифрован, однако шифрование в настройках включено не было. Продолжаем вопреки.
-
+ Tox datafile decryption passwordПароль для расшифровки файла данных Tox
-
-
-
+
+
+ Password errorОшибка пароля
-
-
+
+ Failed to setup password.
Empty password.Не удалось установить пароль.
Пустой пароль.
-
+ Try AgainПопробуйте ещё
-
+ Change profileСменить профиль
-
+ Reinit current profileУвы, никто не знает, что разработчики имели в виду. Ту би транслейтед.Сбросить данные текущего профиля
-
+ Wrong password has been enteredВведён неправильный пароль
-
+ History Log decryption passwordПароль для расшифровки журнала переписки
-
+ Encrypted logЗашифрованный журнал
-
+
+ Your history is encrypted with different password.
+Do you want to try another password?
+ Ваша переписка зашифрована другим паролем.
+Ходите попробовать другой пароль?
+
+
+
+ History
+ История
+
+
+
+ Due to incorret password history will be disabled.
+ Из-за некорректного пароля журналирование будет отключено.
+
+ Your history is encrypted with different password
Do you want to try another password?
- Ваша переписка зашифрована другим паролем
+ Ваша переписка зашифрована другим паролем
Ходите попробовать другой пароль?
- Loggin
- Журналирование
+ Журналирование
- Due to incorret password logging will be disabled
- Из-за некорректного пароля журналирование будет отключено
+ Из-за некорректного пароля журналирование будет отключено
-
+ NO PasswordБЕЗ пароля
-
+ Will be saved without encryption!Будет сохранено без шифрования!
@@ -466,14 +516,20 @@ Do you want to try another password?
Выбрать папку для автоматического приёма
-
+ User aliasПсевдоним пользователя
-
+
+ You can also set this by clicking the chat form name.
+Alias:
+ Можно также установить, щёлкнув по имени вверху окна чата.
+Псевдоним:
+
+ Alias:
- Новый псевдоним:
+ Новый псевдоним:
@@ -484,25 +540,25 @@ Do you want to try another password?
Общие
-
-
+
+ NoneОтсутствует
-
+ Choose an auto accept directorypopup titleВыбрать папку для автоматического приёма
-
+ Call activepopup titleИдёт звонок
-
+ You can't disconnect while a call is active!popup textНельзя отключиться пока идёт звонок!
@@ -522,130 +578,140 @@ Do you want to try another password?
Перевод не изменится до перезапуска qTox.
-
+
+ System tray integration
+ Настройки трея
+
+
+ Show system tray iconПоказывать иконку в трее
-
+ Close to trayСворачивать в трей при закрытии
-
+ Minimize to trayСворачивать в трей
-
+
+ Light icon
+ Светлая иконка
+
+
+ Check for updates on startup (unstable)Проверять на наличие обновлений (нестабильно)
-
+ Focus qTox when a message is receivedЗахватывать фокус при приёме сообщений
-
+ Faux offline messagingИмитация офлайнового обмена сообщениями
-
+ Auto away after (0 to disable)Менять статус на «Отошёл» после (0 — не менять)
-
+ Set to 0 to disableУкажите 0, чтобы отключить
-
+ You can set this on a per-friend basis by right clicking them.autoaccept cb tooltipМожно настроить отдельно для каждого друга (щёлкнув правой кнопкой мыши по другу и выбрав соответствующий пункт меню).
-
+ Use emoticonsИспользовать смайлики
-
+ Smiley PackText on smiley pack labelНабор смайликов
-
+ StyleСтиль
-
+ Theme colorЦвет темы
-
+ Emoticon sizeРазмер смайликов
-
+ pxПо аналогии с Мпикс. Хотя, может лучше принять http://ilyabirman.ru/meanwhile/all/px/? пикс
-
+ Timestamp formatФормат времени
-
+ Connection SettingsНастройки соединения
-
+ Enable IPv6 (recommended)Text on a checkbox to enable IPv6Включить IPv6 (рекомендуется)
-
+ Disabling this allows, e.g., toxing over Tor. It adds load to the Tox network however, so uncheck only when necessary.force tcp checkbox tooltipОтключение позволяет, например, использовать Tox поверх Tor. Однако это добавляет нагрузку на сеть Tox, так что отключайте только в случае необходимости.
-
+ Enable UDP (recommended)Text on checkbox to disable UDPВключить UDP (рекомендуется)
-
+ Use proxy (SOCKS5)Использовать прокси (SOCKS5)
-
+ AddressText on proxy addr labelАдрес
-
+ PortText on proxy port labelПорт
-
+ Reconnectreconnect buttonПереподключиться
@@ -667,42 +733,42 @@ Do you want to try another password?
Портативный режим
-
+ Start in trayЗапускать свёрнутым в трей
-
+ Show contacts' status changesПоказывать изменения статусов контактов
-
+ Provided in minutesВыставлено в минутах
-
+ minutes минут
-
+ Autoaccept filesАвтоматически принимать файлы
-
+ Save files inСохранять в
-
+ PushButton
-
+ ThemeТема
@@ -710,53 +776,53 @@ Do you want to try another password?
GenericChatForm
-
+ Send messageОтправить сообщение
-
+ SmileysСмайлики
-
+ Send file(s)Отправить файл(ы)
-
+ Audio call: RED means you're on a call
- Позвонить, только аудио (красная кнопка значит что вы на связи)
+ Позвонить, только аудио (красная кнопка означает что вы на связи)
-
+ Video call: RED means you're on a call
- Видеозвонок (красная кнопка значит что вы на связи)
+ Видеозвонок (красная кнопка означает что вы на связи)
-
+ Toggle speakers volume: RED is OFF
- Включить или выключить звук (красная кнопка значит что звук выключен)
+ Включить или выключить звук (красная кнопка означает что звук выключен)
-
+ Toggle microphone: RED is OFF
- Включить или выключить микрофон (красная кнопка значит что микрофон выключен)
+ Включить или выключить микрофон (красная кнопка означает что микрофон выключен)
-
-
+
+ Save chat logСохранить журнал чата
-
+ Clear displayed messagesОчистить показываемые сообщения
-
+ ClearedОчищено
@@ -764,13 +830,13 @@ Do you want to try another password?
GroupChatForm
-
+ %1 users in chatNumber of users in chat%1 пользователей в чате
-
+ %1 users in chat%1 пользователей в чате
@@ -778,23 +844,40 @@ Do you want to try another password?
GroupWidget
-
+ Quit groupMenu to quit a groupchatПокинуть группу
-
-
+
+ %1 users in chat%1 пользователей в чате
-
-
+
+ 0 users in chatНи одного пользователя в чате
+
+
+ Set title...
+ Установить заголовок...
+
+
+
+ Group title
+ Заголовок группы
+
+
+
+ You can also set this by clicking the chat form name.
+Title:
+ Можно также установить, щёлкнув по заголовку вверху окна чата.
+Заголовок:
+ IdentityForm
@@ -885,42 +968,49 @@ Do you want to try another password?
+ Are you sure you want to delete this profile?
+Associated friend information and chat logs will be deleted as well.
+ deletion confirmation text
+ Вы действительно хотите удалить этот профиль?
+Связанная с ним информация о друзьях и история переписки будут также удалены.
+
+ Are you sure you want to delete this profile?deletion confirmation text
- Вы действительно хотите удалить этот профиль?
+ Вы действительно хотите удалить этот профиль?
-
+ Import profileimport dialog titleИмпортировать профиль
-
+ Tox save file (*.tox)import dialog filterФайл Tox (*.tox)
-
+ Ignoring non-Tox filepopup titleВыбран не файл Tox
-
+ Warning: you've chosen a file that is not a Tox save file; ignoring.popup textВнимание: вы выбрали не файл Tox; игнорирование.
-
+ Profile already existsimport confirm titleПрофиль уже существует
-
+ A profile named "%1" already exists. Do you want to erase it?import confirm textПрофиль с именем «%1» уже существует. Перезаписать?
@@ -1151,16 +1241,22 @@ Do you want to delete old history file?
QObject
-
+ UpdateThe title of a message boxОбновление
-
+
+ An update is available, do you want to download it now?
+It will be installed when qTox restarts.
+ Обновление доступно, не желаете ли скачать его прямо сейчас?
+Оно будет установлено после того, как qTox будет перезапущен.
+
+ An update is available, do you want to download it now ?
It will be installed when qTox restarts.
- Обновление доступно, не желаете ли скачать его прамо сейчас?
+ Обновление доступно, не желаете ли скачать его прамо сейчас?
Оно будет установлено после того, как qTox будет перезапущен.
@@ -1209,6 +1305,18 @@ It will be installed when qTox restarts.
Без перевода, так как весь остальной CLI на английскомTox URI to parse
+
+
+ Starts new instance and loads specified profile.
+ Без перевода, так как весь остальной CLI на английском
+ Starts new instance and loads specified profile.
+
+
+
+ profile
+ Без перевода, так как весь остальной CLI на английском
+ profile
+ Default
@@ -1309,8 +1417,12 @@ It will be installed when qTox restarts.
Добавить друга
- Do you want to add %1 as a friend ?
+ Хотите добавить %1 в друзья?
+
+
+
+ Do you want to add %1 as a friend?Хотите добавить %1 в друзья?
@@ -1339,160 +1451,160 @@ It will be installed when qTox restarts.
Widget
-
+ OnlineВ сети
-
+ AwayОтошёл
-
+ BusyЗанят
-
+ &QuitВ&ыход
-
+ Change status to:Сменить статус на:
-
+ OnlineButton to set your status to 'Online'В сети
-
+ AwayButton to set your status to 'Away'Вероятно, это не столь долгое путешествиеОтошёл
-
+ BusyButton to set your status to 'Busy'Занят
-
+ Choose a profileВыберите профиль
-
+ Please choose which identity to useВыберите личность, которую хотите использовать
-
+ Choose a profile pictureВыбрать картинку для профиля
-
-
-
+
+
+ ErrorОшибка
-
+ Unable to open this fileНевозможно открыть файл
-
+ Unable to read this imageНевозможно прочесть это изображение
-
+ This image is too bigЭто изображение слишком большое
-
+ Toxcore failed to start, the application will terminate after you close this message.Не удалось запустить toxcore, приложение будет завершено после того как вы закроете это сообщение.
-
+ toxcore failed to start with your proxy settings. qTox cannot run; please modify your settings and restart.popup textНе удалось запустить toxcore с вашими настройками прокси, qTox не может работать; измените ваши настройки и перезапустите его.
-
+ Add friendДобавить друга
-
+ File transfersПередачи файлов
-
+ SettingsНастройки
-
+ Couldn't request friendshipНе удалось запросить добавление в друзья
-
+ awaycontact statusотсутствует
-
+ busycontact statusзанят
-
+ offlinecontact statusофлайн
-
+ onlinecontact statusв сети
-
+ %1 is now %2e.g. "Dubslow is now online"%1 сейчас %2
-
+ <Unknown>Placeholder when we don't know someone's name in a group chat<Неизвестный>
-
+ %1 has set the title to %2%1 сменил заголовок на %2
-
+ Message failed to sendНе удалось отправить сообщение
diff --git a/translations/uk.ts b/translations/uk.ts
index a2ecf9015..51953bc5d 100644
--- a/translations/uk.ts
+++ b/translations/uk.ts
@@ -37,32 +37,42 @@
Пристрій захоплення
-
+
+ Rescan audio devices
+ Пересканувати аудіо пристрої
+
+
+
+ Filter audio
+ Фільтр звуку
+
+
+ Video SettingsПараметри відео
-
+ ResolutionРоздільна здатність
-
+ HueВідтінок
-
+ BrightnessЯскравість
-
+ SaturationНасиченість
-
+ ContrastКонтраст
@@ -112,7 +122,7 @@
qTox needs to use the Tox DNS, but can't do it through a proxy.
-Ignore the proxy and connect to the Internet directly ?
+Ignore the proxy and connect to the Internet directly?
qTox потребує Tox DNS, але не може скористатися ним через проксі.
Проігнорувати проксі та під'єднатися напряму?
@@ -177,52 +187,72 @@ Ignore the proxy and connect to the Internet directly ?
ChatForm
-
+ Load History...Завантажити історію…
-
+ Send a fileНадіслати файл
-
+
+ File not read
+ Файл не читається
+
+
+
+ qTox wasn't able to open %1
+ qTox не може відкрити файл %1
+
+
+ Bad IdeaПогана ідея
-
+ You're trying to send a special (sequential) file, that's not going to work!Ви намагаєтесь передати спеціальний (послідовний) файл, це не так працює!
-
- %1 calling
- %1 викликає
+
+ %1 is calling
+ %1 дзвонить
-
+ %1 stopped calling%1 припинив виклик
-
+ Calling to %1Викликаємо %1
-
+
+ Failed to send file "%1"
+ Не вдалось відправити файл «%1»
+
+
+ Call with %1 ended. %2Виклик із %1 завершено. %2
-
+ Call duration: Тривалість дзвінка:
-
+
+ is typing...
+ набирає...
+
+
+ Call rejectedДзвінок відхилено
@@ -238,104 +268,104 @@ Ignore the proxy and connect to the Internet directly ?
Core
-
+ Toxing on qToxВітання з qTox
-
+ qTox UserКористувач qTox
-
+ Friend is already addedДруга вже додано
-
+ Encryption errorПомилка шифрування
-
+ The .tox file is encrypted, but encryption was not checked, continuing regardless.Файл .tox зашифровано, але шифрування не перевірено, попри це продовжуємо.
-
+ Tox datafile decryption passwordРозшифрування файлу даних Tox
-
-
-
+
+
+ Password errorПомилка паролю
-
-
+
+ Failed to setup password.
Empty password.Не вдалось встановити пароль.
Пароль пустий.
-
+ Try AgainСпробуйте ще раз
-
+ Change profileЗмінити профіль
-
+ Reinit current profileПере ініціалізувати поточний профіль
-
+ Wrong password has been enteredВведено хибний пароль
-
+ History Log decryption passwordРозшифрування історії
-
- Your history is encrypted with different password
+
+ Your history is encrypted with different password.
Do you want to try another password?
- Ваша історія зашифрована інакшим паролем
+ Ваша історія зашифрована інакшим паролем.
Бажаєте спробувати інший пароль?
-
- Encrypted log
- Зашифрований звіт
+
+ History
+ Історія
-
- Loggin
- Звітування
+
+ Due to incorret password history will be disabled.
+ Введено некоректний пароль, звітування вимкнено.
-
- Due to incorret password logging will be disabled
- Введено некоректний пароль, звітування вимкнено
+
+ Encrypted log
+ Зашифрований звіт
-
+ NO PasswordВідсутній пароль
-
+ Will be saved without encryption!Буде збережено без шифрування!
@@ -447,14 +477,16 @@ Do you want to try another password?
Автоматично приймати файли від даного друга
-
+ User aliasПсевдонім користувача
-
- Alias:
- Псевдонім:
+
+ You can also set this by clicking the chat form name.
+Alias:
+ Ви також можете встановити його натиснувши на назву форми в чаті.
+Псевдонім:
@@ -477,25 +509,25 @@ Do you want to try another password?
Основні
-
-
+
+ NoneВідсутній
-
+ Choose an auto accept directorypopup titleОберіть теку, для автоматичного отримання файлів
-
+ Call activepopup titleДзвінок активний
-
+ You can't disconnect while a call is active!popup textВи не можете від'єднатись під час активного дзвінка!
@@ -526,47 +558,52 @@ Do you want to try another password?
Портативний запуск
-
+
+ System tray integration
+ Інтеграція із системним лотком
+
+
+ Show system tray icon
- Показувати піктрограму в системному лотку
+ Показувати піктограму в системному лотку
-
+ Start in trayЗапускати у системному лотку
-
+ Close to trayЗакривати до лотку
-
+ Minimize to trayМінімізувати до лотку
-
+ Show contacts' status changesПоказувати зміну статусів контактів
-
+ Provided in minutesВстановлено в хвилинах
-
+ Set to 0 to disableВстановіть 0, аби вимкнути
-
+ minutes хвилин
-
+ ThemeГрафічна тема
@@ -576,128 +613,148 @@ Do you want to try another password?
Мова інтерфейсу
- Show system tray
- Показувати в системному лотку
+
+ Light icon
+ Світлі піктограми
-
+ Check for updates on startup (unstable)Перевіряти оновлення під час запуску (нестабільна функція)
-
+ Focus qTox when a message is receivedПерехоплювати фокус вікна при отриманні повідомлення
-
+ Faux offline messagingФальшивий поза мережевий обмін повідомленнями
-
+ Auto away after (0 to disable)Авто-статус «Відійшов» (0=вимкнено)
-
+ You can set this on a per-friend basis by right clicking them.autoaccept cb tooltip
-
+ Ви також можете встановити це значення до кожного друга окремо викликавши правою кнопкою меню навпроти нього.
-
+ Autoaccept filesАвтоматично приймати файли
-
+ Save files inЗберігати файли до
-
+ PushButtonТисніть кнопку
-
+ Use emoticonsВикористовувати смайлики
-
+ Smiley PackText on smiley pack labelПакунок смайликів
-
+ StyleСтиль
-
+ Theme colorКолір графічної теми
-
+ Emoticon sizeРозмір смайликів
-
+ px px
-
+ Timestamp formatФормати часового відбитку
-
+ Connection SettingsПараметри підключення
-
+ Enable IPv6 (recommended)Text on a checkbox to enable IPv6Дозволити IPv6 (рекомендовано)
-
+ Disabling this allows, e.g., toxing over Tor. It adds load to the Tox network however, so uncheck only when necessary.force tcp checkbox tooltip
-
+ Enable UDP (recommended)Text on checkbox to disable UDPДозволити UDP (рекомендовано)
-
+
+ Proxy type
+ Тип проксі
+
+
+
+ None
+ Відсутній
+
+
+
+ SOCKS5
+ SOCKS5
+
+
+
+ HTTP
+ HTTP
+
+ Use proxy (SOCKS5)
- Використовувати проксі (SOCKS5)
+ Використовувати проксі (SOCKS5)
-
+ AddressText on proxy addr labelАдреса
-
+ PortText on proxy port labelПорт
-
+ Reconnectreconnect buttonПовторно під'єднатись
@@ -706,53 +763,53 @@ Do you want to try another password?
GenericChatForm
-
+ Send messageВідправити повідомлення
-
+ SmileysСмайлики
-
+ Send file(s)Відправити файл(и)
-
+ Audio call: RED means you're on a callАудіо дзвінок: Червоний - дзвінок активний
-
+ Video call: RED means you're on a callВідео дзвінок: Червоний - дзвінок активний
-
+ Toggle speakers volume: RED is OFFПеремкнути стан гучності відтворення: Червоний - вимкнено
-
+ Toggle microphone: RED is OFFПеремкнути рівень підсилення мікрофону: Червоний - вимкнено
-
-
+
+ Save chat logЗберегти чат
-
+ Clear displayed messagesОчистити показані повідомлення
-
+ ClearedОчищено
@@ -760,13 +817,13 @@ Do you want to try another password?
GroupChatForm
-
+ %1 users in chatNumber of users in chatКористувачів у чаті: %1
-
+ %1 users in chatКористувачів у чаті: %1
@@ -774,23 +831,40 @@ Do you want to try another password?
GroupWidget
-
-
+
+ %1 users in chatКористувачів у чаті: %1
-
-
+
+ 0 users in chatНемає користувачів
-
+ Quit groupMenu to quit a groupchatВийти з групи
+
+
+ Set title...
+ Встановити заголовок…
+
+
+
+ Group title
+ Заголовок групи
+
+
+
+ You can also set this by clicking the chat form name.
+Title:
+ Ви також можете встановити його натиснувши на назву форми в чаті.
+Заголовок:
+ IdentityForm
@@ -881,42 +955,44 @@ Do you want to try another password?
- Are you sure you want to delete this profile?
+ Are you sure you want to delete this profile?
+Associated friend information and chat logs will be deleted as well.deletion confirmation text
- Дійсно вилучити даний профіль?
+ Дійсно вилучити даний профіль?
+Пов'язана інформація про друзів та історія спілкування також буде вилучена.
-
+ Import profileimport dialog titleІмпортувати профіль
-
+ Tox save file (*.tox)import dialog filterФайл збереження Tox (*.tox)
-
+ Ignoring non-Tox filepopup titleІгнорування не Tox файлу
-
+ Warning: you've chosen a file that is not a Tox save file; ignoring.popup textУвага: вказаний вами файл не є файлом збереження Tox; ігнорую.
-
+ Profile already existsimport confirm titleПрофіль вже існує
-
+ A profile named "%1" already exists. Do you want to erase it?import confirm textПрофіль із назвою «%1» вже існує. Бажаєте стерти його?
@@ -1104,9 +1180,13 @@ Do you want to delete old history file?
PrivacySettings
- Typing Notification
- Увімкнути сповіщення про набір
+ Увімкнути сповіщення про набір
+
+
+
+ Send Typing Notifications
+ Надсилати сповіщення про набір
@@ -1187,14 +1267,14 @@ Do you want to delete old history file?
%1.tox успішно імпортовано
-
+ UpdateThe title of a message boxОновити
-
- An update is available, do you want to download it now ?
+
+ An update is available, do you want to download it now?
It will be installed when qTox restarts.Доступне оновлення, бажаєте завантажити його зараз?
Оновлення буде встановлено після перезапуску qTox.
@@ -1204,6 +1284,16 @@ It will be installed when qTox restarts.Tox URI to parseTox URI для розбору
+
+
+ Starts new instance and loads specified profile.
+
+
+
+
+ profile
+ профіль
+ Default
@@ -1294,6 +1384,13 @@ It will be installed when qTox restarts.
Error with the DNSВідповідь DNS не містить жодного коректного Tox ID
+
+
+
+ It appears that qTox has to use the old tox1 protocol.
+Unfortunately tox1 is not secure. Should it be used anyway?
+
+ ToxURIDialog
@@ -1305,7 +1402,7 @@ It will be installed when qTox restarts.
- Do you want to add %1 as a friend ?
+ Do you want to add %1 as a friend?Бажаєте додати %1 як друга?
@@ -1334,159 +1431,158 @@ It will be installed when qTox restarts.
Widget
-
+ OnlineВ мережі
-
+ AwayВідійшов
-
+ BusyЗайнятий
-
+ &Quit&Вийти
- Change status to:
- Змінити статус на:
+ Змінити статус на:
-
+ OnlineButton to set your status to 'Online'В мережі
-
+ AwayButton to set your status to 'Away'Відійшов
-
+ BusyButton to set your status to 'Busy'Зайнятий
-
+ Choose a profileОберіть профіль
-
+ Please choose which identity to useОберіть ідентифікатор для використання
-
+ Choose a profile pictureОберіть зображення для профілю
-
-
-
+
+
+ ErrorПомилка
-
+ Unable to open this fileНеможливо відкрити цей файл
-
+ Unable to read this imageНеможливо прочитати це зображення
-
+ This image is too bigЗображення завелике
-
+ Toxcore failed to start, the application will terminate after you close this message.Помилка запуску ядра tox, програма буде завершена після закриття цього повідомлення.
-
+ toxcore failed to start with your proxy settings. qTox cannot run; please modify your settings and restart.popup textПомилка запуску ядра tox із поточними параметрами проксі. qTox не працює; змініть параметри і перезапустіть.
-
+ Add friendДодати друга
-
+ File transfersПередачі файлів
-
+ SettingsПараметри
-
+ Couldn't request friendshipНе вдалось надіслати запит на дружбу
-
+ awaycontact statusВідійшов
-
+ busycontact statusЗайнятий
-
+ offlinecontact statusПоза мережею
-
+ onlinecontact statusВ мережі
-
+ %1 is now %2e.g. "Dubslow is now online"%1 тепер вже відомий як %2
-
+ <Unknown>Placeholder when we don't know someone's name in a group chat<Невідомо>
-
+ %1 has set the title to %2%1 встановив тему %2
-
+ Message failed to sendНе вдалось відправити повідомлення
diff --git a/ui/chatArea/chatHead.css b/ui/chatArea/chatHead.css
index b953e86e5..206e09883 100644
--- a/ui/chatArea/chatHead.css
+++ b/ui/chatArea/chatHead.css
@@ -1,3 +1,9 @@
+QLineEdit {
+ color: @black;
+ background: white;
+ border: 0px;
+}
+
#nameLabel {
color: @black;
font: @mediumBold;
diff --git a/ui/chatArea/innerStyle.css b/ui/chatArea/innerStyle.css
index dc1f46d73..286775142 100644
--- a/ui/chatArea/innerStyle.css
+++ b/ui/chatArea/innerStyle.css
@@ -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;
+}
diff --git a/ui/volButton/volButton.css b/ui/volButton/volButton.css
index 3bf4d64a8..8210f4819 100644
--- a/ui/volButton/volButton.css
+++ b/ui/volButton/volButton.css
@@ -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 {
diff --git a/ui/volButton/volButton.png b/ui/volButton/volButton.png
index a1c474eab..b07c13209 100644
Binary files a/ui/volButton/volButton.png and b/ui/volButton/volButton.png differ
diff --git a/ui/volButton/volButtonHover.png b/ui/volButton/volButtonHover.png
index 82c126c8f..4a5e47d97 100644
Binary files a/ui/volButton/volButtonHover.png and b/ui/volButton/volButtonHover.png differ
diff --git a/ui/volButton/volButtonPressed.png b/ui/volButton/volButtonPressed.png
index e0078285e..c2379c1c9 100644
Binary files a/ui/volButton/volButtonPressed.png and b/ui/volButton/volButtonPressed.png differ