From e3da9badace3af72a04427a9e23490ea9b2a2cd7 Mon Sep 17 00:00:00 2001 From: dubslow Date: Wed, 16 Jul 2014 17:43:30 -0500 Subject: [PATCH 01/21] Basic infrastructure for profiles is in place, now I gotta hook up the UI --- core.cpp | 67 ++++++++++++++++++++++++++---------- core.h | 7 ++-- settings.cpp | 12 +++++++ settings.h | 4 +++ widget/form/settingsform.cpp | 46 ++++++++++++++++++++----- widget/form/settingsform.h | 15 +++++--- widget/widget.cpp | 36 ++++++++++++------- widget/widget.h | 4 +-- 8 files changed, 144 insertions(+), 47 deletions(-) diff --git a/core.cpp b/core.cpp index 2038131c0..1dcc9349c 100644 --- a/core.cpp +++ b/core.cpp @@ -30,6 +30,7 @@ #include const QString Core::CONFIG_FILE_NAME = "data"; +const QString Core::TOX_EXT = ".tox"; QList Core::fileSendQueue; QList Core::fileRecvQueue; ToxCall Core::calls[TOXAV_MAX_CALLS]; @@ -108,6 +109,7 @@ void Core::start() return; } + // this will attempt to get the last profile from settings loadConfiguration(); tox_callback_friend_request(tox, onFriendRequest, this); @@ -721,34 +723,55 @@ void Core::checkConnection() } } -void Core::loadConfiguration() +QString sanitize(QString name) { - QString path = Settings::getSettingsDirPath() + '/' + CONFIG_FILE_NAME; + // do things + return name; +} - QFile configurationFile(path); +void Core::loadConfiguration(QString path) +{ + if (path == "") + { + // read from settings whose profile? + path = Settings::getSettingsDirPath() + '/' + Settings::getInstance().getCurrentProfile() + TOX_EXT; + QFile file(path); + + // if the last profile doesn't exist, fall back to old "data" + if (!file.exists()) + { + path = Settings::getSettingsDirPath() + '/' + CONFIG_FILE_NAME; + } + } - if (!configurationFile.exists()) { + QFile conf(path); + qDebug() << "Core::loadConfiguration: reading from " << path; + + if (!conf.exists()) { qWarning() << "The Tox configuration file was not found"; return; } - if (!configurationFile.open(QIODevice::ReadOnly)) { + if (!conf.open(QIODevice::ReadOnly)) { qCritical() << "File " << path << " cannot be opened"; return; } - qint64 fileSize = configurationFile.size(); + qint64 fileSize = conf.size(); if (fileSize > 0) { - QByteArray data = configurationFile.readAll(); + QByteArray data = conf.readAll(); tox_load(tox, reinterpret_cast(data.data()), data.size()); } - configurationFile.close(); + conf.close(); // set GUI with user and statusmsg QString name = getUsername(); if (name != "") + { emit usernameSet(name); + Settings::getInstance().setCurrentProfile(name); + } QString msg = getStatusMessage(); if (msg != "") @@ -757,7 +780,7 @@ void Core::loadConfiguration() loadFriends(); } -void Core::saveConfiguration() +void Core::saveConfiguration(QString path) { if (!tox) { @@ -765,23 +788,28 @@ void Core::saveConfiguration() return; } - QString path = Settings::getSettingsDirPath(); - - QDir directory(path); - - if (!directory.exists() && !directory.mkpath(directory.absolutePath())) { - qCritical() << "Error while creating directory " << path; - return; + if (path == "") + { + QString dir = Settings::getSettingsDirPath(); + QDir directory(dir); + if (!directory.exists() && !directory.mkpath(directory.absolutePath())) { + qCritical() << "Error while creating directory " << dir; + return; + } + + path = dir + Settings::getInstance().getCurrentProfile() + TOX_EXT; + QFileInfo info(dir); + if (!info.exists()) // fall back to old school 'data' + path = dir + '/' + CONFIG_FILE_NAME; } - - path += '/' + CONFIG_FILE_NAME; + QSaveFile configurationFile(path); if (!configurationFile.open(QIODevice::WriteOnly)) { qCritical() << "File " << path << " cannot be opened"; return; } - qDebug() << "Core: writing tox_save"; + 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]; @@ -789,6 +817,7 @@ void Core::saveConfiguration() configurationFile.write(reinterpret_cast(data), fileSize); configurationFile.commit(); delete[] data; + //configurationFile.close(); } } diff --git a/core.h b/core.h index 91bbee5e2..af8d4e47e 100644 --- a/core.h +++ b/core.h @@ -114,6 +114,8 @@ class Core : public QObject public: explicit Core(Camera* cam, QThread* coreThread); ~Core(); + + static const QString TOX_EXT; int getGroupNumberPeers(int groupId) const; QString getGroupPeerName(int groupId, int peerId) const; @@ -122,7 +124,9 @@ public: void quitGroupChat(int groupId) const; void dispatchVideoFrame(vpx_image img) const; - void saveConfiguration(); + void saveConfiguration(QString path = ""); + void loadConfiguration(QString path = ""); + QString sanitize(QString name); QString getUsername(); QString getStatusMessage(); @@ -273,7 +277,6 @@ private: void checkConnection(); void onBootstrapTimer(); - void loadConfiguration(); void loadFriends(); static void sendAllFileData(Core* core, ToxFile* file); diff --git a/settings.cpp b/settings.cpp index 888d840a5..62a208df6 100644 --- a/settings.cpp +++ b/settings.cpp @@ -81,6 +81,7 @@ void Settings::load() enableIPv6 = s.value("enableIPv6", true).toBool(); useTranslations = s.value("useTranslations", true).toBool(); makeToxPortable = s.value("makeToxPortable", false).toBool(); + currentProfile = s.value("currentProfile", ".data").toString(); s.endGroup(); s.beginGroup("Widgets"); @@ -137,6 +138,7 @@ void Settings::save(QString path) s.setValue("enableIPv6", enableIPv6); s.setValue("useTranslations",useTranslations); s.setValue("makeToxPortable",makeToxPortable); + s.setValue("currentProfile", currentProfile); s.endGroup(); s.beginGroup("Widgets"); @@ -208,6 +210,16 @@ void Settings::setMakeToxPortable(bool newValue) save(FILENAME); // Commit to the portable file that we don't want to use it } +QString Settings::getCurrentProfile() const +{ + return currentProfile; +} + +void Settings::setCurrentProfile(QString profile) +{ + currentProfile = profile; +} + bool Settings::getUseTranslations() const { return useTranslations; diff --git a/settings.h b/settings.h index d4f015635..3ad240bc7 100644 --- a/settings.h +++ b/settings.h @@ -49,6 +49,9 @@ public: bool getMakeToxPortable() const; void setMakeToxPortable(bool newValue); + QString getCurrentProfile() const; + void setCurrentProfile(QString profile); + bool getUseTranslations() const; void setUseTranslations(bool newValue); @@ -134,6 +137,7 @@ private: bool enableIPv6; bool useTranslations; static bool makeToxPortable; + QString currentProfile; bool enableLogging; bool encryptLogs; diff --git a/widget/form/settingsform.cpp b/widget/form/settingsform.cpp index 1179497c5..b0815825d 100644 --- a/widget/form/settingsform.cpp +++ b/widget/form/settingsform.cpp @@ -25,14 +25,16 @@ SettingsForm::SettingsForm() : QObject() { main = new QWidget(), head = new QWidget(); + hboxcont1 = new QWidget(), hboxcont2 = new QWidget(); QFont bold, small; bold.setBold(true); small.setPixelSize(13); headLabel.setText(tr("User Settings","\"Headline\" of the window")); headLabel.setFont(bold); - nameLabel.setText(tr("Name","Username/nick")); - statusTextLabel.setText(tr("Status","Status message")); + //nameLabel.setText(tr("Name","Username/nick")); + //statusTextLabel.setText(tr("Status","Status message")); + idLabel.setText("Tox ID " + tr("(click here to copy)", "Click on this text to copy TID to clipboard")); id.setFont(small); id.setTextInteractionFlags(Qt::TextSelectableByMouse); @@ -40,6 +42,15 @@ SettingsForm::SettingsForm() id.setFrameStyle(QFrame::NoFrame); id.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); id.setFixedHeight(id.document()->size().height()); + + profilesLabel.setText(tr("Available profiles:", "Labels the profile selection box")); + populateProfiles(); + loadConf.setText(tr("Load profile", "button to load selected profile")); + exportConf.setText(tr("Export profile", "button to save selected profile elsewhere")); + delConf.setText(tr("Delete profile", "button to delete selected profile from disk")); + delConf.setToolTip(tr("This is useful to remain safe on public computers", "describes the delete profile button")); + //delConf.setWhatsThis(tr("This is useful to remain safe on public computers", "describes the delete profile button")); + importConf.setText(tr("Import profile", "button to locate a profile")); videoTest.setText(tr("Test video","Text on a button to test the video/webcam")); enableIPv6.setText(tr("Enable IPv6 (recommended)","Text on a checkbox to enable IPv6")); @@ -50,12 +61,21 @@ SettingsForm::SettingsForm() makeToxPortable.setChecked(Settings::getInstance().getMakeToxPortable()); main->setLayout(&layout); - layout.addWidget(&nameLabel); - layout.addWidget(&name); - layout.addWidget(&statusTextLabel); - layout.addWidget(&statusText); + //layout.addWidget(&nameLabel); + //layout.addWidget(&name); + //layout.addWidget(&statusTextLabel); + //layout.addWidget(&statusText); layout.addWidget(&idLabel); layout.addWidget(&id); + cbox.addWidget(&profilesLabel); + cbox.addWidget(&profiles); + hboxcont1->setLayout(&cbox); + layout.addWidget(hboxcont1); + buttons.addWidget(&loadConf); + buttons.addWidget(&exportConf); + buttons.addWidget(&delConf); + hboxcont2->setLayout(&buttons); + layout.addWidget(hboxcont2); layout.addWidget(&videoTest); layout.addWidget(&enableIPv6); layout.addWidget(&useTranslations); @@ -76,6 +96,16 @@ SettingsForm::~SettingsForm() { } +void SettingsForm::populateProfiles() +{ + QDir dir(Settings::getSettingsDirPath()); + dir.setFilter(QDir::Files | QDir::NoDotAndDotDot); + dir.setNameFilters(QStringList("*.tox")); + for(QFileInfo file : dir.entryInfoList()) { + profiles.addItem(file.completeBaseName()); + } +} + void SettingsForm::setFriendAddress(const QString& friendAddress) { id.setText(friendAddress); @@ -83,8 +113,8 @@ void SettingsForm::setFriendAddress(const QString& friendAddress) void SettingsForm::show(Ui::Widget &ui) { - name.setText(ui.nameLabel->text()); - statusText.setText(ui.statusLabel->text()); + //name.setText(ui.nameLabel->text()); + //statusText.setText(ui.statusLabel->text()); ui.mainContent->layout()->addWidget(main); ui.mainHead->layout()->addWidget(head); main->show(); diff --git a/widget/form/settingsform.h b/widget/form/settingsform.h index 3342c5667..070c4e1b4 100644 --- a/widget/form/settingsform.h +++ b/widget/form/settingsform.h @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include #include "widget/tool/clickablelabel.h" #include "ui_widget.h" #include "widget/selfcamview.h" @@ -50,16 +53,20 @@ private slots: void copyIdClicked(); private: - QLabel headLabel, nameLabel, statusTextLabel; + QLabel headLabel;/*, nameLabel, statusTextLabel;*/ QTextEdit id; ClickableLabel idLabel; - QPushButton videoTest; + QLabel profilesLabel; + QComboBox profiles; + QPushButton loadConf, exportConf, delConf, importConf, videoTest; + QHBoxLayout cbox, buttons; QCheckBox enableIPv6, useTranslations, makeToxPortable; QVBoxLayout layout, headLayout; - QWidget *main, *head; + QWidget *main, *head, *hboxcont1, *hboxcont2; + void populateProfiles(); public: - QLineEdit name, statusText; + //QLineEdit name, statusText; }; #endif // SETTINGSFORM_H diff --git a/widget/widget.cpp b/widget/widget.cpp index f7b7bc1b3..468ea3b83 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -249,8 +249,8 @@ Widget::Widget(QWidget *parent) : connect(setStatusOnline, SIGNAL(triggered()), this, SLOT(setStatusOnline())); connect(setStatusAway, SIGNAL(triggered()), this, SLOT(setStatusAway())); connect(setStatusBusy, SIGNAL(triggered()), this, SLOT(setStatusBusy())); - connect(&settingsForm.name, SIGNAL(editingFinished()), this, SLOT(onUsernameChanged())); - connect(&settingsForm.statusText, SIGNAL(editingFinished()), this, SLOT(onStatusMessageChanged())); + //connect(&settingsForm.name, SIGNAL(editingFinished()), this, SLOT(onUsernameChanged())); + //connect(&settingsForm.statusText, SIGNAL(editingFinished()), this, SLOT(onStatusMessageChanged())); connect(&friendForm, SIGNAL(friendRequested(QString,QString)), this, SIGNAL(friendRequested(QString,QString))); coreThread->start(); @@ -418,44 +418,56 @@ void Widget::hideMainForms() } } -void Widget::onUsernameChanged() +/*void Widget::onUsernameChanged() { - const QString newUsername = settingsForm.name.text(); + //const QString newUsername = settingsForm.name.text(); ui->nameLabel->setText(newUsername); ui->nameLabel->setToolTip(newUsername); // for overlength names settingsForm.name.setText(newUsername); core->setUsername(newUsername); -} +}*/ void Widget::onUsernameChanged(const QString& newUsername, const QString& oldUsername) { ui->nameLabel->setText(oldUsername); // restore old username until Core tells us to set it ui->nameLabel->setToolTip(oldUsername); // for overlength names - settingsForm.name.setText(oldUsername); + //settingsForm.name.setText(oldUsername); core->setUsername(newUsername); + + // move the data file with it + QString dir = Settings::getSettingsDirPath(); + QFile::rename(dir + '/' + oldUsername + core->TOX_EXT, dir + '/' + newUsername + core->TOX_EXT); + // and update current profile + Settings::getInstance().setCurrentProfile(newUsername); } - +// ugh... Widget::onUsernameChanged() calls Core::setUsername, +// which emits Core::usernameSet, which is connect to this function: void Widget::setUsername(const QString& username) { ui->nameLabel->setText(username); ui->nameLabel->setToolTip(username); // for overlength names - settingsForm.name.setText(username); + //settingsForm.name.setText(username); } +// the end result is that the ui gets updated twice -- and actually, +// I believe this function is dead code, since the only way to change +// username now is via the ui (since I killed the settings version) +// the chain of calls before was surely much messier with two ways +// to modify the username... -void Widget::onStatusMessageChanged() +/*void Widget::onStatusMessageChanged() { const QString newStatusMessage = settingsForm.statusText.text(); ui->statusLabel->setText(newStatusMessage); ui->statusLabel->setToolTip(newStatusMessage); // for overlength messsages settingsForm.statusText.setText(newStatusMessage); core->setStatusMessage(newStatusMessage); -} +}*/ void Widget::onStatusMessageChanged(const QString& newStatusMessage, const QString& oldStatusMessage) { ui->statusLabel->setText(oldStatusMessage); // restore old status message until Core tells us to set it ui->statusLabel->setToolTip(oldStatusMessage); // for overlength messsages - settingsForm.statusText.setText(oldStatusMessage); + //settingsForm.statusText.setText(oldStatusMessage); core->setStatusMessage(newStatusMessage); } @@ -463,7 +475,7 @@ void Widget::setStatusMessage(const QString &statusMessage) { ui->statusLabel->setText(statusMessage); ui->statusLabel->setToolTip(statusMessage); // for overlength messsages - settingsForm.statusText.setText(statusMessage); + //settingsForm.statusText.setText(statusMessage); } void Widget::addFriend(int friendId, const QString &userId) diff --git a/widget/widget.h b/widget/widget.h index 0e0a13109..42953e6e8 100644 --- a/widget/widget.h +++ b/widget/widget.h @@ -86,8 +86,8 @@ private slots: void onFailedToStartCore(); void onUsernameChanged(const QString& newUsername, const QString& oldUsername); void onStatusMessageChanged(const QString& newStatusMessage, const QString& oldStatusMessage); - void onUsernameChanged(); - void onStatusMessageChanged(); + //void onUsernameChanged(); + //void onStatusMessageChanged(); void setUsername(const QString& username); void setStatusMessage(const QString &statusMessage); void addFriend(int friendId, const QString& userId); From f423c174e79e561a13dad2a64f5179c5071c54ec Mon Sep 17 00:00:00 2001 From: dubslow Date: Wed, 16 Jul 2014 17:46:51 -0500 Subject: [PATCH 02/21] forgot a button, also the ui is fucked at default size (expand a few pixels and its fine though) --- widget/form/settingsform.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/widget/form/settingsform.cpp b/widget/form/settingsform.cpp index b0815825d..92c12b8c0 100644 --- a/widget/form/settingsform.cpp +++ b/widget/form/settingsform.cpp @@ -76,6 +76,7 @@ SettingsForm::SettingsForm() buttons.addWidget(&delConf); hboxcont2->setLayout(&buttons); layout.addWidget(hboxcont2); + layout.addWidget(&importConf); layout.addWidget(&videoTest); layout.addWidget(&enableIPv6); layout.addWidget(&useTranslations); From 46848d77128d35049e9f47df8dbed1addfa305e6 Mon Sep 17 00:00:00 2001 From: dubslow Date: Wed, 16 Jul 2014 20:00:23 -0500 Subject: [PATCH 03/21] Profiles, with at least a few bugs: sanitizing file names isn't done, delete fails because of autosaves, and imports segfault for me --- widget/form/settingsform.cpp | 44 ++++++++++++++++++++++++++++++++++-- widget/form/settingsform.h | 10 +++++++- widget/widget.cpp | 7 ++++-- widget/widget.h | 2 +- 4 files changed, 57 insertions(+), 6 deletions(-) diff --git a/widget/form/settingsform.cpp b/widget/form/settingsform.cpp index 92c12b8c0..f36f3e63b 100644 --- a/widget/form/settingsform.cpp +++ b/widget/form/settingsform.cpp @@ -21,8 +21,8 @@ #include #include -SettingsForm::SettingsForm() - : QObject() +SettingsForm::SettingsForm(Core* core) + : QObject(), core(core) { main = new QWidget(), head = new QWidget(); hboxcont1 = new QWidget(), hboxcont2 = new QWidget(); @@ -86,6 +86,10 @@ SettingsForm::SettingsForm() head->setLayout(&headLayout); headLayout.addWidget(&headLabel); + connect(&loadConf, SIGNAL(clicked()), this, SLOT(onLoadClicked())); + connect(&exportConf, SIGNAL(clicked()), this, SLOT(onExportClicked())); + connect(&delConf, SIGNAL(clicked()), this, SLOT(onDeleteClicked())); + connect(&importConf, SIGNAL(clicked()), this, SLOT(onImportClicked())); connect(&videoTest, SIGNAL(clicked()), this, SLOT(onTestVideoClicked())); connect(&enableIPv6, SIGNAL(stateChanged(int)), this, SLOT(onEnableIPv6Updated())); connect(&useTranslations, SIGNAL(stateChanged(int)), this, SLOT(onUseTranslationUpdated())); @@ -107,6 +111,11 @@ void SettingsForm::populateProfiles() } } +QString SettingsForm::getSelectedSavePath() +{ + return Settings::getSettingsDirPath() + profiles.currentText() + core->TOX_EXT; +} + void SettingsForm::setFriendAddress(const QString& friendAddress) { id.setText(friendAddress); @@ -122,6 +131,37 @@ void SettingsForm::show(Ui::Widget &ui) head->show(); } +void SettingsForm::onLoadClicked() +{ + core->saveConfiguration(); + core->loadConfiguration(getSelectedSavePath()); + // loadConf also setsCurrentProfile +} + +void SettingsForm::onExportClicked() +{ + QString current = getSelectedSavePath(); + QString path = QFileDialog::getSaveFileName(0, tr("Export profile", "save dialog title"), QDir::homePath() + '/' + profiles.currentText() + core->TOX_EXT, tr("Tox save file (*.tox)", "save dialog filter")); + // dunno if that "~" works + QFile::copy(getSelectedSavePath(), path); +} + +void SettingsForm::onDeleteClicked() +{ // this should really be guarded by a pop up + QFile::remove(getSelectedSavePath()); +} + +void SettingsForm::onImportClicked() +{ + QString path = QFileDialog::getOpenFileName(0, tr("Import profile", "import dialog title"), QDir::homePath(), tr("Tox save file (*.tox)", "import dialog filter")); + // again, the "~"... + QFileInfo info(path); + QString profile = info.completeBaseName(); + QString profilePath = Settings::getSettingsDirPath() + profile + core->TOX_EXT; + QFile::copy(path, profilePath); + core->loadConfiguration(profilePath); +} + void SettingsForm::onTestVideoClicked() { Widget::getInstance()->showTestCamview(); diff --git a/widget/form/settingsform.h b/widget/form/settingsform.h index 070c4e1b4..3a69a1a70 100644 --- a/widget/form/settingsform.h +++ b/widget/form/settingsform.h @@ -29,15 +29,17 @@ #include #include #include +#include #include "widget/tool/clickablelabel.h" #include "ui_widget.h" #include "widget/selfcamview.h" +#include "core.h" class SettingsForm : public QObject { Q_OBJECT public: - SettingsForm(); + SettingsForm(Core* core); ~SettingsForm(); void show(Ui::Widget& ui); @@ -46,6 +48,10 @@ public slots: void setFriendAddress(const QString& friendAddress); private slots: + void onLoadClicked(); + void onExportClicked(); + void onDeleteClicked(); + void onImportClicked(); void onTestVideoClicked(); void onEnableIPv6Updated(); void onUseTranslationUpdated(); @@ -64,6 +70,8 @@ private: QVBoxLayout layout, headLayout; QWidget *main, *head, *hboxcont1, *hboxcont2; void populateProfiles(); + QString getSelectedSavePath(); + Core* core; public: //QLineEdit name, statusText; diff --git a/widget/widget.cpp b/widget/widget.cpp index 468ea3b83..4722dabd0 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -141,6 +141,8 @@ Widget::Widget(QWidget *parent) : isWindowMinimized = 0; + settingsForm = new SettingsForm(core); + ui->mainContent->setLayout(new QVBoxLayout()); ui->mainHead->setLayout(new QVBoxLayout()); ui->mainHead->layout()->setMargin(0); @@ -217,7 +219,7 @@ Widget::Widget(QWidget *parent) : connect(core, &Core::statusSet, this, &Widget::onStatusSet); connect(core, &Core::usernameSet, this, &Widget::setUsername); connect(core, &Core::statusMessageSet, this, &Widget::setStatusMessage); - connect(core, &Core::friendAddressGenerated, &settingsForm, &SettingsForm::setFriendAddress); + connect(core, &Core::friendAddressGenerated, settingsForm, &SettingsForm::setFriendAddress); connect(core, SIGNAL(fileDownloadFinished(const QString&)), &filesForm, SLOT(onFileDownloadComplete(const QString&))); connect(core, SIGNAL(fileUploadFinished(const QString&)), &filesForm, SLOT(onFileUploadComplete(const QString&))); connect(core, &Core::friendAdded, this, &Widget::addFriend); @@ -281,6 +283,7 @@ Widget::~Widget() settings.setValue("geometry", geometry()); settings.setValue("maximized", isMaximized()); settings.setValue("useNativeTheme", useNativeTheme); + delete settingsForm; delete ui; } @@ -391,7 +394,7 @@ void Widget::onTransferClicked() void Widget::onSettingsClicked() { hideMainForms(); - settingsForm.show(*ui); + settingsForm->show(*ui); isFriendWidgetActive = 0; isGroupWidgetActive = 0; } diff --git a/widget/widget.h b/widget/widget.h index 42953e6e8..b5a4b1b5a 100644 --- a/widget/widget.h +++ b/widget/widget.h @@ -142,7 +142,7 @@ private: Core* core; QThread* coreThread; AddFriendForm friendForm; - SettingsForm settingsForm; + SettingsForm* settingsForm; FilesForm filesForm; static Widget* instance; FriendWidget* activeFriendWidget; From f9a3192f30421c9349cee10b9d2d41a29254f21d Mon Sep 17 00:00:00 2001 From: Bill Winslow Date: Wed, 23 Jul 2014 04:22:09 -0500 Subject: [PATCH 04/21] incremental improvements to profiles, more work required --- core.cpp | 15 +++++++++----- core.h | 3 ++- widget/form/settingsform.cpp | 38 ++++++++++++++++++++++++------------ widget/form/settingsform.h | 4 ++-- widget/widget.cpp | 31 ++++++++++++++++++----------- widget/widget.h | 4 +++- 6 files changed, 62 insertions(+), 33 deletions(-) diff --git a/core.cpp b/core.cpp index e7eb0fe4a..150a94c0f 100644 --- a/core.cpp +++ b/core.cpp @@ -723,17 +723,19 @@ void Core::checkConnection() } } -QString sanitize(QString name) +QString Core::sanitize(QString name) { // do things return name; } void Core::loadConfiguration(QString path) -{ +{ // note to self: this really needs refactoring into the GUI, making the path mandatory here + // but for now it's bedtime if (path == "") { // read from settings whose profile? + QString profile = Settings::getInstance().getCurrentProfile(); path = Settings::getSettingsDirPath() + '/' + Settings::getInstance().getCurrentProfile() + TOX_EXT; QFile file(path); @@ -743,6 +745,11 @@ void Core::loadConfiguration(QString path) path = Settings::getSettingsDirPath() + '/' + CONFIG_FILE_NAME; } } + else + { + QString profile = QFileInfo(path).completeBaseName(); + Settings::getInstance().setCurrentProfile(profile); + } QFile conf(path); qDebug() << "Core::loadConfiguration: reading from " << path; @@ -768,10 +775,7 @@ void Core::loadConfiguration(QString path) // set GUI with user and statusmsg QString name = getUsername(); if (name != "") - { emit usernameSet(name); - Settings::getInstance().setCurrentProfile(name); - } QString msg = getStatusMessage(); if (msg != "") @@ -825,6 +829,7 @@ void Core::loadFriends() { const uint32_t friendCount = tox_count_friendlist(tox); if (friendCount > 0) { + emit clearFriends(); // assuming there are not that many friends to fill up the whole stack int32_t *ids = new int32_t[friendCount]; tox_get_friendlist(tox, ids, friendCount); diff --git a/core.h b/core.h index 6ccad0798..30a9bd270 100644 --- a/core.h +++ b/core.h @@ -126,7 +126,7 @@ public: void saveConfiguration(QString path = ""); void loadConfiguration(QString path = ""); - QString sanitize(QString name); + static QString sanitize(QString name); QString getUsername(); QString getStatusMessage(); @@ -177,6 +177,7 @@ signals: void friendMessageReceived(int friendId, const QString& message); void friendAdded(int friendId, const QString& userId); + void clearFriends(); void friendStatusChanged(int friendId, Status status); void friendStatusMessageChanged(int friendId, const QString& message); diff --git a/widget/form/settingsform.cpp b/widget/form/settingsform.cpp index f36f3e63b..aaf340bd5 100644 --- a/widget/form/settingsform.cpp +++ b/widget/form/settingsform.cpp @@ -21,8 +21,8 @@ #include #include -SettingsForm::SettingsForm(Core* core) - : QObject(), core(core) +SettingsForm::SettingsForm() + : QObject() { main = new QWidget(), head = new QWidget(); hboxcont1 = new QWidget(), hboxcont2 = new QWidget(); @@ -81,7 +81,7 @@ SettingsForm::SettingsForm(Core* core) layout.addWidget(&enableIPv6); layout.addWidget(&useTranslations); layout.addWidget(&makeToxPortable); - layout.addStretch(); + //layout.addStretch(); head->setLayout(&headLayout); headLayout.addWidget(&headLabel); @@ -113,7 +113,7 @@ void SettingsForm::populateProfiles() QString SettingsForm::getSelectedSavePath() { - return Settings::getSettingsDirPath() + profiles.currentText() + core->TOX_EXT; + return Settings::getSettingsDirPath() + profiles.currentText() + Widget::getInstance()->getCore()->TOX_EXT; } void SettingsForm::setFriendAddress(const QString& friendAddress) @@ -133,33 +133,45 @@ void SettingsForm::show(Ui::Widget &ui) void SettingsForm::onLoadClicked() { - core->saveConfiguration(); - core->loadConfiguration(getSelectedSavePath()); + Widget::getInstance()->getCore()->saveConfiguration(); + Widget::getInstance()->getCore()->loadConfiguration(getSelectedSavePath()); // loadConf also setsCurrentProfile } void SettingsForm::onExportClicked() { QString current = getSelectedSavePath(); - QString path = QFileDialog::getSaveFileName(0, tr("Export profile", "save dialog title"), QDir::homePath() + '/' + profiles.currentText() + core->TOX_EXT, tr("Tox save file (*.tox)", "save dialog filter")); - // dunno if that "~" works + QString path = QFileDialog::getSaveFileName(0, tr("Export profile", "save dialog title"), QDir::homePath() + '/' + profiles.currentText() + Widget::getInstance()->getCore()->TOX_EXT, tr("Tox save file (*.tox)", "save dialog filter")); QFile::copy(getSelectedSavePath(), path); } void SettingsForm::onDeleteClicked() -{ // this should really be guarded by a pop up - QFile::remove(getSelectedSavePath()); +{ + if (Settings::getInstance().getCurrentProfile() == profiles.currentText()) + { + QMessageBox::warning(main, 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(main, + 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(getSelectedSavePath()); + profiles.removeItem(profiles.currentIndex()); + } + } } void SettingsForm::onImportClicked() { QString path = QFileDialog::getOpenFileName(0, tr("Import profile", "import dialog title"), QDir::homePath(), tr("Tox save file (*.tox)", "import dialog filter")); - // again, the "~"... QFileInfo info(path); QString profile = info.completeBaseName(); - QString profilePath = Settings::getSettingsDirPath() + profile + core->TOX_EXT; + QString profilePath = Settings::getSettingsDirPath() + profile + Widget::getInstance()->getCore()->TOX_EXT; QFile::copy(path, profilePath); - core->loadConfiguration(profilePath); + Widget::getInstance()->getCore()->loadConfiguration(profilePath); + profiles.addItem(profile); } void SettingsForm::onTestVideoClicked() diff --git a/widget/form/settingsform.h b/widget/form/settingsform.h index 3a69a1a70..cb5ad1e12 100644 --- a/widget/form/settingsform.h +++ b/widget/form/settingsform.h @@ -30,6 +30,7 @@ #include #include #include +#include #include "widget/tool/clickablelabel.h" #include "ui_widget.h" #include "widget/selfcamview.h" @@ -39,7 +40,7 @@ class SettingsForm : public QObject { Q_OBJECT public: - SettingsForm(Core* core); + SettingsForm(); ~SettingsForm(); void show(Ui::Widget& ui); @@ -71,7 +72,6 @@ private: QWidget *main, *head, *hboxcont1, *hboxcont2; void populateProfiles(); QString getSelectedSavePath(); - Core* core; public: //QLineEdit name, statusText; diff --git a/widget/widget.cpp b/widget/widget.cpp index 565fc15f9..1cb3ba40c 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -141,8 +141,6 @@ Widget::Widget(QWidget *parent) : isWindowMinimized = 0; - settingsForm = new SettingsForm(core); - ui->mainContent->setLayout(new QVBoxLayout()); ui->mainHead->setLayout(new QVBoxLayout()); ui->mainHead->layout()->setMargin(0); @@ -221,11 +219,12 @@ Widget::Widget(QWidget *parent) : connect(core, &Core::statusSet, this, &Widget::onStatusSet); connect(core, &Core::usernameSet, this, &Widget::setUsername); connect(core, &Core::statusMessageSet, this, &Widget::setStatusMessage); - connect(core, &Core::friendAddressGenerated, settingsForm, &SettingsForm::setFriendAddress); + connect(core, &Core::friendAddressGenerated, &settingsForm, &SettingsForm::setFriendAddress); connect(core, SIGNAL(fileDownloadFinished(const QString&)), &filesForm, SLOT(onFileDownloadComplete(const QString&))); connect(core, SIGNAL(fileUploadFinished(const QString&)), &filesForm, SLOT(onFileUploadComplete(const QString&))); connect(core, &Core::friendAdded, this, &Widget::addFriend); connect(core, &Core::failedToAddFriend, this, &Widget::addFriendFailed); + connect(core, &Core::clearFriends, this, &Widget::clearFriends); connect(core, &Core::friendStatusChanged, this, &Widget::onFriendStatusChanged); connect(core, &Core::friendUsernameChanged, this, &Widget::onFriendUsernameChanged); connect(core, &Core::friendStatusChanged, this, &Widget::onFriendStatusChanged); @@ -285,7 +284,6 @@ Widget::~Widget() settings.setValue("geometry", geometry()); settings.setValue("maximized", isMaximized()); settings.setValue("useNativeTheme", useNativeTheme); - delete settingsForm; delete ui; } @@ -396,7 +394,7 @@ void Widget::onTransferClicked() void Widget::onSettingsClicked() { hideMainForms(); - settingsForm->show(*ui); + settingsForm.show(*ui); isFriendWidgetActive = 0; isGroupWidgetActive = 0; } @@ -439,11 +437,12 @@ void Widget::onUsernameChanged(const QString& newUsername, const QString& oldUse //settingsForm.name.setText(oldUsername); core->setUsername(newUsername); - // move the data file with it + /*// move the data file with it QString dir = Settings::getSettingsDirPath(); - QFile::rename(dir + '/' + oldUsername + core->TOX_EXT, dir + '/' + newUsername + core->TOX_EXT); + QFile::rename(dir + '/' + core->sanitize(oldUsername) + core->TOX_EXT, dir + '/' + core->sanitize(newUsername) + core->TOX_EXT); // and update current profile Settings::getInstance().setCurrentProfile(newUsername); + */ } // ugh... Widget::onUsernameChanged() calls Core::setUsername, // which emits Core::usernameSet, which is connect to this function: @@ -649,19 +648,29 @@ 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 (f->widget == activeFriendWidget) activeFriendWidget = 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::clearFriends() +{ // used for dynamic profile loading + for (Friend* f : FriendList::friendList) + removeFriend(f); +} + void Widget::copyFriendIdToClipboard(int friendId) { Friend* f = FriendList::findFriend(friendId); diff --git a/widget/widget.h b/widget/widget.h index b936cca5a..7bcc643a8 100644 --- a/widget/widget.h +++ b/widget/widget.h @@ -106,6 +106,7 @@ private slots: void onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t change); void onGroupWidgetClicked(GroupWidget* widget); void removeFriend(int friendId); + void clearFriends(); void copyFriendIdToClipboard(int friendId); void removeGroup(int groupId); void splitterMoved(int pos, int index); @@ -119,6 +120,7 @@ protected slots: private: void hideMainForms(); Group* createGroup(int groupId); + void removeFriend(Friend* f); private: Ui::Widget *ui; @@ -142,7 +144,7 @@ private: Core* core; QThread* coreThread; AddFriendForm friendForm; - SettingsForm* settingsForm; + SettingsForm settingsForm; FilesForm filesForm; static Widget* instance; FriendWidget* activeFriendWidget; From b4a42cb34a13da3eff70a1b7f623980543d8d760 Mon Sep 17 00:00:00 2001 From: Bill Winslow Date: Thu, 24 Jul 2014 14:50:47 -0500 Subject: [PATCH 05/21] more incremental changes, nothing works yet (I just want to change branches) --- core.cpp | 40 ++++++++++++++++++++++++---------------- core.h | 6 ++++-- settings.cpp | 2 +- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/core.cpp b/core.cpp index 150a94c0f..3a57db0d2 100644 --- a/core.cpp +++ b/core.cpp @@ -732,6 +732,7 @@ QString Core::sanitize(QString name) void Core::loadConfiguration(QString path) { // note to self: this really needs refactoring into the GUI, making the path mandatory here // but for now it's bedtime + // also loadFriends/clearFriends is borked as fuck if (path == "") { // read from settings whose profile? @@ -784,28 +785,35 @@ void Core::loadConfiguration(QString path) loadFriends(); } -void Core::saveConfiguration(QString path) +void Core::saveConfiguration() +{ + 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(); + if (profile == "") + { // no profile active; this should only happen on startup, if at all + profile = sanitize(getUsername()); + Settings::getInstance().setCurrentProfile(profile); + } + + QString path = dir + profile + TOX_EXT; + QFileInfo info(path); + if (!info.exists()) // fall back to old school 'data' + path = dir + '/' + CONFIG_FILE_NAME; +} + +void Core::saveConfiguration(const QString& path) { if (!tox) { qWarning() << "Core::saveConfiguration: Tox not started, aborting!"; return; } - - if (path == "") - { - QString dir = Settings::getSettingsDirPath(); - QDir directory(dir); - if (!directory.exists() && !directory.mkpath(directory.absolutePath())) { - qCritical() << "Error while creating directory " << dir; - return; - } - - path = dir + Settings::getInstance().getCurrentProfile() + TOX_EXT; - QFileInfo info(dir); - if (!info.exists()) // fall back to old school 'data' - path = dir + '/' + CONFIG_FILE_NAME; - } QSaveFile configurationFile(path); if (!configurationFile.open(QIODevice::WriteOnly)) { diff --git a/core.h b/core.h index 30a9bd270..3467ef15c 100644 --- a/core.h +++ b/core.h @@ -124,8 +124,10 @@ public: void quitGroupChat(int groupId) const; void dispatchVideoFrame(vpx_image img) const; - void saveConfiguration(QString path = ""); - void loadConfiguration(QString path = ""); + void saveConfiguration(); + void saveConfiguration(const QString& path); + void loadConfiguration(QString path); + static QString sanitize(QString name); QString getUsername(); diff --git a/settings.cpp b/settings.cpp index 62a208df6..96eb9ae15 100644 --- a/settings.cpp +++ b/settings.cpp @@ -81,7 +81,7 @@ void Settings::load() enableIPv6 = s.value("enableIPv6", true).toBool(); useTranslations = s.value("useTranslations", true).toBool(); makeToxPortable = s.value("makeToxPortable", false).toBool(); - currentProfile = s.value("currentProfile", ".data").toString(); + currentProfile = s.value("currentProfile", "").toString(); s.endGroup(); s.beginGroup("Widgets"); From 08ab94bf5a6a56d870331d565147d28786ed737b Mon Sep 17 00:00:00 2001 From: Bill Winslow Date: Sun, 27 Jul 2014 03:27:15 -0500 Subject: [PATCH 06/21] more incremental commits, compiles and sort of works now --- core.cpp | 63 +++++++++++++++++++++--------------- core.h | 2 ++ widget/form/settingsform.cpp | 14 ++------ widget/widget.cpp | 3 +- 4 files changed, 44 insertions(+), 38 deletions(-) diff --git a/core.cpp b/core.cpp index 3a57db0d2..2403dcc2b 100644 --- a/core.cpp +++ b/core.cpp @@ -109,8 +109,22 @@ void Core::start() return; } - // this will attempt to get the last profile from settings - loadConfiguration(); + // where do we find the data file? + QString path; + { // read data from whose profile? + path = Settings::getSettingsDirPath() + '/' + Settings::getInstance().getCurrentProfile() + TOX_EXT; + +#if 1 // deprecation attempt + // if the last profile doesn't exist, fall back to old "data" + //! or maybe, should we give an option to choose other existing profiles? + QFile file(path); + if (!file.exists()) + { + path = Settings::getSettingsDirPath() + '/' + CONFIG_FILE_NAME; + } +#endif + } + loadConfiguration(path); tox_callback_friend_request(tox, onFriendRequest, this); tox_callback_friend_message(tox, onFriendMessage, this); @@ -591,6 +605,15 @@ void Core::removeGroup(int groupId) tox_del_groupchat(tox, groupId); } +QString Core::getIDString() +{ + uint8_t friendAddress[TOX_FRIEND_ADDRESS_SIZE]; + tox_get_address(tox, friendAddress); + return CFriendAddress::toString(friendAddress).left(12); + // 12 is the smallest multiple of four such that + // 16^n > 10^10 (which is roughly the planet's population) +} + QString Core::getUsername() { int size = tox_get_self_name_size(tox); @@ -609,8 +632,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(); } } @@ -730,28 +753,8 @@ QString Core::sanitize(QString name) } void Core::loadConfiguration(QString path) -{ // note to self: this really needs refactoring into the GUI, making the path mandatory here - // but for now it's bedtime - // also loadFriends/clearFriends is borked as fuck - if (path == "") - { - // read from settings whose profile? - QString profile = Settings::getInstance().getCurrentProfile(); - path = Settings::getSettingsDirPath() + '/' + Settings::getInstance().getCurrentProfile() + TOX_EXT; - QFile file(path); - - // if the last profile doesn't exist, fall back to old "data" - if (!file.exists()) - { - path = Settings::getSettingsDirPath() + '/' + CONFIG_FILE_NAME; - } - } - else - { - QString profile = QFileInfo(path).completeBaseName(); - Settings::getInstance().setCurrentProfile(profile); - } - +{ // also loadFriends/clearFriends is borked as fuck + // setting the profile is now the responsibility of the caller QFile conf(path); qDebug() << "Core::loadConfiguration: reading from " << path; @@ -795,16 +798,24 @@ void Core::saveConfiguration() } 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 + profile + TOX_EXT; QFileInfo info(path); if (!info.exists()) // fall back to old school 'data' - path = dir + '/' + CONFIG_FILE_NAME; + { //path = dir + '/' + CONFIG_FILE_NAME; + qDebug() << path << " does not exist"; + } + + saveConfiguration(path); } void Core::saveConfiguration(const QString& path) diff --git a/core.h b/core.h index 3467ef15c..9ba3e2778 100644 --- a/core.h +++ b/core.h @@ -130,6 +130,8 @@ public: static QString sanitize(QString name); + QString getIDString(); + QString getUsername(); QString getStatusMessage(); diff --git a/widget/form/settingsform.cpp b/widget/form/settingsform.cpp index aaf340bd5..877685a8c 100644 --- a/widget/form/settingsform.cpp +++ b/widget/form/settingsform.cpp @@ -31,9 +31,6 @@ SettingsForm::SettingsForm() small.setPixelSize(13); headLabel.setText(tr("User Settings","\"Headline\" of the window")); headLabel.setFont(bold); - - //nameLabel.setText(tr("Name","Username/nick")); - //statusTextLabel.setText(tr("Status","Status message")); idLabel.setText("Tox ID " + tr("(click here to copy)", "Click on this text to copy TID to clipboard")); id.setFont(small); @@ -44,7 +41,6 @@ SettingsForm::SettingsForm() id.setFixedHeight(id.document()->size().height()); profilesLabel.setText(tr("Available profiles:", "Labels the profile selection box")); - populateProfiles(); loadConf.setText(tr("Load profile", "button to load selected profile")); exportConf.setText(tr("Export profile", "button to save selected profile elsewhere")); delConf.setText(tr("Delete profile", "button to delete selected profile from disk")); @@ -61,10 +57,6 @@ SettingsForm::SettingsForm() makeToxPortable.setChecked(Settings::getInstance().getMakeToxPortable()); main->setLayout(&layout); - //layout.addWidget(&nameLabel); - //layout.addWidget(&name); - //layout.addWidget(&statusTextLabel); - //layout.addWidget(&statusText); layout.addWidget(&idLabel); layout.addWidget(&id); cbox.addWidget(&profilesLabel); @@ -123,8 +115,7 @@ void SettingsForm::setFriendAddress(const QString& friendAddress) void SettingsForm::show(Ui::Widget &ui) { - //name.setText(ui.nameLabel->text()); - //statusText.setText(ui.statusLabel->text()); + populateProfiles(); ui.mainContent->layout()->addWidget(main); ui.mainHead->layout()->addWidget(head); main->show(); @@ -134,8 +125,8 @@ void SettingsForm::show(Ui::Widget &ui) void SettingsForm::onLoadClicked() { Widget::getInstance()->getCore()->saveConfiguration(); + Settings::getInstance().setCurrentProfile(profiles.currentText()); Widget::getInstance()->getCore()->loadConfiguration(getSelectedSavePath()); - // loadConf also setsCurrentProfile } void SettingsForm::onExportClicked() @@ -169,6 +160,7 @@ void SettingsForm::onImportClicked() QFileInfo info(path); QString profile = info.completeBaseName(); QString profilePath = Settings::getSettingsDirPath() + profile + Widget::getInstance()->getCore()->TOX_EXT; + Settings::getInstance().setCurrentProfile(profile); QFile::copy(path, profilePath); Widget::getInstance()->getCore()->loadConfiguration(profilePath); profiles.addItem(profile); diff --git a/widget/widget.cpp b/widget/widget.cpp index 1cb3ba40c..9fb07d766 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -208,8 +208,9 @@ Widget::Widget(QWidget *parent) : qRegisterMetaType("ToxFile"); qRegisterMetaType("ToxFile::FileDirection"); + // QString path = detectProfiles(); coreThread = new QThread(this); - core = new Core(camera, coreThread); + core = new Core(camera, coreThread/*, profile*/); core->moveToThread(coreThread); connect(coreThread, &QThread::started, core, &Core::start); From 5b6ccf67fd4c98436fc3eae413470811cea3a285 Mon Sep 17 00:00:00 2001 From: Bill Winslow Date: Mon, 28 Jul 2014 16:52:05 -0500 Subject: [PATCH 07/21] incremental, commiting in order to push --- widget/form/settingsform.cpp | 15 +++++++++++---- widget/form/settingsform.h | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/widget/form/settingsform.cpp b/widget/form/settingsform.cpp index 877685a8c..573d80101 100644 --- a/widget/form/settingsform.cpp +++ b/widget/form/settingsform.cpp @@ -93,14 +93,17 @@ SettingsForm::~SettingsForm() { } -void SettingsForm::populateProfiles() +QList SettingsForm::searchProfiles() { + QList out; QDir dir(Settings::getSettingsDirPath()); dir.setFilter(QDir::Files | QDir::NoDotAndDotDot); dir.setNameFilters(QStringList("*.tox")); - for(QFileInfo file : dir.entryInfoList()) { - profiles.addItem(file.completeBaseName()); + for(QFileInfo file : dir.entryInfoList()) + { + out += file.completeBaseName(); } + return out; } QString SettingsForm::getSelectedSavePath() @@ -115,7 +118,11 @@ void SettingsForm::setFriendAddress(const QString& friendAddress) void SettingsForm::show(Ui::Widget &ui) { - populateProfiles(); + profiles.clear(); + for (QString profile : searchProfiles()) + { + profiles.addItem(profile); + } ui.mainContent->layout()->addWidget(main); ui.mainHead->layout()->addWidget(head); main->show(); diff --git a/widget/form/settingsform.h b/widget/form/settingsform.h index cb5ad1e12..a14ed9142 100644 --- a/widget/form/settingsform.h +++ b/widget/form/settingsform.h @@ -44,6 +44,7 @@ public: ~SettingsForm(); void show(Ui::Widget& ui); + static QList searchProfiles(); public slots: void setFriendAddress(const QString& friendAddress); @@ -70,7 +71,6 @@ private: QCheckBox enableIPv6, useTranslations, makeToxPortable; QVBoxLayout layout, headLayout; QWidget *main, *head, *hboxcont1, *hboxcont2; - void populateProfiles(); QString getSelectedSavePath(); public: From 97f107e7f5c9f1d2d204586b09148e1a9f002d21 Mon Sep 17 00:00:00 2001 From: Dubslow Date: Fri, 5 Sep 2014 05:06:35 -0500 Subject: [PATCH 08/21] oops --- core.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core.cpp b/core.cpp index db9e62b2c..81f7b1030 100644 --- a/core.cpp +++ b/core.cpp @@ -909,7 +909,7 @@ void Core::saveConfiguration() Settings::getInstance().setCurrentProfile(profile); } - QString path = dir + profile + TOX_EXT; + QString path = dir + '/' + profile + TOX_EXT; QFileInfo info(path); if (!info.exists()) // fall back to old school 'data' { //path = dir + '/' + CONFIG_FILE_NAME; From 05c654373fd61b483edaa8602d4bea2c08ab9d1f Mon Sep 17 00:00:00 2001 From: Dubslow Date: Wed, 10 Sep 2014 08:12:43 -0500 Subject: [PATCH 09/21] Fixed misusing tox_load; profiles are significantly less buggy --- core.cpp | 30 +++++++++++++++++++++++++----- core.h | 9 ++++++--- widget/form/settingsform.cpp | 10 ++++------ 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/core.cpp b/core.cpp index 81f7b1030..e23d3661d 100644 --- a/core.cpp +++ b/core.cpp @@ -113,7 +113,7 @@ Core::~Core() alcCaptureCloseDevice(alInDev); } -void Core::start() +void Core::get_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(); @@ -160,13 +160,18 @@ void Core::start() emit failedToStart(); return; } +} + +void Core::start() +{ + get_tox(); qsrand(time(nullptr)); // where do we find the data file? QString path; { // read data from whose profile? - path = Settings::getSettingsDirPath() + '/' + Settings::getInstance().getCurrentProfile() + TOX_EXT; + path = Settings::getSettingsDirPath() + QDir::separator() + Settings::getInstance().getCurrentProfile() + TOX_EXT; #if 1 // deprecation attempt // if the last profile doesn't exist, fall back to old "data" @@ -174,7 +179,7 @@ void Core::start() QFile file(path); if (!file.exists()) { - path = Settings::getSettingsDirPath() + '/' + CONFIG_FILE_NAME; + path = Settings::getSettingsDirPath() + QDir::separator() + CONFIG_FILE_NAME; } #endif } @@ -909,10 +914,10 @@ void Core::saveConfiguration() Settings::getInstance().setCurrentProfile(profile); } - QString path = dir + '/' + profile + TOX_EXT; + QString path = dir + QDir::separator() + profile + TOX_EXT; QFileInfo info(path); if (!info.exists()) // fall back to old school 'data' - { //path = dir + '/' + CONFIG_FILE_NAME; + { //path = dir + QDir::separator() + CONFIG_FILE_NAME; qDebug() << path << " does not exist"; } @@ -946,6 +951,21 @@ void Core::saveConfiguration(const QString& path) Settings::getInstance().save(); } +void Core::switchConfiguration(QString profile) +{ + saveConfiguration(); + + if (tox) { + toxav_kill(toxav); + tox_kill(tox); + } + + get_tox(); + + Settings::getInstance().setCurrentProfile(profile); + loadConfiguration(Settings::getSettingsDirPath() + QDir::separator() + profile + TOX_EXT); +} + void Core::loadFriends() { const uint32_t friendCount = tox_count_friendlist(tox); diff --git a/core.h b/core.h index 5de02e7f7..f07618b40 100644 --- a/core.h +++ b/core.h @@ -127,9 +127,7 @@ public: void saveConfiguration(); void saveConfiguration(const QString& path); - void loadConfiguration(QString path); - - static QString sanitize(QString name); + void switchConfiguration(QString profile); QString getIDString(); @@ -286,6 +284,11 @@ private: void checkConnection(); void onBootstrapTimer(); + + void loadConfiguration(QString path); + static QString sanitize(QString name); + + void get_tox(); void loadFriends(); diff --git a/widget/form/settingsform.cpp b/widget/form/settingsform.cpp index bb8c12093..e3f1660a0 100644 --- a/widget/form/settingsform.cpp +++ b/widget/form/settingsform.cpp @@ -120,7 +120,7 @@ QList SettingsForm::searchProfiles() QString SettingsForm::getSelectedSavePath() { - return Settings::getSettingsDirPath() + profiles.currentText() + Widget::getInstance()->getCore()->TOX_EXT; + return Settings::getSettingsDirPath() + QDir::separator() + profiles.currentText() + Widget::getInstance()->getCore()->TOX_EXT; } void SettingsForm::setFriendAddress(const QString& friendAddress) @@ -143,15 +143,13 @@ void SettingsForm::show(Ui::MainWindow &ui) void SettingsForm::onLoadClicked() { - Widget::getInstance()->getCore()->saveConfiguration(); - Settings::getInstance().setCurrentProfile(profiles.currentText()); - Widget::getInstance()->getCore()->loadConfiguration(getSelectedSavePath()); + Widget::getInstance()->getCore()->switchConfiguration(profiles.currentText()); } void SettingsForm::onExportClicked() { QString current = getSelectedSavePath(); - QString path = QFileDialog::getSaveFileName(0, tr("Export profile", "save dialog title"), QDir::homePath() + '/' + profiles.currentText() + Widget::getInstance()->getCore()->TOX_EXT, tr("Tox save file (*.tox)", "save dialog filter")); + QString path = QFileDialog::getSaveFileName(0, tr("Export profile", "save dialog title"), QDir::homePath() + QDir::separator() + profiles.currentText() + Widget::getInstance()->getCore()->TOX_EXT, tr("Tox save file (*.tox)", "save dialog filter")); QFile::copy(getSelectedSavePath(), path); } @@ -181,8 +179,8 @@ void SettingsForm::onImportClicked() QString profilePath = Settings::getSettingsDirPath() + profile + Widget::getInstance()->getCore()->TOX_EXT; Settings::getInstance().setCurrentProfile(profile); QFile::copy(path, profilePath); - Widget::getInstance()->getCore()->loadConfiguration(profilePath); profiles.addItem(profile); + Widget::getInstance()->getCore()->switchConfiguration(profile); } void SettingsForm::onTestVideoClicked() From b684e56df0317b87961e4fd46bc1ea272117224d Mon Sep 17 00:00:00 2001 From: Dubslow Date: Wed, 10 Sep 2014 08:36:11 -0500 Subject: [PATCH 10/21] simplification --- core.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core.cpp b/core.cpp index e23d3661d..1af2d4265 100644 --- a/core.cpp +++ b/core.cpp @@ -859,7 +859,7 @@ QString Core::sanitize(QString name) } void Core::loadConfiguration(QString path) -{ // also loadFriends/clearFriends is borked as fuck +{ // setting the profile is now the responsibility of the caller QFile conf(path); qDebug() << "Core::loadConfiguration: reading from " << path; @@ -959,6 +959,7 @@ void Core::switchConfiguration(QString profile) toxav_kill(toxav); tox_kill(tox); } + emit clearFriends(); get_tox(); @@ -970,7 +971,6 @@ void Core::loadFriends() { const uint32_t friendCount = tox_count_friendlist(tox); if (friendCount > 0) { - emit clearFriends(); // assuming there are not that many friends to fill up the whole stack int32_t *ids = new int32_t[friendCount]; tox_get_friendlist(tox, ids, friendCount); From e4c6216ba8665657766ef4296e6c1f1f06b8cdbf Mon Sep 17 00:00:00 2001 From: Dubslow Date: Wed, 10 Sep 2014 15:47:48 -0500 Subject: [PATCH 11/21] swapping profiles is now less buggy, but friends still don't come online --- core.cpp | 31 +++++++++++++++++++++++-------- core.h | 2 +- settings.h | 2 +- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/core.cpp b/core.cpp index 1af2d4265..12452eee6 100644 --- a/core.cpp +++ b/core.cpp @@ -687,6 +687,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 { @@ -789,7 +791,7 @@ void Core::onFileTransferFinished(ToxFile file) emit fileDownloadFinished(file.filePath); } -void Core::bootstrapDht() +void Core::bootstrapDht(bool reset) { const Settings& s = Settings::getInstance(); QList dhtServerList = s.getDhtServerList(); @@ -797,6 +799,13 @@ void Core::bootstrapDht() int listSize = dhtServerList.size(); static int j = qrand() % listSize, n=0; + if (reset) + { + n = 0; + bootstrapTimer->setInterval(TOX_BOOTSTRAP_INTERVAL); + return; + } + // We couldn't connect after trying 6 different nodes, let's try something else if (n>3) { @@ -811,7 +820,7 @@ void Core::bootstrapDht() { const Settings::DhtServer& dhtServer = dhtServerList[j % listSize]; if (tox_bootstrap_from_address(tox, dhtServer.address.toLatin1().data(), - qToBigEndian(dhtServer.port), CUserId(dhtServer.userId).data()) == 1) + dhtServer.port, CUserId(dhtServer.userId).data()) == 1) qDebug() << QString("Core: Bootstraping from ")+dhtServer.name+QString(", addr ")+dhtServer.address.toLatin1().data() +QString(", port ")+QString().setNum(dhtServer.port); else @@ -826,14 +835,17 @@ void Core::bootstrapDht() void Core::process() { - tox_do(tox); + if (tox) + { + tox_do(tox); #ifdef DEBUG - //we want to see the debug messages immediately - fflush(stdout); + //we want to see the debug messages immediately + fflush(stdout); #endif - checkConnection(); - //int toxInterval = tox_do_interval(tox); - //qDebug() << QString("Tox interval %1").arg(toxInterval); + checkConnection(); + //int toxInterval = tox_do_interval(tox); + //qDebug() << QString("Tox interval %1").arg(toxInterval); + } toxTimer->start(50); } @@ -957,11 +969,14 @@ void Core::switchConfiguration(QString profile) if (tox) { toxav_kill(toxav); + toxav = nullptr; tox_kill(tox); + tox = nullptr; } emit clearFriends(); get_tox(); + bootstrapDht(true); // reset this func Settings::getInstance().setCurrentProfile(profile); loadConfiguration(Settings::getSettingsDirPath() + QDir::separator() + profile + TOX_EXT); diff --git a/core.h b/core.h index f07618b40..49edb606e 100644 --- a/core.h +++ b/core.h @@ -140,7 +140,7 @@ public: public slots: void start(); void process(); - void bootstrapDht(); + void bootstrapDht(bool reset = false); void acceptFriendRequest(const QString& userId); void requestFriendship(const QString& friendAddress, const QString& message); diff --git a/settings.h b/settings.h index 6372c4baf..6533329dc 100644 --- a/settings.h +++ b/settings.h @@ -183,7 +183,7 @@ private: signals: //void dataChanged(); - void dhtServerListChanged(); + void dhtServerListChanged(bool reset = false); void logStorageOptsChanged(); void smileyPackChanged(); void emojiFontChanged(); From 72a76dba03445a8e83eb68a1ff1302a6a4f66e77 Mon Sep 17 00:00:00 2001 From: dubslow Date: Fri, 12 Sep 2014 14:38:14 -0500 Subject: [PATCH 12/21] implement sanitize, one tweak --- core.cpp | 10 +++++++++- widget/form/settingsform.cpp | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/core.cpp b/core.cpp index 548cc075b..4f0fb83c3 100644 --- a/core.cpp +++ b/core.cpp @@ -888,7 +888,15 @@ void Core::checkConnection() QString Core::sanitize(QString name) { - // do things + // these are pretty much Windows banned filename characters + QList 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; } diff --git a/widget/form/settingsform.cpp b/widget/form/settingsform.cpp index 4d5dc3114..6f05e49ad 100644 --- a/widget/form/settingsform.cpp +++ b/widget/form/settingsform.cpp @@ -141,6 +141,8 @@ void SettingsForm::show(Ui::MainWindow &ui) { profiles.addItem(profile); } + if (QString current = Settings::getInstance().getCurrentProfile()) + profiles.setCurrentText(current); ui.mainContent->layout()->addWidget(main); ui.mainHead->layout()->addWidget(head); main->show(); From 2181313d37daa7b8d6da521ab1946fe2de00a7de Mon Sep 17 00:00:00 2001 From: dubslow Date: Thu, 9 Oct 2014 00:30:33 -0500 Subject: [PATCH 13/21] add startup profile detection --- core.cpp | 30 +++++++----------------- core.h | 7 +++--- widget/widget.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++-- widget/widget.h | 4 +++- 4 files changed, 71 insertions(+), 28 deletions(-) diff --git a/core.cpp b/core.cpp index 6b899ab8b..7c97d3387 100644 --- a/core.cpp +++ b/core.cpp @@ -43,8 +43,8 @@ const QString Core::TOX_EXT = ".tox"; QList Core::fileSendQueue; QList 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; @@ -213,28 +213,14 @@ void Core::start() qsrand(time(nullptr)); - // where do we find the data file? - QString path; - { // read data from whose profile? - path = Settings::getSettingsDirPath() + QDir::separator() + Settings::getInstance().getCurrentProfile() + TOX_EXT; - -#if 1 // deprecation attempt - // if the last profile doesn't exist, fall back to old "data" - //! or maybe, should we give an option to choose other existing profiles? - QFile file(path); - if (!file.exists()) - { - path = Settings::getSettingsDirPath() + QDir::separator() + CONFIG_FILE_NAME; - } -#endif - } - if (!loadConfiguration(path)) + 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); @@ -1156,10 +1142,10 @@ void Core::saveConfiguration() 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() << path << " does not exist"; - } +// if (!info.exists()) // fall back to old school 'data' +// { //path = dir + QDir::separator() + CONFIG_FILE_NAME; +// qDebug() << "Core:" << path << " does not exist"; +// } saveConfiguration(path); } diff --git a/core.h b/core.h index 292c82494..7062072d3 100644 --- a/core.h +++ b/core.h @@ -34,11 +34,12 @@ 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; int getGroupNumberPeers(int groupId) const; QString getGroupPeerName(int groupId, int peerId) const; @@ -234,14 +235,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 dhtServerList; int dhtServerId; static QList 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 diff --git a/widget/widget.cpp b/widget/widget.cpp index f610e8187..a3b07bc1d 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include Widget *Widget::instance{nullptr}; @@ -118,9 +119,9 @@ Widget::Widget(QWidget *parent) qRegisterMetaType("ToxFile"); qRegisterMetaType("ToxFile::FileDirection"); - // QString path = detectProfiles(); + QString profilePath = detectProfile(); coreThread = new QThread(this); - core = new Core(camera, coreThread/*, profile*/); + core = new Core(camera, coreThread, profilePath); core->moveToThread(coreThread); connect(coreThread, &QThread::started, core, &Core::start); @@ -215,6 +216,59 @@ 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()) + { +#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 +#endif + return dir.filePath(askProfiles() + Core::TOX_EXT); + } + else + return path; +} + +QList Widget::searchProfiles() +{ + QList 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() +{ + QList profiles = searchProfiles(); + 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(); diff --git a/widget/widget.h b/widget/widget.h index 115fccab0..b93b224e1 100644 --- a/widget/widget.h +++ b/widget/widget.h @@ -56,6 +56,7 @@ public: void newMessageAlert(); bool isFriendWidgetCurActiveWidget(Friend* f); bool getIsWindowMinimized(); + static QList searchProfiles(); ~Widget(); virtual void closeEvent(QCloseEvent *event); @@ -112,8 +113,9 @@ private: virtual bool event(QEvent * e); Group* createGroup(int groupId); void removeFriend(Friend* f); + QString askProfiles(); + QString detectProfile(); -private: Ui::MainWindow *ui; QSplitter *centralLayout; QPoint dragPosition; From 7ce7da07761abb2ee783703066e8b4da1f1f465a Mon Sep 17 00:00:00 2001 From: dubslow Date: Thu, 9 Oct 2014 00:58:35 -0500 Subject: [PATCH 14/21] properly implement clearing contacts list --- widget/friendlistwidget.cpp | 19 +++++++++++++++++++ widget/friendlistwidget.h | 1 + widget/widget.cpp | 8 +------- widget/widget.h | 1 - 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/widget/friendlistwidget.cpp b/widget/friendlistwidget.cpp index 176850e82..feb8ffa26 100644 --- a/widget/friendlistwidget.cpp +++ b/widget/friendlistwidget.cpp @@ -66,3 +66,22 @@ void FriendListWidget::moveWidget(QWidget *w, Status s) mainLayout->removeWidget(w); getFriendLayout(s)->addWidget(w); } + +void clearLayout(QLayout *layout) +{ + QLayoutItem *item; + while((item = layout->takeAt(0))) + { + if (item->layout()) { + clearLayout(item->layout()); + delete item->layout(); + } + delete item->widget(); + delete item; + } +} + +void FriendListWidget::clear() +{ + clearLayout(mainLayout); +} diff --git a/widget/friendlistwidget.h b/widget/friendlistwidget.h index f8c3adf8c..2dd3d4fcd 100644 --- a/widget/friendlistwidget.h +++ b/widget/friendlistwidget.h @@ -38,6 +38,7 @@ public: signals: public slots: + void clear(); private: QHash layouts; diff --git a/widget/widget.cpp b/widget/widget.cpp index a3b07bc1d..98fdad678 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -137,7 +137,7 @@ Widget::Widget(QWidget *parent) connect(core, SIGNAL(fileUploadFinished(const QString&)), &filesForm, SLOT(onFileUploadComplete(const QString&))); connect(core, &Core::friendAdded, this, &Widget::addFriend); connect(core, &Core::failedToAddFriend, this, &Widget::addFriendFailed); - connect(core, &Core::clearFriends, this, &Widget::clearFriends); + connect(core, &Core::clearFriends, contactListWidget, &FriendListWidget::clear); connect(core, &Core::friendStatusChanged, this, &Widget::onFriendStatusChanged); connect(core, &Core::friendUsernameChanged, this, &Widget::onFriendUsernameChanged); connect(core, &Core::friendStatusChanged, this, &Widget::onFriendStatusChanged); @@ -637,12 +637,6 @@ void Widget::removeFriend(int friendId) removeFriend(FriendList::findFriend(friendId)); } -void Widget::clearFriends() -{ // used for dynamic profile loading - for (Friend* f : FriendList::friendList) - removeFriend(f); -} - void Widget::copyFriendIdToClipboard(int friendId) { Friend* f = FriendList::findFriend(friendId); diff --git a/widget/widget.h b/widget/widget.h index b93b224e1..2d86fa7d9 100644 --- a/widget/widget.h +++ b/widget/widget.h @@ -98,7 +98,6 @@ private slots: void onGroupMessageReceived(int groupnumber, const QString& message, const QString& author); void onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t change); void removeFriend(int friendId); - void clearFriends(); void copyFriendIdToClipboard(int friendId); void removeGroup(int groupId); void setStatusOnline(); From eb687b2bfe77622f84617cb18e788dd81cf19914 Mon Sep 17 00:00:00 2001 From: dubslow Date: Thu, 9 Oct 2014 01:23:33 -0500 Subject: [PATCH 15/21] readd profiles ui --- widget/form/settings/identitysettings.ui | 65 ++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/widget/form/settings/identitysettings.ui b/widget/form/settings/identitysettings.ui index d27300155..e68b99deb 100644 --- a/widget/form/settings/identitysettings.ui +++ b/widget/form/settings/identitysettings.ui @@ -59,6 +59,71 @@ + + + + Profiles + + + + + + + + Available profiles: + + + + + + + + + + + + + + Load + + + + + + + Rename + + + + + + + Export + + + + + + + Delete + + + This is useful to remain safe on public computers + + + + + + + + + Import a profile + + + + + + From 0050589cde303bd7328b0684b15b4fbdc931fbcc Mon Sep 17 00:00:00 2001 From: dubslow Date: Thu, 9 Oct 2014 03:07:26 -0500 Subject: [PATCH 16/21] (Re)implement profiles UI, using some of the old code. Avatars aren't handled on switching, and also something about friends disappearing... --- core.cpp | 10 ++-- core.h | 3 +- widget/form/settings/identityform.cpp | 74 ++++++++++++++++++++++++ widget/form/settings/identityform.h | 5 ++ widget/form/settings/identitysettings.ui | 2 +- widget/friendlistwidget.cpp | 19 ------ widget/friendlistwidget.h | 1 - widget/widget.cpp | 21 +++++-- widget/widget.h | 2 + 9 files changed, 105 insertions(+), 32 deletions(-) diff --git a/core.cpp b/core.cpp index 7c97d3387..27e0a0b12 100644 --- a/core.cpp +++ b/core.cpp @@ -633,8 +633,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 { @@ -1183,13 +1183,14 @@ void Core::switchConfiguration(QString profile) toxTimer->stop(); + Widget::getInstance()->clearContactsList(); // we need this to block, so no signals for us + if (tox) { toxav_kill(toxav); toxav = nullptr; tox_kill(tox); tox = nullptr; } - emit clearFriends(); make_tox(); @@ -1210,6 +1211,7 @@ void Core::switchConfiguration(QString profile) void Core::loadFriends() { const uint32_t friendCount = tox_count_friendlist(tox); + qDebug() << "Core: loading" << friendCount << "friends. profile:" << Settings::getInstance().getCurrentProfile(); if (friendCount > 0) { // assuming there are not that many friends to fill up the whole stack int32_t *ids = new int32_t[friendCount]; @@ -1218,7 +1220,7 @@ void Core::loadFriends() for (int32_t i = 0; i < static_cast(friendCount); ++i) { if (tox_get_client_id(tox, ids[i], clientId) == 0) { emit friendAdded(ids[i], CUserId::toString(clientId)); - + qDebug() << "Core: just added friend" << CUserId::toString(clientId); const int nameSize = tox_get_name_size(tox, ids[i]); if (nameSize > 0) { uint8_t *name = new uint8_t[nameSize]; diff --git a/core.h b/core.h index 7062072d3..f57a97342 100644 --- a/core.h +++ b/core.h @@ -40,6 +40,7 @@ public: 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; @@ -109,7 +110,6 @@ signals: void friendMessageReceived(int friendId, const QString& message, bool isAction); void friendAdded(int friendId, const QString& userId); - void clearFriends(); void friendStatusChanged(int friendId, Status status); void friendStatusMessageChanged(int friendId, const QString& message); @@ -218,7 +218,6 @@ private: bool checkConnection(); bool loadConfiguration(QString path); // Returns false for a critical error, true otherwise - static QString sanitize(QString name); void make_tox(); void loadFriends(); diff --git a/widget/form/settings/identityform.cpp b/widget/form/settings/identityform.cpp index 5aff0e513..a49a43b08 100644 --- a/widget/form/settings/identityform.cpp +++ b/widget/form/settings/identityform.cpp @@ -18,12 +18,17 @@ #include "ui_identitysettings.h" #include "identityform.h" #include "widget/form/settingswidget.h" +#include "misc/settings.h" #include "widget/croppinglabel.h" +#include "widget/widget.h" #include "core.h" #include #include #include #include +#include +#include +#include IdentityForm::IdentityForm() : GenericForm(tr("Your identity"), QPixmap(":/img/settings/identity.png")) @@ -50,6 +55,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() @@ -77,6 +87,12 @@ void IdentityForm::onStatusMessageEdited() void IdentityForm::updateContent() { toxId->setText(Core::getInstance()->getSelfId().toString()); + 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) @@ -88,3 +104,61 @@ 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::copy(dir.filePath(cur+Core::TOX_EXT), dir.filePath(name+Core::TOX_EXT)); + bodyUI->profiles->setItemText(bodyUI->profiles->currentIndex(), 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); +} diff --git a/widget/form/settings/identityform.h b/widget/form/settings/identityform.h index 2a4b07a77..a313aa135 100644 --- a/widget/form/settings/identityform.h +++ b/widget/form/settings/identityform.h @@ -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; diff --git a/widget/form/settings/identitysettings.ui b/widget/form/settings/identitysettings.ui index e68b99deb..47cb70f2e 100644 --- a/widget/form/settings/identitysettings.ui +++ b/widget/form/settings/identitysettings.ui @@ -75,7 +75,7 @@ - + diff --git a/widget/friendlistwidget.cpp b/widget/friendlistwidget.cpp index feb8ffa26..176850e82 100644 --- a/widget/friendlistwidget.cpp +++ b/widget/friendlistwidget.cpp @@ -66,22 +66,3 @@ void FriendListWidget::moveWidget(QWidget *w, Status s) mainLayout->removeWidget(w); getFriendLayout(s)->addWidget(w); } - -void clearLayout(QLayout *layout) -{ - QLayoutItem *item; - while((item = layout->takeAt(0))) - { - if (item->layout()) { - clearLayout(item->layout()); - delete item->layout(); - } - delete item->widget(); - delete item; - } -} - -void FriendListWidget::clear() -{ - clearLayout(mainLayout); -} diff --git a/widget/friendlistwidget.h b/widget/friendlistwidget.h index 2dd3d4fcd..f8c3adf8c 100644 --- a/widget/friendlistwidget.h +++ b/widget/friendlistwidget.h @@ -38,7 +38,6 @@ public: signals: public slots: - void clear(); private: QHash layouts; diff --git a/widget/widget.cpp b/widget/widget.cpp index 98fdad678..09aa0f8e0 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -137,7 +137,6 @@ Widget::Widget(QWidget *parent) connect(core, SIGNAL(fileUploadFinished(const QString&)), &filesForm, SLOT(onFileUploadComplete(const QString&))); connect(core, &Core::friendAdded, this, &Widget::addFriend); connect(core, &Core::failedToAddFriend, this, &Widget::addFriendFailed); - connect(core, &Core::clearFriends, contactListWidget, &FriendListWidget::clear); connect(core, &Core::friendStatusChanged, this, &Widget::onFriendStatusChanged); connect(core, &Core::friendUsernameChanged, this, &Widget::onFriendUsernameChanged); connect(core, &Core::friendStatusChanged, this, &Widget::onFriendStatusChanged); @@ -637,6 +636,14 @@ 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); @@ -700,19 +707,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(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; diff --git a/widget/widget.h b/widget/widget.h index 2d86fa7d9..a7f210d98 100644 --- a/widget/widget.h +++ b/widget/widget.h @@ -57,6 +57,7 @@ public: bool isFriendWidgetCurActiveWidget(Friend* f); bool getIsWindowMinimized(); static QList searchProfiles(); + void clearContactsList(); ~Widget(); virtual void closeEvent(QCloseEvent *event); @@ -112,6 +113,7 @@ private: virtual bool event(QEvent * e); Group* createGroup(int groupId); void removeFriend(Friend* f); + void removeGroup(Group* g); QString askProfiles(); QString detectProfile(); From 983879e799618003fb8750899e3fff2106609845 Mon Sep 17 00:00:00 2001 From: dubslow Date: Thu, 9 Oct 2014 03:59:35 -0500 Subject: [PATCH 17/21] IT WORKS, IT FINALLY WORKS --- core.cpp | 27 +++++++++------------------ widget/form/settings/identityform.cpp | 4 +++- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/core.cpp b/core.cpp index 27e0a0b12..a31ed51e2 100644 --- a/core.cpp +++ b/core.cpp @@ -279,9 +279,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() { @@ -936,6 +936,8 @@ void Core::removeFriend(int friendId) void Core::removeGroup(int groupId) { + if (!tox) + return; tox_del_groupchat(tox, groupId); } @@ -1183,35 +1185,24 @@ void Core::switchConfiguration(QString profile) toxTimer->stop(); - Widget::getInstance()->clearContactsList(); // we need this to block, so no signals for us - 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 - make_tox(); - + loadPath = QDir(Settings::getSettingsDirPath()).filePath(profile + TOX_EXT); Settings::getInstance().setCurrentProfile(profile); - if (!loadConfiguration(Settings::getSettingsDirPath() + QDir::separator() + profile + TOX_EXT)) - { - emit failedToStart(); - toxav_kill(toxav); - toxav = nullptr; - tox_kill(tox); - tox = nullptr; - return; - } - process(); // restarts toxTimer + start(); } void Core::loadFriends() { const uint32_t friendCount = tox_count_friendlist(tox); - qDebug() << "Core: loading" << friendCount << "friends. profile:" << Settings::getInstance().getCurrentProfile(); if (friendCount > 0) { // assuming there are not that many friends to fill up the whole stack int32_t *ids = new int32_t[friendCount]; @@ -1220,7 +1211,7 @@ void Core::loadFriends() for (int32_t i = 0; i < static_cast(friendCount); ++i) { if (tox_get_client_id(tox, ids[i], clientId) == 0) { emit friendAdded(ids[i], CUserId::toString(clientId)); - qDebug() << "Core: just added friend" << CUserId::toString(clientId); + const int nameSize = tox_get_name_size(tox, ids[i]); if (nameSize > 0) { uint8_t *name = new uint8_t[nameSize]; diff --git a/widget/form/settings/identityform.cpp b/widget/form/settings/identityform.cpp index a49a43b08..09be6af66 100644 --- a/widget/form/settings/identityform.cpp +++ b/widget/form/settings/identityform.cpp @@ -44,7 +44,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); @@ -72,6 +72,7 @@ void IdentityForm::copyIdClicked() QString txt = toxId->text(); txt.replace('\n',""); QApplication::clipboard()->setText(txt); + toxId->setCursorPosition(0); } void IdentityForm::onUserNameEdited() @@ -87,6 +88,7 @@ void IdentityForm::onStatusMessageEdited() void IdentityForm::updateContent() { toxId->setText(Core::getInstance()->getSelfId().toString()); + toxId->setCursorPosition(0); bodyUI->profiles->clear(); for (QString profile : Widget::searchProfiles()) bodyUI->profiles->addItem(profile); From a99e7d2b940a37004a18933e0cea9f8fd8c3cbca Mon Sep 17 00:00:00 2001 From: dubslow Date: Thu, 9 Oct 2014 04:26:32 -0500 Subject: [PATCH 18/21] tweaks --- widget/form/settings/identityform.cpp | 3 ++- widget/widget.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/widget/form/settings/identityform.cpp b/widget/form/settings/identityform.cpp index 09be6af66..cea181318 100644 --- a/widget/form/settings/identityform.cpp +++ b/widget/form/settings/identityform.cpp @@ -121,8 +121,9 @@ void IdentityForm::onRenameClicked() { name = Core::sanitize(name); QDir dir(Settings::getSettingsDirPath()); - QFile::copy(dir.filePath(cur+Core::TOX_EXT), dir.filePath(name+Core::TOX_EXT)); + 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); } } diff --git a/widget/widget.cpp b/widget/widget.cpp index 09aa0f8e0..84d18bc81 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -223,6 +223,7 @@ QString Widget::detectProfile() 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); From 6ab90d45162cf271359b47642069280f84fdd06b Mon Sep 17 00:00:00 2001 From: dubslow Date: Fri, 10 Oct 2014 17:07:18 -0500 Subject: [PATCH 19/21] read tox_save if no data; if no profiles, no popup --- core.cpp | 17 ++++++++++------- widget/widget.cpp | 13 +++++++++++-- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/core.cpp b/core.cpp index a31ed51e2..efaa68e7f 100644 --- a/core.cpp +++ b/core.cpp @@ -213,14 +213,17 @@ void Core::start() qsrand(time(nullptr)); - if (!loadConfiguration(loadPath)) // loadPath is meaningless after this - { - emit failedToStart(); - tox_kill(tox); - tox = nullptr; - return; + if (loadPath != "") + { + if (!loadConfiguration(loadPath)) // loadPath is meaningless after this + { + emit failedToStart(); + tox_kill(tox); + tox = nullptr; + return; + } + loadPath = ""; } - loadPath = ""; tox_callback_friend_request(tox, onFriendRequest, this); tox_callback_friend_message(tox, onFriendMessage, this); diff --git a/widget/widget.cpp b/widget/widget.cpp index 84d18bc81..85ce6ae3c 100644 --- a/widget/widget.cpp +++ b/widget/widget.cpp @@ -230,9 +230,17 @@ QString Widget::detectProfile() 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 - return dir.filePath(askProfiles() + Core::TOX_EXT); + { + profile = askProfiles(); + if (profile != "") + return dir.filePath(profile + Core::TOX_EXT); + else + return ""; + } } else return path; @@ -250,8 +258,9 @@ QList Widget::searchProfiles() } QString Widget::askProfiles() -{ +{ // TODO: allow user to create new Tox ID, even if a profile already exists QList profiles = searchProfiles(); + if (profiles.empty()) return ""; bool ok; QString profile = QInputDialog::getItem(this, tr("Choose a profile"), From 57943e2435f7ac30e7e7fb8d6d2620ea99f82ca9 Mon Sep 17 00:00:00 2001 From: apprb Date: Mon, 13 Oct 2014 00:02:55 +0900 Subject: [PATCH 20/21] FileTransferWidget improvements --- src/filetransferinstance.cpp | 16 +++++++++------- src/filetransferinstance.h | 1 + 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/filetransferinstance.cpp b/src/filetransferinstance.cpp index f3301e58a..ea3d74dee 100644 --- a/src/filetransferinstance.cpp +++ b/src/filetransferinstance.cpp @@ -24,7 +24,7 @@ #include #include -#define CONTENT_WIDTH 250 +#define MAX_CONTENT_WIDTH 250 #define MAX_PREVIEW_SIZE 25*1024*1024 uint FileTransferInstance::Idconter = 0; @@ -43,9 +43,10 @@ FileTransferInstance::FileTransferInstance(ToxFile File) // update this whenever you change the font in innerStyle.css QFontMetrics fm(Style::getFont(Style::Small)); - filenameElided = fm.elidedText(filename, Qt::ElideRight, CONTENT_WIDTH); - + filenameElided = fm.elidedText(filename, Qt::ElideRight, MAX_CONTENT_WIDTH); size = getHumanReadableSize(File.filesize); + contentPrefWidth = std::max(fm.width(filenameElided), fm.width(size)); + speed = "0B/s"; eta = "00:00"; @@ -57,7 +58,7 @@ FileTransferInstance::FileTransferInstance(ToxFile File) File.file->seek(0); if (preview.loadFromData(File.file->readAll())) { - pic = preview.scaledToHeight(50); + pic = preview.scaled(100, 50, Qt::KeepAspectRatio, Qt::SmoothTransformation); } } File.file->seek(0); @@ -127,7 +128,7 @@ void FileTransferInstance::onFileTransferFinished(ToxFile File) { if (preview.loadFromData(previewFile.readAll())) { - pic = preview.scaledToHeight(50); + pic = preview.scaled(100, 50, Qt::KeepAspectRatio, Qt::SmoothTransformation); } previewFile.close(); } @@ -377,7 +378,8 @@ QString FileTransferInstance::draw2ButtonsForm(const QString &type, const QImage QString imgBstr = ""; QString content; - QString progrBar = ""; + QString progrBar = ""; content = "

