1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

Remove deprecated profile management functions

This commit is contained in:
tux3 2015-06-04 11:37:54 +02:00
parent 933dce485d
commit abf65a5060
14 changed files with 85 additions and 393 deletions

View File

@ -103,7 +103,7 @@ Core::~Core()
{
qDebug() << "Deleting Core";
saveConfiguration();
profile.saveToxSave();
toxTimer->stop();
coreThread->exit(0);
while (coreThread->isRunning())
@ -339,7 +339,7 @@ void Core::start()
// This is useful for e.g. the profileForm that searches for saves.
if (isNewProfile)
{
saveConfiguration();
profile.saveToxSave();
emit idSet(getSelfId().toString());
}
@ -582,7 +582,7 @@ void Core::acceptFriendRequest(const QString& userId)
}
else
{
saveConfiguration();
profile.saveToxSave();
emit friendAdded(friendId, userId);
}
}
@ -627,7 +627,7 @@ void Core::requestFriendship(const QString& friendAddress, const QString& messag
emit friendAdded(friendId, userId);
}
}
saveConfiguration();
profile.saveToxSave();
}
int Core::sendMessage(uint32_t friendId, const QString& message)
@ -742,7 +742,7 @@ void Core::removeFriend(uint32_t friendId, bool fake)
}
else
{
saveConfiguration();
profile.saveToxSave();
emit friendRemoved(friendId);
}
}
@ -780,7 +780,7 @@ void Core::setUsername(const QString& username)
else
{
emit usernameSet(username);
saveConfiguration();
profile.saveToxSave();
}
}
@ -844,7 +844,7 @@ void Core::setStatusMessage(const QString& message)
}
else
{
saveConfiguration();
profile.saveToxSave();
emit statusMessageSet(message);
}
}
@ -869,7 +869,7 @@ void Core::setStatus(Status status)
}
tox_self_set_status(tox, userstatus);
saveConfiguration();
profile.saveToxSave();
emit statusSet(status);
}
@ -890,84 +890,13 @@ QString Core::sanitize(QString name)
return name;
}
void Core::saveConfiguration()
QByteArray Core::getToxSaveData()
{
if (QThread::currentThread() != coreThread)
return (void) QMetaObject::invokeMethod(this, "saveConfiguration");
if (!isReady())
return;
ProfileLocker::assertLock();
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());
if (profile == "") // happens on creation of a new Tox ID
profile = getIDString();
Settings::getInstance().switchProfile(profile);
}
QString path = directory.filePath(profile + TOX_EXT);
saveConfiguration(path);
}
void Core::switchConfiguration(const QString& _profile)
{
QString profile = QFileInfo(_profile).baseName();
// If we can't get a lock, then another instance is already using that profile
while (!profile.isEmpty() && !ProfileLocker::lock(profile))
{
qWarning() << "Profile "<<profile<<" is already in use, pick another";
GUI::showWarning(tr("Profile already in use"),
tr("This profile is already used by another qTox instance\n"
"Please select another profile"));
do {
profile = Settings::getInstance().askProfiles();
} while (profile.isEmpty());
}
if (profile.isEmpty())
qDebug() << "creating new Id";
else
qDebug() << "switching from" << Settings::getInstance().getCurrentProfile() << "to" << profile;
saveConfiguration();
saveCurrentInformation(); // part of a hack, see core.h
ready = false;
GUI::setEnabled(false);
clearPassword(ptMain);
clearPassword(ptHistory);
toxTimer->stop();
deadifyTox();
emit selfAvatarChanged(QPixmap(":/img/contact_dark.svg"));
emit blockingClearContacts(); // we need this to block, but signals are required for thread safety
//if (profile.isEmpty())
//loadPath = "";
//else
// loadPath = QDir(Settings::getSettingsDirPath()).filePath(profile + TOX_EXT);
Settings::getInstance().switchProfile(profile);
HistoryKeeper::resetInstance();
start();
uint32_t fileSize = tox_get_savedata_size(tox);
QByteArray data;
data.resize(fileSize);
tox_get_savedata(tox, (uint8_t*)data.data());
return data;
}
void Core::loadFriends()

