mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Merge pull request #414 from dubslow/profiles
Profiles -- they actually work!!!!!!!
This commit is contained in:
commit
259a1d042b
122
src/core.cpp
122
src/core.cpp
|
@ -39,11 +39,12 @@
|
|||
#include <QMessageBox>
|
||||
|
||||
const QString Core::CONFIG_FILE_NAME = "data";
|
||||
const QString Core::TOX_EXT = ".tox";
|
||||
QList<ToxFile> Core::fileSendQueue;
|
||||
QList<ToxFile> Core::fileRecvQueue;
|
||||
|
||||
Core::Core(Camera* cam, QThread *coreThread) :
|
||||
tox(nullptr), camera(cam)
|
||||
Core::Core(Camera* cam, QThread *coreThread, QString loadPath) :
|
||||
tox(nullptr), camera(cam), loadPath(loadPath)
|
||||
{
|
||||
videobuf = new uint8_t[videobufsize];
|
||||
videoBusyness=0;
|
||||
|
@ -117,12 +118,11 @@ Core* Core::getInstance()
|
|||
return Widget::getInstance()->getCore();
|
||||
}
|
||||
|
||||
void Core::start()
|
||||
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();
|
||||
|
||||
if (enableIPv6)
|
||||
|
@ -205,16 +205,25 @@ void Core::start()
|
|||
emit failedToStart();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Core::start()
|
||||
{
|
||||
make_tox();
|
||||
|
||||
qsrand(time(nullptr));
|
||||
|
||||
if (!loadConfiguration())
|
||||
if (loadPath != "")
|
||||
{
|
||||
if (!loadConfiguration(loadPath)) // loadPath is meaningless after this
|
||||
{
|
||||
emit failedToStart();
|
||||
tox_kill(tox);
|
||||
tox = nullptr;
|
||||
return;
|
||||
}
|
||||
loadPath = "";
|
||||
}
|
||||
|
||||
tox_callback_friend_request(tox, onFriendRequest, this);
|
||||
tox_callback_friend_message(tox, onFriendMessage, this);
|
||||
|
@ -273,9 +282,9 @@ void Core::start()
|
|||
* 5 disconnected; 4 were DCd for less than 20 ticks, while the 5th was ~50 ticks.
|
||||
* So I set the tolerance here at 25, and initial DCs should be very rare now.
|
||||
* This should be able to go to 50 or 100 without affecting legitimate disconnects'
|
||||
* downtime, but lets be conservative for now. Edit: now 40.
|
||||
* downtime, but lets be conservative for now. Edit: now ~~40~~ 30.
|
||||
*/
|
||||
#define CORE_DISCONNECT_TOLERANCE 40
|
||||
#define CORE_DISCONNECT_TOLERANCE 30
|
||||
|
||||
void Core::process()
|
||||
{
|
||||
|
@ -627,8 +636,8 @@ void Core::onAvatarInfoCallback(Tox*, int32_t friendnumber, uint8_t format,
|
|||
{
|
||||
qDebug() << "Core: Got null avatar info from" << core->getFriendUsername(friendnumber);
|
||||
emit core->friendAvatarRemoved(friendnumber);
|
||||
QFile::remove(QDir(Settings::getInstance().getSettingsDirPath()).filePath("avatars/"+core->getFriendAddress(friendnumber).left(64)+".png"));
|
||||
QFile::remove(QDir(Settings::getInstance().getSettingsDirPath()).filePath("avatars/"+core->getFriendAddress(friendnumber).left(64)+".hash"));
|
||||
QFile::remove(QDir(Settings::getSettingsDirPath()).filePath("avatars/"+core->getFriendAddress(friendnumber).left(64)+".png"));
|
||||
QFile::remove(QDir(Settings::getSettingsDirPath()).filePath("avatars/"+core->getFriendAddress(friendnumber).left(64)+".hash"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -918,6 +927,8 @@ void Core::acceptFileRecvRequest(int friendId, int fileNum, QString path)
|
|||
|
||||
void Core::removeFriend(int friendId)
|
||||
{
|
||||
if (!tox)
|
||||
return;
|
||||
if (tox_del_friend(tox, friendId) == -1) {
|
||||
emit failedToRemoveFriend(friendId);
|
||||
} else {
|
||||
|
@ -928,6 +939,8 @@ void Core::removeFriend(int friendId)
|
|||
|
||||
void Core::removeGroup(int groupId)
|
||||
{
|
||||
if (!tox)
|
||||
return;
|
||||
tox_del_groupchat(tox, groupId);
|
||||
}
|
||||
|
||||
|
@ -949,8 +962,8 @@ void Core::setUsername(const QString& username)
|
|||
if (tox_set_name(tox, cUsername.data(), cUsername.size()) == -1) {
|
||||
emit failedToSetUsername(username);
|
||||
} else {
|
||||
saveConfiguration();
|
||||
emit usernameSet(username);
|
||||
saveConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -981,6 +994,13 @@ ToxID Core::getSelfId()
|
|||
return ToxID::fromString(CFriendAddress::toString(friendAddress));
|
||||
}
|
||||
|
||||
QString Core::getIDString()
|
||||
{
|
||||
return getSelfId().toString().left(12);
|
||||
// 12 is the smallest multiple of four such that
|
||||
// 16^n > 10^10 (which is roughly the planet's population)
|
||||
}
|
||||
|
||||
QString Core::getStatusMessage()
|
||||
{
|
||||
int size = tox_get_self_status_message_size(tox);
|
||||
|
@ -1038,11 +1058,25 @@ void Core::onFileTransferFinished(ToxFile file)
|
|||
emit fileDownloadFinished(file.filePath);
|
||||
}
|
||||
|
||||
bool Core::loadConfiguration()
|
||||
QString Core::sanitize(QString name)
|
||||
{
|
||||
QString path = QDir(Settings::getSettingsDirPath()).filePath(CONFIG_FILE_NAME);
|
||||
// these are pretty much Windows banned filename characters
|
||||
QList<QChar> banned = {'/', '\\', ':', '<', '>', '"', '|', '?', '*'};
|
||||
for (QChar c : banned)
|
||||
name.replace(c, '_');
|
||||
// also remove leading and trailing periods
|
||||
if (name[0] == '.')
|
||||
name[0] = '_';
|
||||
if (name.endsWith('.'))
|
||||
name[name.length()-1] = '_';
|
||||
return name;
|
||||
}
|
||||
|
||||
bool Core::loadConfiguration(QString path)
|
||||
{
|
||||
// setting the profile is now the responsibility of the caller
|
||||
QFile configurationFile(path);
|
||||
qDebug() << "Core::loadConfiguration: reading from " << path;
|
||||
|
||||
if (!configurationFile.exists()) {
|
||||
qWarning() << "The Tox configuration file was not found";
|
||||
|
@ -1093,32 +1127,51 @@ bool Core::loadConfiguration()
|
|||
|
||||
void Core::saveConfiguration()
|
||||
{
|
||||
Settings::getInstance().save();
|
||||
QString dir = Settings::getSettingsDirPath();
|
||||
QDir directory(dir);
|
||||
if (!directory.exists() && !directory.mkpath(directory.absolutePath())) {
|
||||
qCritical() << "Error while creating directory " << dir;
|
||||
return;
|
||||
}
|
||||
|
||||
QString profile = Settings::getInstance().getCurrentProfile();
|
||||
//qDebug() << "saveConf read profile: " << profile;
|
||||
if (profile == "")
|
||||
{ // no profile active; this should only happen on startup, if at all
|
||||
profile = sanitize(getUsername());
|
||||
if (profile == "") // happens on creation of a new Tox ID
|
||||
profile = getIDString();
|
||||
//qDebug() << "saveConf: read sanitized user as " << profile;
|
||||
Settings::getInstance().setCurrentProfile(profile);
|
||||
}
|
||||
|
||||
QString path = dir + QDir::separator() + profile + TOX_EXT;
|
||||
QFileInfo info(path);
|
||||
// if (!info.exists()) // fall back to old school 'data'
|
||||
// { //path = dir + QDir::separator() + CONFIG_FILE_NAME;
|
||||
// qDebug() << "Core:" << path << " does not exist";
|
||||
// }
|
||||
|
||||
saveConfiguration(path);
|
||||
}
|
||||
|
||||
void Core::saveConfiguration(const QString& path)
|
||||
{
|
||||
if (!tox)
|
||||
{
|
||||
qWarning() << "Core::saveConfiguration: Tox not started, aborting!";
|
||||
return;
|
||||
}
|
||||
|
||||
QString path = Settings::getSettingsDirPath();
|
||||
Settings::getInstance().save();
|
||||
|
||||
QDir directory(path);
|
||||
|
||||
if (!directory.exists() && !directory.mkpath(directory.absolutePath())) {
|
||||
qCritical() << "Error while creating directory " << path;
|
||||
return;
|
||||
}
|
||||
|
||||
path = directory.filePath(CONFIG_FILE_NAME);
|
||||
QSaveFile configurationFile(path);
|
||||
if (!configurationFile.open(QIODevice::WriteOnly)) {
|
||||
qCritical() << "File " << path << " cannot be opened";
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "Core: Saving";
|
||||
|
||||
qDebug() << "Core: writing tox_save to " << path;
|
||||
uint32_t fileSize = tox_size(tox);
|
||||
if (fileSize > 0 && fileSize <= INT32_MAX) {
|
||||
uint8_t *data = new uint8_t[fileSize];
|
||||
|
@ -1129,6 +1182,27 @@ void Core::saveConfiguration()
|
|||
}
|
||||
}
|
||||
|
||||
void Core::switchConfiguration(QString profile)
|
||||
{
|
||||
saveConfiguration();
|
||||
|
||||
toxTimer->stop();
|
||||
|
||||
if (tox) {
|
||||
toxav_kill(toxav);
|
||||
toxav = nullptr;
|
||||
tox_kill(tox);
|
||||
tox = nullptr;
|
||||
}
|
||||
emit selfAvatarChanged(QPixmap(":/img/contact_dark.png"));
|
||||
Widget::getInstance()->clearContactsList(); // we need this to block, so no signals for us
|
||||
|
||||
loadPath = QDir(Settings::getSettingsDirPath()).filePath(profile + TOX_EXT);
|
||||
Settings::getInstance().setCurrentProfile(profile);
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
void Core::loadFriends()
|
||||
{
|
||||
const uint32_t friendCount = tox_count_friendlist(tox);
|
||||
|
|
17
src/core.h
17
src/core.h
|
@ -34,10 +34,14 @@ class Core : public QObject
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Core(Camera* cam, QThread* coreThread);
|
||||
explicit Core(Camera* cam, QThread* coreThread, QString initialLoadPath);
|
||||
static Core* getInstance(); ///< Returns the global widget's Core instance
|
||||
~Core();
|
||||
|
||||
static const QString TOX_EXT;
|
||||
static const QString CONFIG_FILE_NAME;
|
||||
static QString sanitize(QString name);
|
||||
|
||||
int getGroupNumberPeers(int groupId) const;
|
||||
QString getGroupPeerName(int groupId, int peerId) const;
|
||||
QList<QString> getGroupPeerNames(int groupId) const;
|
||||
|
@ -48,6 +52,10 @@ public:
|
|||
void dispatchVideoFrame(vpx_image img) const;
|
||||
|
||||
void saveConfiguration();
|
||||
void saveConfiguration(const QString& path);
|
||||
void switchConfiguration(QString profile);
|
||||
|
||||
QString getIDString();
|
||||
|
||||
QString getUsername();
|
||||
QString getStatusMessage();
|
||||
|
@ -209,7 +217,8 @@ private:
|
|||
|
||||
bool checkConnection();
|
||||
|
||||
bool loadConfiguration(); // Returns false for a critical error, true otherwise
|
||||
bool loadConfiguration(QString path); // Returns false for a critical error, true otherwise
|
||||
void make_tox();
|
||||
void loadFriends();
|
||||
|
||||
static void sendAllFileData(Core* core, ToxFile* file);
|
||||
|
@ -225,14 +234,14 @@ private slots:
|
|||
private:
|
||||
Tox* tox;
|
||||
ToxAv* toxav;
|
||||
QTimer *toxTimer, *fileTimer, *bootstrapTimer; //, *saveTimer;
|
||||
QTimer *toxTimer, *fileTimer; //, *saveTimer;
|
||||
Camera* camera;
|
||||
QString loadPath; // meaningless after start() is called
|
||||
QList<DhtServer> dhtServerList;
|
||||
int dhtServerId;
|
||||
static QList<ToxFile> fileSendQueue, fileRecvQueue;
|
||||
static ToxCall calls[];
|
||||
|
||||
static const QString CONFIG_FILE_NAME;
|
||||
static const int videobufsize;
|
||||
static uint8_t* videobuf;
|
||||
static int videoBusyness; // Used to know when to drop frames
|
||||
|
|
|
@ -115,6 +115,7 @@ void Settings::load()
|
|||
useProxy = s.value("useProxy", false).toBool();
|
||||
proxyAddr = s.value("proxyAddr", "").toString();
|
||||
proxyPort = s.value("proxyPort", 0).toInt();
|
||||
currentProfile = s.value("currentProfile", "").toString();
|
||||
s.endGroup();
|
||||
|
||||
s.beginGroup("Widgets");
|
||||
|
@ -219,6 +220,7 @@ void Settings::save(QString path)
|
|||
s.setValue("forceTCP", forceTCP);
|
||||
s.setValue("proxyAddr", proxyAddr);
|
||||
s.setValue("proxyPort", proxyPort);
|
||||
s.setValue("currentProfile", currentProfile);
|
||||
s.endGroup();
|
||||
|
||||
s.beginGroup("Widgets");
|
||||
|
@ -410,6 +412,16 @@ void Settings::setProxyPort(int newValue)
|
|||
proxyPort = newValue;
|
||||
}
|
||||
|
||||
QString Settings::getCurrentProfile() const
|
||||
{
|
||||
return currentProfile;
|
||||
}
|
||||
|
||||
void Settings::setCurrentProfile(QString profile)
|
||||
{
|
||||
currentProfile = profile;
|
||||
}
|
||||
|
||||
bool Settings::getEnableLogging() const
|
||||
{
|
||||
return enableLogging;
|
||||
|
|
|
@ -52,6 +52,9 @@ public:
|
|||
bool getAutostartInTray() const;
|
||||
void setAutostartInTray(bool newValue);
|
||||
|
||||
QString getCurrentProfile() const;
|
||||
void setCurrentProfile(QString profile);
|
||||
|
||||
bool getUseTranslations() const;
|
||||
void setUseTranslations(bool newValue);
|
||||
|
||||
|
@ -176,6 +179,8 @@ private:
|
|||
QString proxyAddr;
|
||||
int proxyPort;
|
||||
|
||||
QString currentProfile;
|
||||
|
||||
bool enableLogging;
|
||||
bool encryptLogs;
|
||||
|
||||
|
|
|
@ -18,11 +18,16 @@
|
|||
#include "ui_identitysettings.h"
|
||||
#include "identityform.h"
|
||||
#include "src/widget/form/settingswidget.h"
|
||||
#include "src/misc/settings.h"
|
||||
#include "src/widget/croppinglabel.h"
|
||||
#include "src/widget/widget.h"
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QInputDialog>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
|
||||
IdentityForm::IdentityForm() :
|
||||
GenericForm(tr("Your identity"), QPixmap(":/img/settings/identity.png"))
|
||||
|
@ -38,7 +43,7 @@ IdentityForm::IdentityForm() :
|
|||
|
||||
// toxId->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
toxId->setReadOnly(true);
|
||||
// toxId->setFrameStyle(QFrame::NoFrame);
|
||||
toxId->setFrame(false);
|
||||
// toxId->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
// toxId->setFixedHeight(toxId->document()->size().height()*2);
|
||||
toxId->setFont(small);
|
||||
|
@ -49,6 +54,11 @@ IdentityForm::IdentityForm() :
|
|||
connect(toxId, SIGNAL(clicked()), this, SLOT(copyIdClicked()));
|
||||
connect(bodyUI->userName, SIGNAL(editingFinished()), this, SLOT(onUserNameEdited()));
|
||||
connect(bodyUI->statusMessage, SIGNAL(editingFinished()), this, SLOT(onStatusMessageEdited()));
|
||||
connect(bodyUI->loadButton, &QPushButton::clicked, this, &IdentityForm::onLoadClicked);
|
||||
connect(bodyUI->renameButton, &QPushButton::clicked, this, &IdentityForm::onRenameClicked);
|
||||
connect(bodyUI->exportButton, &QPushButton::clicked, this, &IdentityForm::onExportClicked);
|
||||
connect(bodyUI->deleteButton, &QPushButton::clicked, this, &IdentityForm::onDeleteClicked);
|
||||
connect(bodyUI->importButton, &QPushButton::clicked, this, &IdentityForm::onImportClicked);
|
||||
}
|
||||
|
||||
IdentityForm::~IdentityForm()
|
||||
|
@ -61,6 +71,7 @@ void IdentityForm::copyIdClicked()
|
|||
QString txt = toxId->text();
|
||||
txt.replace('\n',"");
|
||||
QApplication::clipboard()->setText(txt);
|
||||
toxId->setCursorPosition(0);
|
||||
}
|
||||
|
||||
void IdentityForm::onUserNameEdited()
|
||||
|
@ -76,6 +87,13 @@ void IdentityForm::onStatusMessageEdited()
|
|||
void IdentityForm::present()
|
||||
{
|
||||
toxId->setText(Core::getInstance()->getSelfId().toString());
|
||||
toxId->setCursorPosition(0);
|
||||
bodyUI->profiles->clear();
|
||||
for (QString profile : Widget::searchProfiles())
|
||||
bodyUI->profiles->addItem(profile);
|
||||
QString current = Settings::getInstance().getCurrentProfile();
|
||||
if (current != "")
|
||||
bodyUI->profiles->setCurrentText(current);
|
||||
}
|
||||
|
||||
void IdentityForm::setUserName(const QString &name)
|
||||
|
@ -87,3 +105,62 @@ void IdentityForm::setStatusMessage(const QString &msg)
|
|||
{
|
||||
bodyUI->statusMessage->setText(msg);
|
||||
}
|
||||
|
||||
void IdentityForm::onLoadClicked()
|
||||
{
|
||||
Core::getInstance()->switchConfiguration(bodyUI->profiles->currentText());
|
||||
}
|
||||
|
||||
void IdentityForm::onRenameClicked()
|
||||
{
|
||||
QString cur = bodyUI->profiles->currentText();
|
||||
QString title = tr("Rename \"%1\"", "renaming a profile").arg(cur);
|
||||
QString name = QInputDialog::getText(this, title, title+":");
|
||||
if (name != "")
|
||||
{
|
||||
name = Core::sanitize(name);
|
||||
QDir dir(Settings::getSettingsDirPath());
|
||||
QFile::rename(dir.filePath(cur+Core::TOX_EXT), dir.filePath(name+Core::TOX_EXT));
|
||||
bodyUI->profiles->setItemText(bodyUI->profiles->currentIndex(), name);
|
||||
Settings::getInstance().setCurrentProfile(name);
|
||||
}
|
||||
}
|
||||
|
||||
void IdentityForm::onExportClicked()
|
||||
{
|
||||
QString current = bodyUI->profiles->currentText() + Core::TOX_EXT;
|
||||
QString path = QFileDialog::getSaveFileName(this, tr("Export profile", "save dialog title"),
|
||||
QDir::home().filePath(current),
|
||||
tr("Tox save file (*.tox)", "save dialog filter"));
|
||||
QFile::copy(QDir(Settings::getSettingsDirPath()).filePath(current), path);
|
||||
}
|
||||
|
||||
void IdentityForm::onDeleteClicked()
|
||||
{
|
||||
if (Settings::getInstance().getCurrentProfile() == bodyUI->profiles->currentText())
|
||||
{
|
||||
QMessageBox::warning(this, tr("Profile currently loaded","current profile deletion warning title"), tr("This profile is currently in use. Please load a different profile before deleting this one.","current profile deletion warning text"));
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::StandardButton resp = QMessageBox::question(this,
|
||||
tr("Deletion imminent!","deletion confirmation title"), tr("Are you sure you want to delete this profile?","deletion confirmation text"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
||||
if (resp == QMessageBox::Yes)
|
||||
{
|
||||
QFile::remove(QDir(Settings::getSettingsDirPath()).filePath(bodyUI->profiles->currentText()+Core::TOX_EXT));
|
||||
bodyUI->profiles->removeItem(bodyUI->profiles->currentIndex());
|
||||
bodyUI->profiles->setCurrentText(Settings::getInstance().getCurrentProfile());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IdentityForm::onImportClicked()
|
||||
{
|
||||
QString path = QFileDialog::getOpenFileName(this, tr("Import profile", "import dialog title"), QDir::homePath(), tr("Tox save file (*.tox)", "import dialog filter"));
|
||||
QFileInfo info(path);
|
||||
QString profile = info.completeBaseName();
|
||||
QString profilePath = QDir(Settings::getSettingsDirPath()).filePath(profile + Core::TOX_EXT);
|
||||
QFile::copy(path, profilePath);
|
||||
bodyUI->profiles->addItem(profile);
|
||||
Core::getInstance()->switchConfiguration(profile);
|
||||
}
|
||||
|
|
|
@ -60,6 +60,11 @@ private slots:
|
|||
void copyIdClicked();
|
||||
void onUserNameEdited();
|
||||
void onStatusMessageEdited();
|
||||
void onLoadClicked();
|
||||
void onRenameClicked();
|
||||
void onExportClicked();
|
||||
void onDeleteClicked();
|
||||
void onImportClicked();
|
||||
|
||||
private:
|
||||
Ui::IdentitySettings* bodyUI;
|
||||
|
|
|
@ -59,6 +59,71 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="profilesGroup">
|
||||
<property name="title">
|
||||
<string>Profiles</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="profilesVLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="profilesComboLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="profilesLabel">
|
||||
<property name="text">
|
||||
<string>Available profiles:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="profiles" />
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="profilesButtonsLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="loadButton">
|
||||
<property name="text">
|
||||
<string comment="load profile button">Load</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="renameButton">
|
||||
<property name="text">
|
||||
<string comment="rename profile button">Rename</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="exportButton">
|
||||
<property name="text">
|
||||
<string comment="export profile button">Export</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="deleteButton">
|
||||
<property name="text">
|
||||
<string comment="delete profile button">Delete</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string comment="delete profile button tooltip">This is useful to remain safe on public computers</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="importButton">
|
||||
<property name="text">
|
||||
<string comment="import profile button">Import a profile</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <QClipboard>
|
||||
#include <QThread>
|
||||
#include <QFileDialog>
|
||||
#include <QInputDialog>
|
||||
#include <tox/tox.h>
|
||||
|
||||
Widget *Widget::instance{nullptr};
|
||||
|
@ -116,8 +117,9 @@ Widget::Widget(QWidget *parent)
|
|||
qRegisterMetaType<ToxFile>("ToxFile");
|
||||
qRegisterMetaType<ToxFile::FileDirection>("ToxFile::FileDirection");
|
||||
|
||||
QString profilePath = detectProfile();
|
||||
coreThread = new QThread(this);
|
||||
core = new Core(Camera::getInstance(), coreThread);
|
||||
core = new Core(Camera::getInstance(), coreThread, profilePath);
|
||||
core->moveToThread(coreThread);
|
||||
connect(coreThread, &QThread::started, core, &Core::start);
|
||||
|
||||
|
@ -211,6 +213,69 @@ void Widget::closeEvent(QCloseEvent *event)
|
|||
QWidget::closeEvent(event);
|
||||
}
|
||||
|
||||
QString Widget::detectProfile()
|
||||
{
|
||||
QDir dir(Settings::getSettingsDirPath());
|
||||
QString path, profile = Settings::getInstance().getCurrentProfile();
|
||||
path = dir.filePath(profile + Core::TOX_EXT);
|
||||
QFile file(path);
|
||||
if (profile == "" || !file.exists())
|
||||
{
|
||||
Settings::getInstance().setCurrentProfile("");
|
||||
#if 1 // deprecation attempt
|
||||
// if the last profile doesn't exist, fall back to old "data"
|
||||
path = dir.filePath(Core::CONFIG_FILE_NAME);
|
||||
QFile file(path);
|
||||
if (file.exists())
|
||||
return path;
|
||||
else if (QFile(path = dir.filePath("tox_save")).exists()) // also import tox_save if no data
|
||||
return path;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
profile = askProfiles();
|
||||
if (profile != "")
|
||||
return dir.filePath(profile + Core::TOX_EXT);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
}
|
||||
else
|
||||
return path;
|
||||
}
|
||||
|
||||
QList<QString> Widget::searchProfiles()
|
||||
{
|
||||
QList<QString> out;
|
||||
QDir dir(Settings::getSettingsDirPath());
|
||||
dir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
|
||||
dir.setNameFilters(QStringList("*.tox"));
|
||||
for(QFileInfo file : dir.entryInfoList())
|
||||
out += file.completeBaseName();
|
||||
return out;
|
||||
}
|
||||
|
||||
QString Widget::askProfiles()
|
||||
{ // TODO: allow user to create new Tox ID, even if a profile already exists
|
||||
QList<QString> profiles = searchProfiles();
|
||||
if (profiles.empty()) return "";
|
||||
bool ok;
|
||||
QString profile = QInputDialog::getItem(this,
|
||||
tr("Choose a profile"),
|
||||
tr("Please choose which identity to use"),
|
||||
profiles,
|
||||
0, // which slot to start on
|
||||
false, // if the user can enter their own input
|
||||
&ok);
|
||||
if (!ok) // user cancelled
|
||||
{
|
||||
qApp->quit();
|
||||
return "";
|
||||
}
|
||||
else
|
||||
return profile;
|
||||
}
|
||||
|
||||
QString Widget::getUsername()
|
||||
{
|
||||
return core->getUsername();
|
||||
|
@ -565,19 +630,31 @@ void Widget::onFriendRequestReceived(const QString& userId, const QString& messa
|
|||
emit friendRequestAccepted(userId);
|
||||
}
|
||||
|
||||
void Widget::removeFriend(int friendId)
|
||||
void Widget::removeFriend(Friend* f)
|
||||
{
|
||||
Friend* f = FriendList::findFriend(friendId);
|
||||
f->widget->setAsInactiveChatroom();
|
||||
if (static_cast<GenericChatroomWidget*>(f->widget) == activeChatroomWidget)
|
||||
activeChatroomWidget = nullptr;
|
||||
FriendList::removeFriend(friendId);
|
||||
core->removeFriend(friendId);
|
||||
FriendList::removeFriend(f->friendId);
|
||||
core->removeFriend(f->friendId);
|
||||
delete f;
|
||||
if (ui->mainHead->layout()->isEmpty())
|
||||
onAddClicked();
|
||||
}
|
||||
|
||||
void Widget::removeFriend(int friendId)
|
||||
{
|
||||
removeFriend(FriendList::findFriend(friendId));
|
||||
}
|
||||
|
||||
void Widget::clearContactsList()
|
||||
{
|
||||
for (Friend* f : FriendList::friendList)
|
||||
removeFriend(f);
|
||||
for (Group* g : GroupList::groupList)
|
||||
removeGroup(g);
|
||||
}
|
||||
|
||||
void Widget::copyFriendIdToClipboard(int friendId)
|
||||
{
|
||||
Friend* f = FriendList::findFriend(friendId);
|
||||
|
@ -641,19 +718,23 @@ void Widget::onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t Cha
|
|||
g->updatePeer(peernumber,core->getGroupPeerName(groupnumber, peernumber));
|
||||
}
|
||||
|
||||
void Widget::removeGroup(int groupId)
|
||||
void Widget::removeGroup(Group* g)
|
||||
{
|
||||
Group* g = GroupList::findGroup(groupId);
|
||||
g->widget->setAsInactiveChatroom();
|
||||
if (static_cast<GenericChatroomWidget*>(g->widget) == activeChatroomWidget)
|
||||
activeChatroomWidget = nullptr;
|
||||
GroupList::removeGroup(groupId);
|
||||
core->removeGroup(groupId);
|
||||
GroupList::removeGroup(g->groupId);
|
||||
core->removeGroup(g->groupId);
|
||||
delete g;
|
||||
if (ui->mainHead->layout()->isEmpty())
|
||||
onAddClicked();
|
||||
}
|
||||
|
||||
void Widget::removeGroup(int groupId)
|
||||
{
|
||||
removeGroup(GroupList::findGroup(groupId));
|
||||
}
|
||||
|
||||
Core *Widget::getCore()
|
||||
{
|
||||
return core;
|
||||
|
|
|
@ -56,6 +56,8 @@ public:
|
|||
void newMessageAlert();
|
||||
bool isFriendWidgetCurActiveWidget(Friend* f);
|
||||
bool getIsWindowMinimized();
|
||||
static QList<QString> searchProfiles();
|
||||
void clearContactsList();
|
||||
~Widget();
|
||||
|
||||
virtual void closeEvent(QCloseEvent *event);
|
||||
|
@ -111,8 +113,11 @@ private:
|
|||
void hideMainForms();
|
||||
virtual bool event(QEvent * e);
|
||||
Group* createGroup(int groupId);
|
||||
void removeFriend(Friend* f);
|
||||
void removeGroup(Group* g);
|
||||
QString askProfiles();
|
||||
QString detectProfile();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
QSplitter *centralLayout;
|
||||
QPoint dragPosition;
|
||||
|
|
Loading…
Reference in New Issue
Block a user