" + filenameElided + "

"; content += ""; @@ -421,7 +423,7 @@ QString FileTransferInstance::wrapIntoForm(const QString& content, const QString res += "
" + imgLeftA + "
" + imgLeftB + "
\n"; res += "\n"; res += insertMiniature(type); - res += "\n"; res += insertMiniature(type); - res += "\n"; + res += "\n"; res += "\n"; diff --git a/ui/chatArea/innerStyle.css b/ui/chatArea/innerStyle.css index 823c8dfbe..b5c537362 100644 --- a/ui/chatArea/innerStyle.css +++ b/ui/chatArea/innerStyle.css @@ -41,7 +41,7 @@ div.green { margin-top: 12px; margin-bottom: 12px; margin-left: 0px; - margin-right: 12px; + margin-right: 0px; color: @white; background-color: @green; font: @small; @@ -51,7 +51,7 @@ div.silver { margin-top: 12px; margin-bottom: 12px; margin-left: 0px; - margin-right: 12px; + margin-right: 0px; color: @black; background-color: @lightGrey; font: @small; @@ -61,7 +61,7 @@ div.red { margin-top: 12px; margin-bottom: 12px; margin-left: 0px; - margin-right: 12px; + margin-right: 0px; color: @white; background-color: @red; font: @small;
\n"; + res += "\n"; res += "
"; res += content; res += "
\n"; diff --git a/src/filetransferinstance.h b/src/filetransferinstance.h index f32c10f92..a4f6524ee 100644 --- a/src/filetransferinstance.h +++ b/src/filetransferinstance.h @@ -78,6 +78,7 @@ private: long long lastBytesSent, totalBytes; int fileNum; int friendId; + int contentPrefWidth; QString savePath; ToxFile::FileDirection direction; QString stopFileButtonStylesheet, pauseFileButtonStylesheet, acceptFileButtonStylesheet; From 339afafa050985acbfe9f4f5453590b8f108e5f0 Mon Sep 17 00:00:00 2001 From: apprb Date: Mon, 13 Oct 2014 16:43:20 +0900 Subject: [PATCH 21/21] magic number removed in FileTransferInstance --- src/filetransferinstance.cpp | 5 ++++- ui/chatArea/innerStyle.css | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/filetransferinstance.cpp b/src/filetransferinstance.cpp index ea3d74dee..158ddd65c 100644 --- a/src/filetransferinstance.cpp +++ b/src/filetransferinstance.cpp @@ -423,11 +423,14 @@ QString FileTransferInstance::wrapIntoForm(const QString& content, const QString res += "
" + imgLeftA + "
" + imgLeftB + "
\n"; res += "
\n"; + res += "\n"; res += "
"; res += content; res += "
\n"; res += "
\n"; + res += "
\n"; + res += "
\n"; res += "
" + imgAstr + "
" + imgBstr + "
\n"; res += "