View File

@ -92,9 +92,7 @@ public slots:
void process(); ///< Processes toxcore events and ensure we stay connected, called by its own timer
void bootstrapDht(); ///< Connects us to the Tox network
void saveConfiguration();
void saveConfiguration(const QString& path);
void switchConfiguration(const QString& profile); ///< Load a different profile and restart the core
QByteArray getToxSaveData(); ///< Returns the unencrypted tox save data
void acceptFriendRequest(const QString& userId);
void requestFriendship(const QString& friendAddress, const QString& message);
@ -303,16 +301,6 @@ private:
TOX_PASS_KEY* pwsaltedkeys[PasswordType::ptCounter] = {nullptr}; // use the pw's hash as the "pw"
// Hack for reloading current profile if switching to an encrypted one fails.
// Testing the passwords before killing the current profile is perfectly doable,
// however it would require major refactoring;
// the Core class as a whole also requires major refactoring (especially to support multiple IDs at once),
// so I'm punting on this until then, when it would get fixed anyways
TOX_PASS_KEY* backupkeys[PasswordType::ptCounter] = {nullptr};
QString* backupProfile = nullptr;
void saveCurrentInformation();
QString loadOldInformation();
static const int videobufsize;
static uint8_t* videobuf;

View File

@ -62,43 +62,6 @@ void Core::clearPassword(PasswordType passtype)
pwsaltedkeys[passtype] = nullptr;
}
// part of a hack, see core.h
void Core::saveCurrentInformation()
{
if (pwsaltedkeys[ptMain])
{
backupkeys[ptMain] = new TOX_PASS_KEY;
std::copy(pwsaltedkeys[ptMain], pwsaltedkeys[ptMain]+1, backupkeys[ptMain]);
}
if (pwsaltedkeys[ptHistory])
{
backupkeys[ptHistory] = new TOX_PASS_KEY;
std::copy(pwsaltedkeys[ptHistory], pwsaltedkeys[ptHistory]+1, backupkeys[ptHistory]);
}
backupProfile = new QString(Settings::getInstance().getCurrentProfile());
}
QString Core::loadOldInformation()
{
QString out;
if (backupProfile)
{
out = *backupProfile;
delete backupProfile;
backupProfile = nullptr;
}
backupProfile = nullptr;
clearPassword(ptMain);
clearPassword(ptHistory);
// we can just copy the pointer, as long as we null out backupkeys
// (if backupkeys was null anyways, then this is a null-op)
pwsaltedkeys[ptMain] = backupkeys[ptMain];
pwsaltedkeys[ptHistory] = backupkeys[ptHistory];
backupkeys[ptMain] = nullptr;
backupkeys[ptHistory] = nullptr;
return out;
}
QByteArray Core::encryptData(const QByteArray& data, PasswordType passtype)
{
if (!pwsaltedkeys[passtype])
@ -228,72 +191,3 @@ void Core::checkEncryptedHistory()
dialogtxt = a + "\n" + c + "\n" + b;
} while (error);
}
void Core::saveConfiguration(const QString& path)
{
if (QThread::currentThread() != coreThread)
return (void) QMetaObject::invokeMethod(this, "saveConfiguration", Q_ARG(const QString&, path));
if (!isReady())
{
qWarning() << "saveConfiguration: Tox not started, aborting!";
return;
}
QSaveFile configurationFile(path);
if (!configurationFile.open(QIODevice::WriteOnly))
{
qCritical() << "File " << path << " cannot be opened";
return;
}
qDebug() << "writing tox_save to " << path;
uint32_t fileSize = tox_get_savedata_size(tox);
bool encrypt = Settings::getInstance().getEncryptTox();
if (fileSize > 0 && fileSize <= std::numeric_limits<int32_t>::max())
{
uint8_t *data = new uint8_t[fileSize];
if (encrypt)
{
if (!pwsaltedkeys[ptMain])
{
// probably zero chance event
GUI::showWarning(tr("NO Password"), tr("Local file encryption is enabled, but there is no password! It will be disabled."));
Settings::getInstance().setEncryptTox(false);
tox_get_savedata(tox, data);
}
else
{
tox_get_savedata(tox, data);
uint8_t* newData = new uint8_t[fileSize+TOX_PASS_ENCRYPTION_EXTRA_LENGTH];
if (tox_pass_key_encrypt(data, fileSize, pwsaltedkeys[ptMain], newData, nullptr))
{
delete[] data;
data = newData;
fileSize+=TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
}
else
{
delete[] newData;
delete[] data;
qCritical() << "Core::saveConfiguration(QString): Encryption failed, couldn't save";
configurationFile.cancelWriting();
return;
}
}
}
else
{
tox_get_savedata(tox, data);
}
configurationFile.write(reinterpret_cast<char *>(data), fileSize);
configurationFile.commit();
delete[] data;
}
Settings::getInstance().save();
}

View File

@ -1282,3 +1282,11 @@ void Settings::createPersonal(QString basename)
ps.beginGroup("Privacy");
ps.endGroup();
}
void Settings::createSettingsDir()
{
QString dir = Settings::getSettingsDirPath();
QDir directory(dir);
if (!directory.exists() && !directory.mkpath(directory.absolutePath()))
qCritical() << "Error while creating directory " << dir;
}

View File

@ -36,6 +36,7 @@ public:
QString detectProfile();
QList<QString> searchProfiles();
QString askProfiles();
void createSettingsDir(); ///< Creates a path to the settings dir, if it doesn't already exist
void createPersonal(QString basename); ///< Write a default personnal settings file for a profile

View File

@ -148,7 +148,6 @@ void Nexus::showMainGUI()
connect(widget, &Widget::statusSet, core, &Core::setStatus);
connect(widget, &Widget::friendRequested, core, &Core::requestFriendship);
connect(widget, &Widget::friendRequestAccepted, core, &Core::acceptFriendRequest);
connect(widget, &Widget::changeProfile, core, &Core::switchConfiguration);
#endif
profile->startCore();

View File

@ -184,6 +184,11 @@ fail:
return data;
}
void Profile::saveToxSave()
{
saveToxSave(core->getToxSaveData());
}
void Profile::saveToxSave(QByteArray data)
{
ProfileLocker::assertLock();

View File

@ -27,7 +27,8 @@ public:
void startCore(); ///< Starts the Core thread
bool isNewProfile();
QByteArray loadToxSave(); ///< Loads the profile's .tox save from file, unencrypted
void saveToxSave(QByteArray data); ///< Saves the profile's .tox save, encrypted if needed
void saveToxSave(); ///< Saves the profile's .tox save, encrypted if needed
void saveToxSave(QByteArray data); ///< Saves the profile's .tox save with this data, encrypted if needed
/// Scan for profile, automatically importing them if needed
/// NOT thread-safe

View File

@ -26,6 +26,7 @@
#include "src/historykeeper.h"
#include "src/misc/style.h"
#include "src/profilelocker.h"
#include "src/profile.h"
#include <QLabel>
#include <QLineEdit>
#include <QGroupBox>
@ -35,17 +36,6 @@
#include <QFileDialog>
#include <QBuffer>
void ProfileForm::refreshProfiles()
{
bodyUI->profiles->clear();
for (QString profile : Settings::getInstance().searchProfiles())
bodyUI->profiles->addItem(profile);
QString current = Settings::getInstance().getCurrentProfile();
if (current != "")
bodyUI->profiles->setCurrentText(current);
}
ProfileForm::ProfileForm(QWidget *parent) :
QWidget{parent}, qr{nullptr}
{
@ -98,25 +88,12 @@ ProfileForm::ProfileForm(QWidget *parent) :
connect(bodyUI->toxIdLabel, SIGNAL(clicked()), this, SLOT(copyIdClicked()));
connect(toxId, SIGNAL(clicked()), this, SLOT(copyIdClicked()));
connect(core, &Core::idSet, this, &ProfileForm::setToxId);
connect(core, &Core::statusSet, this, &ProfileForm::onStatusSet);
connect(bodyUI->userName, SIGNAL(editingFinished()), this, SLOT(onUserNameEdited()));
connect(bodyUI->statusMessage, SIGNAL(editingFinished()), this, SLOT(onStatusMessageEdited()));
connect(bodyUI->loadButton, &QPushButton::clicked, this, &ProfileForm::onLoadClicked);
connect(bodyUI->renameButton, &QPushButton::clicked, this, &ProfileForm::onRenameClicked);
connect(bodyUI->exportButton, &QPushButton::clicked, this, &ProfileForm::onExportClicked);
connect(bodyUI->deleteButton, &QPushButton::clicked, this, &ProfileForm::onDeleteClicked);
connect(bodyUI->importButton, &QPushButton::clicked, this, &ProfileForm::onImportClicked);
connect(bodyUI->newButton, &QPushButton::clicked, this, &ProfileForm::onNewClicked);
connect(core, &Core::avStart, this, &ProfileForm::disableSwitching);
connect(core, &Core::avStarting, this, &ProfileForm::disableSwitching);
connect(core, &Core::avInvite, this, &ProfileForm::disableSwitching);
connect(core, &Core::avRinging, this, &ProfileForm::disableSwitching);
connect(core, &Core::avCancel, this, &ProfileForm::enableSwitching);
connect(core, &Core::avEnd, this, &ProfileForm::enableSwitching);
connect(core, &Core::avEnding, this, &ProfileForm::enableSwitching);
connect(core, &Core::avPeerTimeout, this, &ProfileForm::enableSwitching);
connect(core, &Core::avRequestTimeout, this, &ProfileForm::enableSwitching);
connect(bodyUI->logoutButton, &QPushButton::clicked, this, &ProfileForm::onLogoutClicked);
connect(core, &Core::usernameSet, this, [=](const QString& val) { bodyUI->userName->setText(val); });
connect(core, &Core::statusMessageSet, this, [=](const QString& val) { bodyUI->statusMessage->setText(val); });
@ -187,7 +164,6 @@ void ProfileForm::setToxId(const QString& id)
qr = new QRWidget();
qr->setQRData("tox:"+id);
bodyUI->qrCode->setPixmap(QPixmap::fromImage(qr->getImage()->scaledToWidth(150)));
refreshProfiles();
}
void ProfileForm::onAvatarClicked()
@ -250,22 +226,9 @@ void ProfileForm::onAvatarClicked()
Nexus::getCore()->setAvatar(bytes);
}
void ProfileForm::onLoadClicked()
{
if (bodyUI->profiles->currentText() != Settings::getInstance().getCurrentProfile())
{
if (Core::getInstance()->anyActiveCalls())
GUI::showWarning(tr("Call active", "popup title"),
tr("You can't switch profiles while a call is active!", "popup text"));
else
emit Widget::getInstance()->changeProfile(bodyUI->profiles->currentText());
// I think by directly calling the function, I may have been causing thread issues
}
}
void ProfileForm::onRenameClicked()
{
QString cur = bodyUI->profiles->currentText();
/** TODO: Create a rename (low level) function in Profile, use it
QString title = tr("Rename \"%1\"", "renaming a profile").arg(cur);
do
{
@ -297,11 +260,12 @@ void ProfileForm::onRenameClicked()
break;
}
} while (true);
*/
}
void ProfileForm::onExportClicked()
{
QString current = bodyUI->profiles->currentText() + Core::TOX_EXT;
QString current = Nexus::getProfile()->getName() + Core::TOX_EXT;
QString path = QFileDialog::getSaveFileName(0, tr("Export profile", "save dialog title"),
QDir::home().filePath(current),
tr("Tox save file (*.tox)", "save dialog filter"));
@ -319,6 +283,7 @@ void ProfileForm::onExportClicked()
void ProfileForm::onDeleteClicked()
{
/** Add a delete function in profile
if (Settings::getInstance().getCurrentProfile() == bodyUI->profiles->currentText())
{
GUI::showWarning(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"));
@ -340,76 +305,22 @@ void ProfileForm::onDeleteClicked()
bodyUI->profiles->setCurrentText(Settings::getInstance().getCurrentProfile());
}
}
*/
}
void ProfileForm::onImportClicked()
void ProfileForm::onLogoutClicked()
{
QString path = QFileDialog::getOpenFileName(0,
tr("Import profile", "import dialog title"),
QDir::homePath(),
tr("Tox save file (*.tox)", "import dialog filter"));
if (path.isEmpty())
return;
QFileInfo info(path);
QString profile = info.completeBaseName();
if (info.suffix() != "tox")
{
GUI::showWarning(tr("Ignoring non-Tox file", "popup title"),
tr("Warning: you've chosen a file that is not a Tox save file; ignoring.", "popup text"));
return;
}
QString profilePath = QDir(Settings::getSettingsDirPath()).filePath(profile + Core::TOX_EXT);
if (QFileInfo(profilePath).exists() && !GUI::askQuestion(tr("Profile already exists", "import confirm title"),
tr("A profile named \"%1\" already exists. Do you want to erase it?", "import confirm text").arg(profile)))
return;
QFile::copy(path, profilePath);
bodyUI->profiles->addItem(profile);
/// TODO: Save and call Nexus show login?
}
void ProfileForm::onStatusSet(Status)
{
refreshProfiles();
}
void ProfileForm::onNewClicked()
{
emit Widget::getInstance()->changeProfile(QString());
}
void ProfileForm::disableSwitching()
{
bodyUI->loadButton->setEnabled(false);
bodyUI->newButton->setEnabled(false);
}
void ProfileForm::enableSwitching()
{
if (!core->anyActiveCalls())
{
bodyUI->loadButton->setEnabled(true);
bodyUI->newButton->setEnabled(true);
}
}
void ProfileForm::showEvent(QShowEvent *event)
{
refreshProfiles();
QWidget::showEvent(event);
}
void ProfileForm::on_copyQr_clicked()
void ProfileForm::onCopyQrClicked()
{
QApplication::clipboard()->setImage(*qr->getImage());
}
void ProfileForm::on_saveQr_clicked()
void ProfileForm::onSaveQrClicked()
{
QString current = bodyUI->profiles->currentText() + ".png";
QString current = Nexus::getProfile()->getName() + ".png";
QString path = QFileDialog::getSaveFileName(0, tr("Save", "save qr image"),
QDir::home().filePath(current),
tr("Save QrCode (*.png)", "save dialog filter"));
@ -424,14 +335,3 @@ void ProfileForm::on_saveQr_clicked()
GUI::showWarning(tr("Failed to copy file"), tr("The file you chose could not be written to."));
}
}
bool ProfileForm::eventFilter(QObject *o, QEvent *e)
{
if ((e->type() == QEvent::Wheel) &&
(qobject_cast<QComboBox*>(o) || qobject_cast<QAbstractSpinBox*>(o) ))
{
e->ignore();
return true;
}
return QWidget::eventFilter(o, e);
}

View File

@ -56,7 +56,6 @@ signals:
public slots:
void onSelfAvatarLoaded(const QPixmap &pic);
void onStatusSet(Status status);
private slots:
void setToxId(const QString& id);
@ -64,21 +63,12 @@ private slots:
void onAvatarClicked();
void onUserNameEdited();
void onStatusMessageEdited();
void onLoadClicked();
void onRenameClicked();
void onExportClicked();
void onDeleteClicked();
void onImportClicked();
void onNewClicked();
void disableSwitching();
void enableSwitching();
void on_copyQr_clicked();
void on_saveQr_clicked();
protected:
virtual void showEvent(QShowEvent *);
bool eventFilter(QObject *o, QEvent *e);
void onLogoutClicked();
void onCopyQrClicked();
void onSaveQrClicked();
private:
void refreshProfiles();

View File

@ -37,10 +37,10 @@
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<x>-3</x>
<y>0</y>
<width>565</width>
<height>617</height>
<width>630</width>
<height>625</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="0,0,1">
@ -160,55 +160,44 @@ Share it with your friends to communicate.</string>
<item alignment="Qt::AlignTop">
<widget class="QGroupBox" name="profilesGroup">
<property name="title">
<string>Profiles</string>
<string>Profile</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">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string comment="toolTip for currently set profile">Currently selected profile.</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="profilesButtonsLayout">
<item>
<widget class="QPushButton" name="loadButton">
<property name="toolTip">
<string comment="tooltip for loading profile button">Load selected profile and switch to it.</string>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="text">
<string comment="load profile button">Load</string>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</widget>
</spacer>
</item>
<item>
<widget class="QPushButton" name="renameButton">
<property name="toolTip">
<string comment="tooltip for renaming profile button">Rename selected profile.</string>
<string comment="tooltip for renaming profile button">Rename profile.</string>
</property>
<property name="text">
<string comment="rename profile button">Rename</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="deleteButton">
<property name="toolTip">
<string comment="delete profile button tooltip">Delete profile.</string>
</property>
<property name="text">
<string comment="delete profile button">Delete</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="exportButton">
<property name="toolTip">
@ -221,38 +210,27 @@ Profile does not contain your history.</string>
</widget>
</item>
<item>
<widget class="QPushButton" name="deleteButton">
<widget class="QPushButton" name="logoutButton">
<property name="toolTip">
<string comment="delete profile button tooltip">Delete selected profile.</string>
<string comment="tooltip for logout button">Go back to the login screen</string>
</property>
<property name="text">
<string comment="delete profile button">Delete</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="profilesButtonsLayout2">
<item>
<widget class="QPushButton" name="importButton">
<property name="toolTip">
<string comment="tooltip for importing profile button">Import Tox profile from a .tox file.</string>
</property>
<property name="text">
<string comment="import profile button">Import a profile</string>
<string comment="import profile button">Logout</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="newButton">
<property name="toolTip">
<string comment="tooltip for creating new Tox ID button">Create new Tox ID and switch to it.</string>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="text">
<string comment="new profile button">New Tox ID</string>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</widget>
</spacer>
</item>
</layout>
</item>

View File

@ -349,9 +349,9 @@ void GeneralForm::onReconnectClicked()
{
if (Core::getInstance()->anyActiveCalls())
QMessageBox::warning(this, tr("Call active", "popup title"),
tr("You can't disconnect while a call is active!", "popup text"));
tr("You can't disconnect while a call is active!", "popup text"));
else
emit Widget::getInstance()->changeProfile(Settings::getInstance().getCurrentProfile());
; /// TODO: Add a reset function in Profile to save then restart toxcore
}
void GeneralForm::reloadSmiles()

View File

@ -218,7 +218,7 @@ bool PrivacyForm::setToxPassword()
core->setPassword(newpw, Core::ptMain);
Settings::getInstance().setEncryptTox(true);
core->saveConfiguration();
Settings::getInstance().save();
return true;
}
else

View File

@ -131,7 +131,6 @@ signals:
void statusSelected(Status status);
void usernameChanged(const QString& username);
void statusMessageChanged(const QString& statusMessage);
void changeProfile(const QString& profile);
void resized();
private slots: