tdesktop/Telegram/SourceFiles/settingswidget.cpp
John Preston 38c2915533 Fixes in floating dates with migrated histories.
All service messages are now not multiline (including pinned).
Confirmation for profile photo deleting will be added (not enabled).
Copy-by-selection should be supported in Linux version now.
Drafts that contain only reply-to-id (without text) support added.
2016-06-14 19:26:41 +03:00

2003 lines
67 KiB
C++

/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#include "stdafx.h"
#include "settingswidget.h"
#include "observer_peer.h"
#include "lang.h"
#include "boxes/aboutbox.h"
#include "mainwidget.h"
#include "application.h"
#include "boxes/photocropbox.h"
#include "boxes/connectionbox.h"
#include "boxes/backgroundbox.h"
#include "boxes/addcontactbox.h"
#include "boxes/emojibox.h"
#include "boxes/confirmbox.h"
#include "boxes/downloadpathbox.h"
#include "boxes/usernamebox.h"
#include "boxes/languagebox.h"
#include "boxes/passcodebox.h"
#include "boxes/autolockbox.h"
#include "boxes/sessionsbox.h"
#include "boxes/stickersetbox.h"
#include "langloaderplain.h"
#include "ui/filedialog.h"
#include "apiwrap.h"
#include "autoupdater.h"
#include "localstorage.h"
Slider::Slider(QWidget *parent, const style::slider &st, int32 count, int32 sel) : QWidget(parent),
_count(count), _sel(snap(sel, 0, _count)), _wasSel(_sel), _st(st), _pressed(false) {
resize(_st.width, _st.bar.pxHeight());
setCursor(style::cur_pointer);
}
void Slider::mousePressEvent(QMouseEvent *e) {
_pressed = true;
mouseMoveEvent(e);
}
void Slider::mouseMoveEvent(QMouseEvent *e) {
if (_pressed) {
int32 newSel = snap(qRound((_count - 1) * float64(e->pos().x() - _st.bar.pxWidth() / 2) / (width() - _st.bar.pxWidth())), 0, _count - 1);
if (newSel != _sel) {
_sel = newSel;
update();
}
}
}
void Slider::mouseReleaseEvent(QMouseEvent *e) {
_pressed = false;
if (_sel != _wasSel) {
emit changed(_wasSel);
_wasSel = _sel;
}
}
int32 Slider::selected() const {
return _sel;
}
void Slider::setSelected(int32 sel) {
if (_sel != sel) {
_sel = sel;
emit changed(_wasSel);
_wasSel = _sel;
update();
}
}
void Slider::paintEvent(QPaintEvent *e) {
Painter p(this);
p.fillRect(0, (height() - _st.thickness) / 2, width(), _st.thickness, _st.color->b);
int32 x = qFloor(_sel * float64(width() - _st.bar.pxWidth()) / (_count - 1)), y = (height() - _st.bar.pxHeight()) / 2;
p.drawSprite(QPoint(x, y), _st.bar);
}
QString scaleLabel(DBIScale scale) {
switch (scale) {
case dbisOne: return qsl("100%");
case dbisOneAndQuarter: return qsl("125%");
case dbisOneAndHalf: return qsl("150%");
case dbisTwo: return qsl("200%");
}
return QString();
}
bool scaleIs(DBIScale scale) {
return cRealScale() == scale || (cRealScale() == dbisAuto && cScreenScale() == scale);
}
SettingsInner::SettingsInner(SettingsWidget *parent) : TWidget(parent)
, _self(App::self())
// profile
, _nameCache(self() ? self()->name : QString())
, _uploadPhoto(this, lang(lng_settings_upload), st::btnSetUpload)
, _cancelPhoto(this, lang(lng_cancel))
, _nameOver(false)
, _photoOver(false)
, a_photoOver(0)
, _a_photo(animation(this, &SettingsInner::step_photo))
// contact info
, _phoneText(self() ? App::formatPhone(self()->phone()) : QString())
, _chooseUsername(this, (self() && !self()->username.isEmpty()) ? ('@' + self()->username) : lang(lng_settings_choose_username))
// notifications
, _desktopNotify(this, lang(lng_settings_desktop_notify), cDesktopNotify())
, _senderName(this, lang(lng_settings_show_name), cNotifyView() <= dbinvShowName)
, _messagePreview(this, lang(lng_settings_show_preview), cNotifyView() <= dbinvShowPreview)
, _windowsNotifications(this, lang(lng_settings_use_windows), cWindowsNotifications())
, _soundNotify(this, lang(lng_settings_sound_notify), cSoundNotify())
, _includeMuted(this, lang(lng_settings_include_muted), cIncludeMuted())
// general
, _changeLanguage(this, lang(lng_settings_change_lang))
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
, _autoUpdate(this, lang(lng_settings_auto_update), cAutoUpdate())
, _checkNow(this, lang(lng_settings_check_now))
, _restartNow(this, lang(lng_settings_update_now))
#endif
, _supportTray(cSupportTray())
, _workmodeTray(this, lang(lng_settings_workmode_tray), (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray))
, _workmodeWindow(this, lang(lng_settings_workmode_window), (cWorkMode() == dbiwmWindowOnly || cWorkMode() == dbiwmWindowAndTray))
, _autoStart(this, lang(lng_settings_auto_start), cAutoStart())
, _startMinimized(this, lang(lng_settings_start_min), cStartMinimized())
, _sendToMenu(this, lang(lng_settings_add_sendto), cSendToMenu())
, _dpiAutoScale(this, lng_settings_scale_auto(lt_cur, scaleLabel(cScreenScale())), (cConfigScale() == dbisAuto))
, _dpiSlider(this, st::dpiSlider, dbisScaleCount - 1, cEvalScale(cConfigScale()) - 1)
, _dpiWidth1(st::dpiFont1->width(scaleLabel(dbisOne)))
, _dpiWidth2(st::dpiFont2->width(scaleLabel(dbisOneAndQuarter)))
, _dpiWidth3(st::dpiFont3->width(scaleLabel(dbisOneAndHalf)))
, _dpiWidth4(st::dpiFont4->width(scaleLabel(dbisTwo)))
// chat options
, _replaceEmojis(this, lang(lng_settings_replace_emojis), cReplaceEmojis())
, _viewEmojis(this, lang(lng_settings_view_emojis))
, _stickers(this, lang(lng_stickers_you_have))
, _enterSend(this, qsl("send_key"), 0, lang(lng_settings_send_enter), !cCtrlEnter())
, _ctrlEnterSend(this, qsl("send_key"), 1, lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_settings_send_cmdenter : lng_settings_send_ctrlenter), cCtrlEnter())
, _dontAskDownloadPath(this, lang(lng_download_path_dont_ask), !cAskDownloadPath())
, _downloadPathWidth(st::linkFont->width(lang(lng_download_path_label)) + st::linkFont->spacew)
, _downloadPathEdit(this, cDownloadPath().isEmpty() ? lang(lng_download_path_default) : ((cDownloadPath() == qsl("tmp")) ? lang(lng_download_path_temp) : st::linkFont->elided(QDir::toNativeSeparators(cDownloadPath()), st::setWidth - st::cbDefFlat.textLeft - _downloadPathWidth)))
, _downloadPathClear(this, lang(lng_download_path_clear))
, _tempDirClearingWidth(st::linkFont->width(lang(lng_download_path_clearing)))
, _tempDirClearedWidth(st::linkFont->width(lang(lng_download_path_cleared)))
, _tempDirClearFailedWidth(st::linkFont->width(lang(lng_download_path_clear_failed)))
, _autoDownload(this, lang(lng_media_auto_settings))
// local storage
, _localStorageClear(this, lang(lng_local_storage_clear))
, _localStorageHeight(1)
, _storageClearingWidth(st::linkFont->width(lang(lng_local_storage_clearing)))
, _storageClearedWidth(st::linkFont->width(lang(lng_local_storage_cleared)))
, _storageClearFailedWidth(st::linkFont->width(lang(lng_local_storage_clear_failed)))
// chat background
, _backFromGallery(this, lang(lng_settings_bg_from_gallery))
, _backFromFile(this, lang(lng_settings_bg_from_file))
, _tileBackground(this, lang(lng_settings_bg_tile), cTileBackground())
, _adaptiveForWide(this, lang(lng_settings_adaptive_wide), Global::AdaptiveForWide())
, _needBackgroundUpdate(false)
// advanced
, _passcodeEdit(this, lang(cHasPasscode() ? lng_passcode_change : lng_passcode_turn_on))
, _passcodeTurnOff(this, lang(lng_passcode_turn_off))
, _autoLock(this, (cAutoLock() % 3600) ? lng_passcode_autolock_minutes(lt_count, cAutoLock() / 60) : lng_passcode_autolock_hours(lt_count, cAutoLock() / 3600))
, _autoLockText(lang(psIdleSupported() ? lng_passcode_autolock_away : lng_passcode_autolock_inactive) + ' ')
, _autoLockWidth(st::linkFont->width(_autoLockText))
, _passwordEdit(this, lang(lng_cloud_password_set))
, _passwordTurnOff(this, lang(lng_passcode_turn_off))
, _hasPasswordRecovery(false)
, _connectionType(this, lang(lng_connection_auto_connecting))
, _connectionTypeText(lang(lng_connection_type) + ' ')
, _connectionTypeWidth(st::linkFont->width(_connectionTypeText))
, _showSessions(this, lang(lng_settings_show_sessions))
, _askQuestion(this, lang(lng_settings_ask_question))
, _telegramFAQ(this, lang(lng_settings_faq))
, _logOut(this, lang(lng_settings_logout), st::btnRedLink)
, _supportGetRequest(0) {
Notify::registerPeerObserver(Notify::PeerUpdate::Flag::UsernameChanged, this, &SettingsInner::notifyPeerUpdated);
App::clearMousedItems();
if (self()) {
self()->loadUserpic();
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
connect(App::api(), SIGNAL(fullPeerUpdated(PeerData*)), this, SLOT(onFullPeerUpdated(PeerData*)));
_nameText.setText(st::setNameFont, _nameCache, _textNameOptions);
PhotoData *selfPhoto = (self()->photoId && self()->photoId != UnknownPeerPhotoId) ? App::photo(self()->photoId) : 0;
if (selfPhoto && selfPhoto->date) {
_photoLink.reset(new PhotoOpenClickHandler(selfPhoto, self()));
}
App::api()->requestFullPeer(self());
onReloadPassword();
connect(App::main(), SIGNAL(peerPhotoChanged(PeerData *)), this, SLOT(peerUpdated(PeerData *)));
connect(App::main(), SIGNAL(peerNameChanged(PeerData *, const PeerData::Names &, const PeerData::NameFirstChars &)), this, SLOT(peerUpdated(PeerData *)));
Sandbox::connect(SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(onReloadPassword(Qt::ApplicationState)));
}
// profile
connect(&_uploadPhoto, SIGNAL(clicked()), this, SLOT(onUpdatePhoto()));
connect(&_cancelPhoto, SIGNAL(clicked()), this, SLOT(onUpdatePhotoCancel()));
connect(App::app(), SIGNAL(peerPhotoDone(PeerId)), this, SLOT(onPhotoUpdateDone(PeerId)));
connect(App::app(), SIGNAL(peerPhotoFail(PeerId)), this, SLOT(onPhotoUpdateFail(PeerId)));
// contact info
connect(&_chooseUsername, SIGNAL(clicked()), this, SLOT(onUsername()));
// notifications
_senderName.setDisabled(!_desktopNotify.checked());
_messagePreview.setDisabled(_senderName.disabled() || !_senderName.checked());
connect(&_desktopNotify, SIGNAL(changed()), this, SLOT(onDesktopNotify()));
connect(&_senderName, SIGNAL(changed()), this, SLOT(onSenderName()));
connect(&_messagePreview, SIGNAL(changed()), this, SLOT(onMessagePreview()));
connect(&_windowsNotifications, SIGNAL(changed()), this, SLOT(onWindowsNotifications()));
connect(&_soundNotify, SIGNAL(changed()), this, SLOT(onSoundNotify()));
connect(&_includeMuted, SIGNAL(changed()), this, SLOT(onIncludeMuted()));
// general
connect(&_changeLanguage, SIGNAL(clicked()), this, SLOT(onChangeLanguage()));
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
connect(&_autoUpdate, SIGNAL(changed()), this, SLOT(onAutoUpdate()));
connect(&_checkNow, SIGNAL(clicked()), this, SLOT(onCheckNow()));
connect(&_restartNow, SIGNAL(clicked()), this, SLOT(onRestartNow()));
#endif
connect(&_workmodeTray, SIGNAL(changed()), this, SLOT(onWorkmodeTray()));
connect(&_workmodeWindow, SIGNAL(changed()), this, SLOT(onWorkmodeWindow()));
_startMinimized.setDisabled(!_autoStart.checked());
connect(&_autoStart, SIGNAL(changed()), this, SLOT(onAutoStart()));
connect(&_startMinimized, SIGNAL(changed()), this, SLOT(onStartMinimized()));
connect(&_sendToMenu, SIGNAL(changed()), this, SLOT(onSendToMenu()));
connect(&_dpiAutoScale, SIGNAL(changed()), this, SLOT(onScaleAuto()));
connect(&_dpiSlider, SIGNAL(changed(int32)), this, SLOT(onScaleChange()));
_curVersionText = lng_settings_current_version(lt_version, QString::fromLatin1(AppVersionStr.c_str()) + (cAlphaVersion() ? " alpha" : "") + (cBetaVersion() ? qsl(" beta %1").arg(cBetaVersion()) : QString())) + ' ';
_curVersionWidth = st::linkFont->width(_curVersionText);
_newVersionText = lang(lng_settings_update_ready) + ' ';
_newVersionWidth = st::linkFont->width(_newVersionText);
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
Sandbox::connect(SIGNAL(updateChecking()), this, SLOT(onUpdateChecking()));
Sandbox::connect(SIGNAL(updateLatest()), this, SLOT(onUpdateLatest()));
Sandbox::connect(SIGNAL(updateProgress(qint64,qint64)), this, SLOT(onUpdateDownloading(qint64,qint64)));
Sandbox::connect(SIGNAL(updateFailed()), this, SLOT(onUpdateFailed()));
Sandbox::connect(SIGNAL(updateReady()), this, SLOT(onUpdateReady()));
#endif
// chat options
connect(&_replaceEmojis, SIGNAL(changed()), this, SLOT(onReplaceEmojis()));
connect(&_viewEmojis, SIGNAL(clicked()), this, SLOT(onViewEmojis()));
connect(&_stickers, SIGNAL(clicked()), this, SLOT(onStickers()));
connect(&_enterSend, SIGNAL(changed()), this, SLOT(onEnterSend()));
connect(&_ctrlEnterSend, SIGNAL(changed()), this, SLOT(onCtrlEnterSend()));
connect(&_dontAskDownloadPath, SIGNAL(changed()), this, SLOT(onDontAskDownloadPath()));
connect(&_downloadPathEdit, SIGNAL(clicked()), this, SLOT(onDownloadPathEdit()));
connect(&_downloadPathClear, SIGNAL(clicked()), this, SLOT(onDownloadPathClear()));
switch (App::wnd()->tempDirState()) {
case MainWindow::TempDirEmpty: _tempDirClearState = TempDirEmpty; break;
case MainWindow::TempDirExists: _tempDirClearState = TempDirExists; break;
case MainWindow::TempDirRemoving: _tempDirClearState = TempDirClearing; break;
}
connect(App::wnd(), SIGNAL(tempDirCleared(int)), this, SLOT(onTempDirCleared(int)));
connect(App::wnd(), SIGNAL(tempDirClearFailed(int)), this, SLOT(onTempDirClearFailed(int)));
connect(&_autoDownload, SIGNAL(clicked()), this, SLOT(onAutoDownload()));
// local storage
connect(&_localStorageClear, SIGNAL(clicked()), this, SLOT(onLocalStorageClear()));
switch (App::wnd()->localStorageState()) {
case MainWindow::TempDirEmpty: _storageClearState = TempDirEmpty; break;
case MainWindow::TempDirExists: _storageClearState = TempDirExists; break;
case MainWindow::TempDirRemoving: _storageClearState = TempDirClearing; break;
}
// chat background
if (!cChatBackground()) App::initBackground();
updateChatBackground();
connect(&_backFromGallery, SIGNAL(clicked()), this, SLOT(onBackFromGallery()));
connect(&_backFromFile, SIGNAL(clicked()), this, SLOT(onBackFromFile()));
connect(&_tileBackground, SIGNAL(changed()), this, SLOT(onTileBackground()));
connect(&_adaptiveForWide, SIGNAL(changed()), this, SLOT(onAdaptiveForWide()));
// advanced
connect(&_passcodeEdit, SIGNAL(clicked()), this, SLOT(onPasscode()));
connect(&_passcodeTurnOff, SIGNAL(clicked()), this, SLOT(onPasscodeOff()));
connect(&_autoLock, SIGNAL(clicked()), this, SLOT(onAutoLock()));
connect(&_passwordEdit, SIGNAL(clicked()), this, SLOT(onPassword()));
connect(&_passwordTurnOff, SIGNAL(clicked()), this, SLOT(onPasswordOff()));
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
connect(&_connectionType, SIGNAL(clicked()), this, SLOT(onConnectionType()));
#endif
connect(&_showSessions, SIGNAL(clicked()), this, SLOT(onShowSessions()));
connect(&_askQuestion, SIGNAL(clicked()), this, SLOT(onAskQuestion()));
connect(&_telegramFAQ, SIGNAL(clicked()), this, SLOT(onTelegramFAQ()));
connect(&_logOut, SIGNAL(clicked()), App::wnd(), SLOT(onLogout()));
if (App::main()) {
connect(App::main(), SIGNAL(peerUpdated(PeerData*)), this, SLOT(peerUpdated(PeerData*)));
}
updateOnlineDisplay();
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
switch (Sandbox::updatingState()) {
case Application::UpdatingDownload:
setUpdatingState(UpdatingDownload, true);
setDownloadProgress(Sandbox::updatingReady(), Sandbox::updatingSize());
break;
case Application::UpdatingReady: setUpdatingState(UpdatingReady, true); break;
default: setUpdatingState(UpdatingNone, true); break;
}
#endif
updateConnectionType();
setMouseTracking(true);
}
void SettingsInner::notifyPeerUpdated(const Notify::PeerUpdate &update) {
if (update.peer == App::self()) {
if (update.flags & Notify::PeerUpdate::Flag::UsernameChanged) {
usernameChanged();
}
}
}
void SettingsInner::peerUpdated(PeerData *data) {
if (self() && data == self()) {
if (self()->photoId && self()->photoId != UnknownPeerPhotoId) {
PhotoData *selfPhoto = App::photo(self()->photoId);
if (selfPhoto->date) {
_photoLink.reset(new PhotoOpenClickHandler(selfPhoto, self()));
} else {
_photoLink.clear();
App::api()->requestFullPeer(self());
}
} else {
_photoLink.clear();
}
if (_nameCache != self()->name) {
_nameCache = self()->name;
_nameText.setText(st::setNameFont, _nameCache, _textNameOptions);
update();
}
}
}
void SettingsInner::paintEvent(QPaintEvent *e) {
bool animateBackground = false;
if (App::main() && App::main()->chatBackgroundLoading()) {
App::main()->checkChatBackground();
if (App::main()->chatBackgroundLoading()) {
animateBackground = true;
} else {
updateChatBackground();
}
} else if (_needBackgroundUpdate) {
updateChatBackground();
}
Painter p(this);
p.setClipRect(e->rect());
int32 top = 0;
if (self()) {
// profile
top += st::setTop;
_nameText.drawElided(p, _uploadPhoto.x() + st::setNameLeft, top + st::setNameTop, _uploadPhoto.width() - st::setNameLeft);
if (!_cancelPhoto.isHidden()) {
p.setFont(st::linkFont->f);
p.setPen(st::black->p);
p.drawText(_uploadPhoto.x() + st::setStatusLeft, _cancelPhoto.y() + st::linkFont->ascent, lang(lng_settings_uploading_photo));
}
if (_photoLink) {
self()->paintUserpicLeft(p, st::setPhotoSize, _left, top, st::setWidth);
} else {
if (a_photoOver.current() < 1) {
p.drawSprite(QPoint(_left, top), st::setPhotoImg);
}
if (a_photoOver.current() > 0) {
p.setOpacity(a_photoOver.current());
p.drawSprite(QPoint(_left, top), st::setOverPhotoImg);
p.setOpacity(1);
}
}
p.setFont(st::setStatusFont->f);
bool connecting = App::wnd()->connectingVisible();
p.setPen((connecting ? st::profileOfflineFg : st::profileOnlineFg)->p);
p.drawText(_uploadPhoto.x() + st::setStatusLeft, top + st::setStatusTop + st::setStatusFont->ascent, lang(connecting ? lng_status_connecting : lng_status_online));
top += st::setPhotoSize;
if (!_errorText.isEmpty()) {
p.setFont(st::setErrFont->f);
p.setPen(st::setErrColor->p);
p.drawText(QRect(_uploadPhoto.x(), _uploadPhoto.y() + _uploadPhoto.height() + st::setLittleSkip, _uploadPhoto.width(), st::setErrFont->height), _errorText, style::al_center);
}
// contact info
p.setFont(st::setHeaderFont->f);
p.setPen(st::setHeaderColor->p);
p.drawText(_left + st::setHeaderLeft, top + st::setHeaderTop + st::setHeaderFont->ascent, lang(lng_settings_section_contact_info));
top += st::setHeaderSkip;
p.setFont(st::linkFont->f);
p.setPen(st::black->p);
p.drawText(_left, top + st::linkFont->ascent, lang(lng_settings_phone_number));
p.drawText(_left + st::setContactInfoLeft, top + st::linkFont->ascent, _phoneText);
top += st::linkFont->height + st::setLittleSkip;
p.drawText(_left, top + st::linkFont->ascent, lang(lng_settings_username));
top += st::linkFont->height;
// notifications
p.setFont(st::setHeaderFont->f);
p.setPen(st::setHeaderColor->p);
p.drawText(_left + st::setHeaderLeft, top + st::setHeaderTop + st::setHeaderFont->ascent, lang(lng_settings_section_notify));
top += st::setHeaderSkip;
top += _desktopNotify.height() + st::setLittleSkip;
top += _senderName.height() + st::setLittleSkip;
top += _messagePreview.height() + st::setSectionSkip;
if (App::wnd()->psHasNativeNotifications() && cPlatform() == dbipWindows) {
top += _windowsNotifications.height() + st::setSectionSkip;
}
top += _soundNotify.height() + st::setSectionSkip;
top += _includeMuted.height();
}
// general
p.setFont(st::setHeaderFont->f);
p.setPen(st::setHeaderColor->p);
p.drawText(_left + st::setHeaderLeft, top + st::setHeaderTop + st::setHeaderFont->ascent, lang(lng_settings_section_general));
top += st::setHeaderSkip;
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
top += _autoUpdate.height();
QString textToDraw;
if (cAutoUpdate()) {
switch (_updatingState) {
case UpdatingNone: textToDraw = _curVersionText; break;
case UpdatingCheck: textToDraw = lang(lng_settings_update_checking); break;
case UpdatingLatest: textToDraw = lang(lng_settings_latest_installed); break;
case UpdatingDownload: textToDraw = _newVersionDownload; break;
case UpdatingReady: textToDraw = _newVersionText; break;
case UpdatingFail: textToDraw = lang(lng_settings_update_fail); break;
}
} else {
textToDraw = _curVersionText;
}
p.setFont(st::linkFont);
p.setPen(st::setVersionColor);
p.drawText(_left + st::setVersionLeft, top + st::setVersionTop + st::linkFont->ascent, textToDraw);
top += st::setVersionHeight;
#endif
if (cPlatform() == dbipWindows) {
top += _workmodeTray.height() + st::setLittleSkip;
top += _workmodeWindow.height() + st::setSectionSkip;
top += _autoStart.height() + st::setLittleSkip;
top += _startMinimized.height() + st::setSectionSkip;
top += _sendToMenu.height();
} else if (_supportTray) {
top += _workmodeTray.height();
}
if (!cRetina()) {
p.setFont(st::setHeaderFont->f);
p.setPen(st::setHeaderColor->p);
p.drawText(_left + st::setHeaderLeft, top + st::setHeaderTop + st::setHeaderFont->ascent, lang(lng_settings_scale_label));
top += st::setHeaderSkip;
top += _dpiAutoScale.height() + st::setLittleSkip;
top += _dpiSlider.height() + st::dpiFont4->height;
int32 sLeft = _dpiSlider.x() + _dpiWidth1 / 2, sWidth = _dpiSlider.width();
float64 sStep = (sWidth - _dpiWidth1 / 2 - _dpiWidth4 / 2) / float64(dbisScaleCount - 2);
p.setFont(st::dpiFont1->f);
p.setPen((scaleIs(dbisOne) ? st::dpiActive : st::dpiInactive)->p);
p.drawText(sLeft + qRound(0 * sStep) - _dpiWidth1 / 2, top - (st::dpiFont4->height - st::dpiFont1->height) / 2 - st::dpiFont1->descent, scaleLabel(dbisOne));
p.setFont(st::dpiFont2->f);
p.setPen((scaleIs(dbisOneAndQuarter) ? st::dpiActive : st::dpiInactive)->p);
p.drawText(sLeft + qRound(1 * sStep) - _dpiWidth2 / 2, top - (st::dpiFont4->height - st::dpiFont2->height) / 2 - st::dpiFont2->descent, scaleLabel(dbisOneAndQuarter));
p.setFont(st::dpiFont3->f);
p.setPen((scaleIs(dbisOneAndHalf) ? st::dpiActive : st::dpiInactive)->p);
p.drawText(sLeft + qRound(2 * sStep) - _dpiWidth3 / 2, top - (st::dpiFont4->height - st::dpiFont3->height) / 2 - st::dpiFont3->descent, scaleLabel(dbisOneAndHalf));
p.setFont(st::dpiFont4->f);
p.setPen((scaleIs(dbisTwo) ? st::dpiActive : st::dpiInactive)->p);
p.drawText(sLeft + qRound(3 * sStep) - _dpiWidth4 / 2, top - (st::dpiFont4->height - st::dpiFont4->height) / 2 - st::dpiFont4->descent, scaleLabel(dbisTwo));
p.setFont(st::linkFont->f);
}
if (self()) {
// chat options
p.setFont(st::setHeaderFont->f);
p.setPen(st::setHeaderColor->p);
p.drawText(_left + st::setHeaderLeft, top + st::setHeaderTop + st::setHeaderFont->ascent, lang(lng_settings_section_chat));
top += st::setHeaderSkip;
top += _replaceEmojis.height() + st::setLittleSkip;
top += _stickers.height() + st::setSectionSkip;
top += _enterSend.height() + st::setLittleSkip;
top += _ctrlEnterSend.height() + st::setSectionSkip;
top += _dontAskDownloadPath.height();
if (!cAskDownloadPath()) {
top += st::setLittleSkip;
p.setFont(st::linkFont->f);
p.setPen(st::black->p);
p.drawText(_left + st::cbDefFlat.textLeft, top + st::linkFont->ascent, lang(lng_download_path_label));
if (cDownloadPath() == qsl("tmp")) {
QString clearText;
int32 clearWidth = 0;
switch (_tempDirClearState) {
case TempDirClearing: clearText = lang(lng_download_path_clearing); clearWidth = _tempDirClearingWidth; break;
case TempDirCleared: clearText = lang(lng_download_path_cleared); clearWidth = _tempDirClearedWidth; break;
case TempDirClearFailed: clearText = lang(lng_download_path_clear_failed); clearWidth = _tempDirClearFailedWidth; break;
}
if (clearWidth) {
p.drawText(_left + st::setWidth - clearWidth, top + st::linkFont->ascent, clearText);
}
}
top += _downloadPathEdit.height();
}
top += st::setLittleSkip;
top += _autoDownload.height();
// local storage
p.setFont(st::setHeaderFont->f);
p.setPen(st::setHeaderColor->p);
p.drawText(_left + st::setHeaderLeft, top + st::setHeaderTop + st::setHeaderFont->ascent, lang(lng_settings_section_cache));
p.setFont(st::linkFont->f);
p.setPen(st::black->p);
QString clearText;
int32 clearWidth = 0;
switch (_storageClearState) {
case TempDirClearing: clearText = lang(lng_local_storage_clearing); clearWidth = _storageClearingWidth; break;
case TempDirCleared: clearText = lang(lng_local_storage_cleared); clearWidth = _storageClearedWidth; break;
case TempDirClearFailed: clearText = lang(lng_local_storage_clear_failed); clearWidth = _storageClearFailedWidth; break;
}
if (clearWidth) {
p.drawText(_left + st::setWidth - clearWidth, top + st::setHeaderTop + st::setHeaderFont->ascent, clearText);
}
top += st::setHeaderSkip;
int32 cntImages = Local::hasImages() + Local::hasStickers() + Local::hasWebFiles(), cntAudios = Local::hasAudios();
if (cntImages > 0 && cntAudios > 0) {
if (_localStorageHeight != 2) {
cntAudios = 0;
QTimer::singleShot(0, this, SLOT(onUpdateLocalStorage()));
}
} else {
if (_localStorageHeight != 1) {
QTimer::singleShot(0, this, SLOT(onUpdateLocalStorage()));
}
}
if (cntImages > 0) {
QString cnt = lng_settings_images_cached(lt_count, cntImages, lt_size, formatSizeText(Local::storageImagesSize() + Local::storageStickersSize() + Local::storageWebFilesSize()));
p.drawText(_left + st::setHeaderLeft, top + st::linkFont->ascent, cnt);
}
if (_localStorageHeight == 2) top += _localStorageClear.height() + st::setLittleSkip;
if (cntAudios > 0) {
QString cnt = lng_settings_audios_cached(lt_count, cntAudios, lt_size, formatSizeText(Local::storageAudiosSize()));
p.drawText(_left + st::setHeaderLeft, top + st::linkFont->ascent, cnt);
} else if (cntImages <= 0) {
p.drawText(_left + st::setHeaderLeft, top + st::linkFont->ascent, lang(lng_settings_no_data_cached));
}
top += _localStorageClear.height();
// chat background
p.setFont(st::setHeaderFont->f);
p.setPen(st::setHeaderColor->p);
p.drawText(_left + st::setHeaderLeft, top + st::setHeaderTop + st::setHeaderFont->ascent, lang(lng_settings_section_background));
top += st::setHeaderSkip;
if (animateBackground) {
const QPixmap &pix = App::main()->newBackgroundThumb()->pixBlurred(st::setBackgroundSize);
p.drawPixmap(_left, top, st::setBackgroundSize, st::setBackgroundSize, pix, 0, (pix.height() - st::setBackgroundSize) / 2, st::setBackgroundSize, st::setBackgroundSize);
uint64 dt = getms();
int32 cnt = int32(st::photoLoaderCnt), period = int32(st::photoLoaderPeriod), t = dt % period, delta = int32(st::photoLoaderDelta);
int32 x = _left + (st::setBackgroundSize - st::mediaviewLoader.width()) / 2;
int32 y = top + (st::setBackgroundSize - st::mediaviewLoader.height()) / 2;
p.fillRect(x, y, st::mediaviewLoader.width(), st::mediaviewLoader.height(), st::photoLoaderBg->b);
x += (st::mediaviewLoader.width() - cnt * st::mediaviewLoaderPoint.width() - (cnt - 1) * st::mediaviewLoaderSkip) / 2;
y += (st::mediaviewLoader.height() - st::mediaviewLoaderPoint.height()) / 2;
QColor c(st::white->c);
QBrush b(c);
for (int32 i = 0; i < cnt; ++i) {
t -= delta;
while (t < 0) t += period;
float64 alpha = (t >= st::photoLoaderDuration1 + st::photoLoaderDuration2) ? 0 : ((t > st::photoLoaderDuration1 ? ((st::photoLoaderDuration1 + st::photoLoaderDuration2 - t) / st::photoLoaderDuration2) : (t / st::photoLoaderDuration1)));
c.setAlphaF(st::photoLoaderAlphaMin + alpha * (1 - st::photoLoaderAlphaMin));
b.setColor(c);
p.fillRect(x + i * (st::mediaviewLoaderPoint.width() + st::mediaviewLoaderSkip), y, st::mediaviewLoaderPoint.width(), st::mediaviewLoaderPoint.height(), b);
}
QTimer::singleShot(AnimationTimerDelta, this, SLOT(updateBackgroundRect()));
} else {
p.drawPixmap(_left, top, _background);
}
top += st::setBackgroundSize;
top += st::setLittleSkip;
top += _tileBackground.height();
if (Global::AdaptiveLayout() == Adaptive::WideLayout) {
top += st::setLittleSkip;
top += _adaptiveForWide.height();
}
}
// advanced
p.setFont(st::setHeaderFont->f);
p.setPen(st::setHeaderColor->p);
p.drawText(_left + st::setHeaderLeft, top + st::setHeaderTop + st::setHeaderFont->ascent, lang(lng_settings_section_advanced));
top += st::setHeaderSkip;
p.setFont(st::linkFont->f);
p.setPen(st::black->p);
if (self()) {
top += _passcodeEdit.height() + st::setLittleSkip;
if (cHasPasscode()) {
p.drawText(_left, top + st::linkFont->ascent, _autoLockText);
top += _autoLock.height() + st::setLittleSkip;
}
if (!_waitingConfirm.isEmpty()) p.drawText(_left, top + st::linkFont->ascent, _waitingConfirm);
top += _passwordEdit.height() + st::setLittleSkip;
}
p.drawText(_left, _connectionType.y() + st::linkFont->ascent, _connectionTypeText);
}
void SettingsInner::resizeEvent(QResizeEvent *e) {
_left = (width() - st::setWidth) / 2;
int32 top = 0;
if (self()) {
// profile
top += st::setTop;
top += st::setPhotoSize;
_uploadPhoto.move(_left + st::setWidth - _uploadPhoto.width(), top - _uploadPhoto.height());
_cancelPhoto.move(_left + st::setWidth - _cancelPhoto.width(), top - _uploadPhoto.height() + st::btnSetUpload.textTop + st::btnSetUpload.font->ascent - st::linkFont->ascent);
// contact info
top += st::setHeaderSkip;
top += st::linkFont->height + st::setLittleSkip;
_chooseUsername.move(_left + st::setContactInfoLeft, top); top += st::linkFont->height;
// notifications
top += st::setHeaderSkip;
_desktopNotify.move(_left, top); top += _desktopNotify.height() + st::setLittleSkip;
_senderName.move(_left, top); top += _senderName.height() + st::setLittleSkip;
_messagePreview.move(_left, top); top += _messagePreview.height() + st::setSectionSkip;
if (App::wnd()->psHasNativeNotifications() && cPlatform() == dbipWindows) {
_windowsNotifications.move(_left, top); top += _windowsNotifications.height() + st::setSectionSkip;
}
_soundNotify.move(_left, top); top += _soundNotify.height() + st::setSectionSkip;
_includeMuted.move(_left, top); top += _includeMuted.height();
}
// general
top += st::setHeaderSkip;
_changeLanguage.move(_left + st::setWidth - _changeLanguage.width(), top - st::setHeaderSkip + st::setHeaderTop + st::setHeaderFont->ascent - st::linkFont->ascent);
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
_autoUpdate.move(_left, top);
_checkNow.move(_left + st::setWidth - _checkNow.width(), top + st::cbDefFlat.textTop); top += _autoUpdate.height();
_restartNow.move(_left + st::setWidth - _restartNow.width(), top + st::setVersionTop);
top += st::setVersionHeight;
#endif
if (cPlatform() == dbipWindows) {
_workmodeTray.move(_left, top); top += _workmodeTray.height() + st::setLittleSkip;
_workmodeWindow.move(_left, top); top += _workmodeWindow.height() + st::setSectionSkip;
_autoStart.move(_left, top); top += _autoStart.height() + st::setLittleSkip;
_startMinimized.move(_left, top); top += _startMinimized.height() + st::setSectionSkip;
_sendToMenu.move(_left, top); top += _sendToMenu.height();
} else if (_supportTray) {
_workmodeTray.move(_left, top); top += _workmodeTray.height();
}
if (!cRetina()) {
top += st::setHeaderSkip;
_dpiAutoScale.move(_left, top); top += _dpiAutoScale.height() + st::setLittleSkip;
_dpiSlider.move(_left, top); top += _dpiSlider.height() + st::dpiFont4->height;
}
// chat options
if (self()) {
top += st::setHeaderSkip;
_viewEmojis.move(_left + st::setWidth - _viewEmojis.width(), top + st::cbDefFlat.textTop);
_replaceEmojis.move(_left, top); top += _replaceEmojis.height() + st::setLittleSkip;
_stickers.move(_left + st::cbDefFlat.textLeft, top); top += _stickers.height() + st::setSectionSkip;
_enterSend.move(_left, top); top += _enterSend.height() + st::setLittleSkip;
_ctrlEnterSend.move(_left, top); top += _ctrlEnterSend.height() + st::setSectionSkip;
_dontAskDownloadPath.move(_left, top); top += _dontAskDownloadPath.height();
if (!cAskDownloadPath()) {
top += st::setLittleSkip;
_downloadPathEdit.move(_left + st::cbDefFlat.textLeft + _downloadPathWidth, top);
if (cDownloadPath() == qsl("tmp")) {
_downloadPathClear.move(_left + st::setWidth - _downloadPathClear.width(), top);
}
top += _downloadPathEdit.height();
}
top += st::setLittleSkip;
_autoDownload.move(_left + st::cbDefFlat.textLeft, top); top += _autoDownload.height();
// local storage
_localStorageClear.move(_left + st::setWidth - _localStorageClear.width(), top + st::setHeaderTop + st::setHeaderFont->ascent - st::linkFont->ascent);
top += st::setHeaderSkip;
if ((Local::hasImages() || Local::hasStickers() || Local::hasWebFiles()) && Local::hasAudios()) {
_localStorageHeight = 2;
top += _localStorageClear.height() + st::setLittleSkip;
} else {
_localStorageHeight = 1;
}
top += _localStorageClear.height();
// chat background
top += st::setHeaderSkip;
_backFromGallery.move(_left + st::setBackgroundSize + st::setLittleSkip, top);
_backFromFile.move(_left + st::setBackgroundSize + st::setLittleSkip, top + _backFromGallery.height() + st::setLittleSkip);
top += st::setBackgroundSize;
top += st::setLittleSkip;
_tileBackground.move(_left, top); top += _tileBackground.height();
if (Global::AdaptiveLayout() == Adaptive::WideLayout) {
top += st::setLittleSkip;
_adaptiveForWide.move(_left, top); top += _adaptiveForWide.height();
}
}
// advanced
top += st::setHeaderSkip;
if (self()) {
_passcodeEdit.move(_left, top);
_passcodeTurnOff.move(_left + st::setWidth - _passcodeTurnOff.width(), top); top += _passcodeTurnOff.height() + st::setLittleSkip;
if (cHasPasscode()) {
_autoLock.move(_left + _autoLockWidth, top); top += _autoLock.height() + st::setLittleSkip;
}
_passwordEdit.move(_left, top);
_passwordTurnOff.move(_left + st::setWidth - _passwordTurnOff.width(), top); top += _passwordTurnOff.height() + st::setLittleSkip;
}
_connectionType.move(_left + _connectionTypeWidth, top); top += _connectionType.height() + st::setLittleSkip;
if (self()) {
_showSessions.move(_left, top); top += _showSessions.height() + st::setSectionSkip;
_askQuestion.move(_left, top); top += _askQuestion.height() + st::setLittleSkip;
_telegramFAQ.move(_left, top); top += _telegramFAQ.height() + st::setSectionSkip;
_logOut.move(_left, top);
} else {
top += st::setSectionSkip - st::setLittleSkip;
_telegramFAQ.move(_left, top);
}
}
void SettingsInner::keyPressEvent(QKeyEvent *e) {
if (e->key() == Qt::Key_Escape || e->key() == Qt::Key_Back) {
App::wnd()->showSettings();
}
_secretText += e->text().toLower();
int32 size = _secretText.size(), from = 0;
while (size > from) {
QStringRef str(_secretText.midRef(from));
if (str == qstr("debugmode")) {
QString text = cDebug() ? qsl("Do you want to disable DEBUG logs?") : qsl("Do you want to enable DEBUG logs?\n\nAll network events will be logged.");
ConfirmBox *box = new ConfirmBox(text);
connect(box, SIGNAL(confirmed()), App::app(), SLOT(onSwitchDebugMode()));
Ui::showLayer(box);
from = size;
break;
} else if (str == qstr("testmode")) {
QString text = cTestMode() ? qsl("Do you want to disable TEST mode?") : qsl("Do you want to enable TEST mode?\n\nYou will be switched to test cloud.");
ConfirmBox *box = new ConfirmBox(text);
connect(box, SIGNAL(confirmed()), App::app(), SLOT(onSwitchTestMode()));
Ui::showLayer(box);
from = size;
break;
} else if (str == qstr("loadlang")) {
chooseCustomLang();
} else if (str == qstr("debugfiles") && cDebug()) {
if (DebugLogging::FileLoader()) {
Global::RefDebugLoggingFlags() &= ~DebugLogging::FileLoaderFlag;
} else {
Global::RefDebugLoggingFlags() |= DebugLogging::FileLoaderFlag;
}
Ui::showLayer(new InformBox(DebugLogging::FileLoader() ? qsl("Enabled file download logging") : qsl("Disabled file download logging")));
} else if (str == qstr("crashplease")) {
t_assert(!"Crashed in Settings!");
} else if (str == qstr("workmode")) {
QString text = Global::DialogsModeEnabled() ? qsl("Disable work mode?") : qsl("Enable work mode?");
auto box = std_::make_unique<ConfirmBox>(text);
connect(box.get(), SIGNAL(confirmed()), App::app(), SLOT(onSwitchWorkMode()));
Ui::showLayer(box.release());
from = size;
break;
} else if (
qsl("debugmode").startsWith(str) ||
qsl("testmode").startsWith(str) ||
qsl("loadlang").startsWith(str) ||
qsl("debugfiles").startsWith(str) ||
qsl("workmode").startsWith(str) ||
qsl("crashplease").startsWith(str)) {
break;
}
++from;
}
_secretText = (size > from) ? _secretText.mid(from) : QString();
}
void SettingsInner::mouseMoveEvent(QMouseEvent *e) {
if (!self()) {
setCursor(style::cur_default);
} else {
bool nameOver = QRect(_uploadPhoto.x() + st::setNameLeft, st::setTop + st::setNameTop, qMin(_uploadPhoto.width() - int(st::setNameLeft), _nameText.maxWidth()), st::setNameFont->height).contains(e->pos());
if (nameOver != _nameOver) {
_nameOver = nameOver;
}
bool photoOver = QRect(_left, st::setTop, st::setPhotoSize, st::setPhotoSize).contains(e->pos());
if (photoOver != _photoOver) {
_photoOver = photoOver;
if (!_photoLink) {
a_photoOver.start(_photoOver ? 1 : 0);
_a_photo.start();
}
}
setCursor((_nameOver || _photoOver) ? style::cur_pointer : style::cur_default);
}
}
void SettingsInner::mousePressEvent(QMouseEvent *e) {
mouseMoveEvent(e);
if (!self()) {
return;
}
if (QRect(_uploadPhoto.x() + st::setNameLeft, st::setTop + st::setNameTop, qMin(_uploadPhoto.width() - int(st::setNameLeft), _nameText.maxWidth()), st::setNameFont->height).contains(e->pos())) {
Ui::showLayer(new EditNameTitleBox(self()));
} else if (QRect(_left, st::setTop, st::setPhotoSize, st::setPhotoSize).contains(e->pos())) {
if (_photoLink) {
App::photo(self()->photoId)->download();
_photoLink->onClick(e->button());
} else {
onUpdatePhoto();
}
}
}
void SettingsInner::contextMenuEvent(QContextMenuEvent *e) {
}
void SettingsInner::updateAdaptiveLayout() {
showAll();
resizeEvent(0);
}
void SettingsInner::step_photo(float64 ms, bool timer) {
float64 dt = ms / st::setPhotoDuration;
if (dt >= 1) {
_a_photo.stop();
a_photoOver.finish();
} else {
a_photoOver.update(dt, anim::linear);
}
if (timer) update(_left, st::setTop, st::setPhotoSize, st::setPhotoSize);
}
void SettingsInner::updateSize(int32 newWidth) {
if (_logOut.isHidden()) {
resize(newWidth, _telegramFAQ.geometry().bottom() + st::setBottom);
} else {
resize(newWidth, _logOut.geometry().bottom() + st::setBottom);
}
}
void SettingsInner::updateOnlineDisplay() {
}
void SettingsInner::updateConnectionType() {
QString connection;
switch (cConnectionType()) {
case dbictAuto: {
QString transport = MTP::dctransport();
connection = transport.isEmpty() ? lang(lng_connection_auto_connecting) : lng_connection_auto(lt_transport, transport);
} break;
case dbictHttpProxy:
case dbictTcpProxy: {
QString transport = MTP::dctransport();
connection = transport.isEmpty() ? lang(lng_connection_proxy_connecting) : lng_connection_proxy(lt_transport, transport);
} break;
}
_connectionType.setText(connection);
}
void SettingsInner::passcodeChanged() {
resizeEvent(0);
_passcodeEdit.setText(lang(cHasPasscode() ? lng_passcode_change : lng_passcode_turn_on));
_autoLock.setText((cAutoLock() % 3600) ? lng_passcode_autolock_minutes(lt_count, cAutoLock() / 60) : lng_passcode_autolock_hours(lt_count, cAutoLock() / 3600));
// _passwordEdit.setText()
showAll();
}
void SettingsInner::updateBackgroundRect() {
update(_left, _tileBackground.y() - st::setLittleSkip - st::setBackgroundSize, st::setBackgroundSize, st::setBackgroundSize);
}
void SettingsInner::onFullPeerUpdated(PeerData *peer) {
if (!self() || self() != peer) return;
PhotoData *selfPhoto = (self()->photoId && self()->photoId != UnknownPeerPhotoId) ? App::photo(self()->photoId) : 0;
if (selfPhoto && selfPhoto->date) {
_photoLink.reset(new PhotoOpenClickHandler(selfPhoto, self()));
} else {
_photoLink.clear();
}
}
void SettingsInner::gotPassword(const MTPaccount_Password &result) {
_waitingConfirm = QString();
switch (result.type()) {
case mtpc_account_noPassword: {
const auto &d(result.c_account_noPassword());
_curPasswordSalt = QByteArray();
_hasPasswordRecovery = false;
_curPasswordHint = QString();
_newPasswordSalt = qba(d.vnew_salt);
QString pattern = qs(d.vemail_unconfirmed_pattern);
if (!pattern.isEmpty()) _waitingConfirm = lng_cloud_password_waiting(lt_email, pattern);
} break;
case mtpc_account_password: {
const auto &d(result.c_account_password());
_curPasswordSalt = qba(d.vcurrent_salt);
_hasPasswordRecovery = mtpIsTrue(d.vhas_recovery);
_curPasswordHint = qs(d.vhint);
_newPasswordSalt = qba(d.vnew_salt);
QString pattern = qs(d.vemail_unconfirmed_pattern);
if (!pattern.isEmpty()) _waitingConfirm = lng_cloud_password_waiting(lt_email, pattern);
} break;
}
_waitingConfirm = st::linkFont->elided(_waitingConfirm, st::setWidth - _passwordTurnOff.width());
_passwordEdit.setText(lang(_curPasswordSalt.isEmpty() ? lng_cloud_password_set : lng_cloud_password_edit));
showAll();
update();
_newPasswordSalt.resize(_newPasswordSalt.size() + 8);
memset_rand(_newPasswordSalt.data() + _newPasswordSalt.size() - 8, 8);
}
void SettingsInner::offPasswordDone(const MTPBool &result) {
onReloadPassword();
}
bool SettingsInner::offPasswordFail(const RPCError &error) {
if (MTP::isDefaultHandledError(error)) return false;
onReloadPassword();
return true;
}
void SettingsInner::usernameChanged() {
_chooseUsername.setText((self() && !self()->username.isEmpty()) ? ('@' + self()->username) : lang(lng_settings_choose_username));
showAll();
update();
}
void SettingsInner::showAll() {
// profile
if (self()) {
if (App::app()->isPhotoUpdating(self()->id)) {
_cancelPhoto.show();
_uploadPhoto.hide();
} else {
_cancelPhoto.hide();
_uploadPhoto.show();
}
} else {
_uploadPhoto.hide();
_cancelPhoto.hide();
}
// contact info
if (self()) {
_chooseUsername.show();
} else {
_chooseUsername.hide();
}
// notifications
if (self()) {
_desktopNotify.show();
_senderName.show();
_messagePreview.show();
if (App::wnd()->psHasNativeNotifications() && cPlatform() == dbipWindows) {
_windowsNotifications.show();
} else {
_windowsNotifications.hide();
}
_soundNotify.show();
_includeMuted.show();
} else {
_desktopNotify.hide();
_senderName.hide();
_messagePreview.hide();
_windowsNotifications.hide();
_soundNotify.hide();
_includeMuted.hide();
}
// general
_changeLanguage.show();
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
_autoUpdate.show();
setUpdatingState(_updatingState, true);
#endif
if (cPlatform() == dbipWindows) {
_workmodeTray.show();
_workmodeWindow.show();
_autoStart.show();
_startMinimized.show();
_sendToMenu.show();
} else {
if (_supportTray) {
_workmodeTray.show();
} else {
_workmodeTray.hide();
}
_workmodeWindow.hide();
_autoStart.hide();
_startMinimized.hide();
_sendToMenu.hide();
}
if (cRetina()) {
_dpiSlider.hide();
_dpiAutoScale.hide();
} else {
_dpiSlider.show();
_dpiAutoScale.show();
}
// chat options
if (self()) {
_replaceEmojis.show();
if (cReplaceEmojis()) {
_viewEmojis.show();
} else {
_viewEmojis.hide();
}
_stickers.show();
_enterSend.show();
_ctrlEnterSend.show();
_dontAskDownloadPath.show();
if (cAskDownloadPath()) {
_downloadPathEdit.hide();
_downloadPathClear.hide();
} else {
_downloadPathEdit.show();
if (cDownloadPath() == qsl("tmp") && _tempDirClearState == TempDirExists) { // dir exists, not clearing right now
_downloadPathClear.show();
} else {
_downloadPathClear.hide();
}
}
_autoDownload.show();
} else {
_replaceEmojis.hide();
_viewEmojis.hide();
_stickers.hide();
_enterSend.hide();
_ctrlEnterSend.hide();
_dontAskDownloadPath.hide();
_downloadPathEdit.hide();
_downloadPathClear.hide();
_autoDownload.hide();
}
// local storage
if (self() && _storageClearState == TempDirExists) {
_localStorageClear.show();
} else {
_localStorageClear.hide();
}
// chat background
if (self()) {
_backFromGallery.show();
_backFromFile.show();
_tileBackground.show();
if (Global::AdaptiveLayout() == Adaptive::WideLayout) {
_adaptiveForWide.show();
} else {
_adaptiveForWide.hide();
}
} else {
_backFromGallery.hide();
_backFromFile.hide();
_tileBackground.hide();
_adaptiveForWide.hide();
}
// advanced
if (self()) {
_passcodeEdit.show();
if (cHasPasscode()) {
_autoLock.show();
_passcodeTurnOff.show();
} else {
_autoLock.hide();
_passcodeTurnOff.hide();
}
if (_waitingConfirm.isEmpty()) {
_passwordEdit.show();
} else {
_passwordEdit.hide();
}
if (_curPasswordSalt.isEmpty() && _waitingConfirm.isEmpty()) {
_passwordTurnOff.hide();
} else {
_passwordTurnOff.show();
}
_showSessions.show();
_askQuestion.show();
_logOut.show();
} else {
_passcodeEdit.hide();
_autoLock.hide();
_passcodeTurnOff.hide();
_passwordEdit.hide();
_passwordTurnOff.hide();
_showSessions.hide();
_askQuestion.hide();
_logOut.hide();
}
_telegramFAQ.show();
}
void SettingsInner::saveError(const QString &str) {
_errorText = str;
resizeEvent(0);
update();
}
void SettingsInner::supportGot(const MTPhelp_Support &support) {
if (!App::main()) return;
if (support.type() == mtpc_help_support) {
const auto &d(support.c_help_support());
UserData *u = App::feedUsers(MTP_vector<MTPUser>(1, d.vuser));
Ui::showPeerHistory(u, ShowAtUnreadMsgId);
App::wnd()->hideSettings();
}
}
void SettingsInner::onUpdatePhotoCancel() {
if (self()) {
App::app()->cancelPhotoUpdate(self()->id);
}
showAll();
update();
}
void SettingsInner::onUpdatePhoto() {
if (!self()) {
return;
}
saveError();
QStringList imgExtensions(cImgExtensions());
QString filter(qsl("Image files (*") + imgExtensions.join(qsl(" *")) + qsl(");;All files (*.*)"));
QImage img;
QString file;
QByteArray remoteContent;
if (filedialogGetOpenFile(file, remoteContent, lang(lng_choose_images), filter)) {
if (!remoteContent.isEmpty()) {
img = App::readImage(remoteContent);
} else {
if (!file.isEmpty()) {
img = App::readImage(file);
}
}
} else {
return;
}
if (img.isNull() || img.width() > 10 * img.height() || img.height() > 10 * img.width()) {
saveError(lang(lng_bad_photo));
return;
}
PhotoCropBox *box = new PhotoCropBox(img, self());
connect(box, SIGNAL(closed()), this, SLOT(onPhotoUpdateStart()));
Ui::showLayer(box);
}
void SettingsInner::onShowSessions() {
SessionsBox *box = new SessionsBox();
Ui::showLayer(box);
}
void SettingsInner::onAskQuestion() {
if (!App::self()) return;
ConfirmBox *box = new ConfirmBox(lang(lng_settings_ask_sure), lang(lng_settings_ask_ok), st::defaultBoxButton, lang(lng_settings_faq_button));
connect(box, SIGNAL(confirmed()), this, SLOT(onAskQuestionSure()));
connect(box, SIGNAL(cancelPressed()), this, SLOT(onTelegramFAQ()));
Ui::showLayer(box);
}
void SettingsInner::onAskQuestionSure() {
if (_supportGetRequest) return;
_supportGetRequest = MTP::send(MTPhelp_GetSupport(), rpcDone(&SettingsInner::supportGot));
}
void SettingsInner::onTelegramFAQ() {
QDesktopServices::openUrl(telegramFaqLink());
}
void SettingsInner::chooseCustomLang() {
QString file;
QByteArray arr;
if (filedialogGetOpenFile(file, arr, qsl("Choose language .strings file"), qsl("Language files (*.strings)"))) {
_testlang = QFileInfo(file).absoluteFilePath();
LangLoaderPlain loader(_testlang, LangLoaderRequest(lng_sure_save_language, lng_cancel, lng_box_ok));
if (loader.errors().isEmpty()) {
LangLoaderResult result = loader.found();
QString text = result.value(lng_sure_save_language, langOriginal(lng_sure_save_language)),
save = result.value(lng_box_ok, langOriginal(lng_box_ok)),
cancel = result.value(lng_cancel, langOriginal(lng_cancel));
ConfirmBox *box = new ConfirmBox(text, save, st::defaultBoxButton, cancel);
connect(box, SIGNAL(confirmed()), this, SLOT(onSaveTestLang()));
Ui::showLayer(box);
} else {
Ui::showLayer(new InformBox("Custom lang failed :(\n\nError: " + loader.errors()));
}
}
}
void SettingsInner::onChangeLanguage() {
if ((_changeLanguage.clickModifiers() & Qt::ShiftModifier) && (_changeLanguage.clickModifiers() & Qt::AltModifier)) {
chooseCustomLang();
} else {
Ui::showLayer(new LanguageBox());
}
}
void SettingsInner::onSaveTestLang() {
cSetLangFile(_testlang);
cSetLang(languageTest);
Local::writeSettings();
cSetRestarting(true);
App::quit();
}
void SettingsInner::onUpdateLocalStorage() {
resizeEvent(0);
updateSize(width());
update();
}
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
void SettingsInner::onAutoUpdate() {
cSetAutoUpdate(!cAutoUpdate());
Local::writeSettings();
resizeEvent(0);
if (cAutoUpdate()) {
Sandbox::startUpdateCheck();
if (_updatingState == UpdatingNone) {
_checkNow.show();
} else if (_updatingState == UpdatingReady) {
_restartNow.show();
}
} else {
Sandbox::stopUpdate();
_restartNow.hide();
_checkNow.hide();
}
update();
}
void SettingsInner::onCheckNow() {
if (!cAutoUpdate()) return;
cSetLastUpdateCheck(0);
Sandbox::startUpdateCheck();
}
#endif
void SettingsInner::onRestartNow() {
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
checkReadyUpdate();
if (_updatingState == UpdatingReady) {
cSetRestartingUpdate(true);
} else {
cSetRestarting(true);
cSetRestartingToSettings(true);
}
#else
cSetRestarting(true);
cSetRestartingToSettings(true);
#endif
App::quit();
}
void SettingsInner::onPasscode() {
PasscodeBox *box = new PasscodeBox();
connect(box, SIGNAL(closed()), this, SLOT(passcodeChanged()));
Ui::showLayer(box);
}
void SettingsInner::onPasscodeOff() {
PasscodeBox *box = new PasscodeBox(true);
connect(box, SIGNAL(closed()), this, SLOT(passcodeChanged()));
Ui::showLayer(box);
}
void SettingsInner::onPassword() {
PasscodeBox *box = new PasscodeBox(_newPasswordSalt, _curPasswordSalt, _hasPasswordRecovery, _curPasswordHint);
connect(box, SIGNAL(reloadPassword()), this, SLOT(onReloadPassword()));
Ui::showLayer(box);
}
void SettingsInner::onPasswordOff() {
if (_curPasswordSalt.isEmpty()) {
_passwordTurnOff.hide();
// int32 flags = MTPDaccount_passwordInputSettings::flag_new_salt | MTPDaccount_passwordInputSettings::flag_new_password_hash | MTPDaccount_passwordInputSettings::flag_hint | MTPDaccount_passwordInputSettings::flag_email;
MTPDaccount_passwordInputSettings::Flags flags = MTPDaccount_passwordInputSettings::Flag::f_email;
MTPaccount_PasswordInputSettings settings(MTP_account_passwordInputSettings(MTP_flags(flags), MTP_bytes(QByteArray()), MTP_bytes(QByteArray()), MTP_string(QString()), MTP_string(QString())));
MTP::send(MTPaccount_UpdatePasswordSettings(MTP_bytes(QByteArray()), settings), rpcDone(&SettingsInner::offPasswordDone), rpcFail(&SettingsInner::offPasswordFail));
} else {
PasscodeBox *box = new PasscodeBox(_newPasswordSalt, _curPasswordSalt, _hasPasswordRecovery, _curPasswordHint, true);
connect(box, SIGNAL(reloadPassword()), this, SLOT(onReloadPassword()));
Ui::showLayer(box);
}
}
void SettingsInner::onReloadPassword(Qt::ApplicationState state) {
if (state == Qt::ApplicationActive) {
MTP::send(MTPaccount_GetPassword(), rpcDone(&SettingsInner::gotPassword));
}
}
void SettingsInner::onAutoLock() {
AutoLockBox *box = new AutoLockBox();
connect(box, SIGNAL(closed()), this, SLOT(passcodeChanged()));
Ui::showLayer(box);
}
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
void SettingsInner::onConnectionType() {
ConnectionBox *box = new ConnectionBox();
connect(box, SIGNAL(closed()), this, SLOT(updateConnectionType()), Qt::QueuedConnection);
Ui::showLayer(box);
}
#endif
void SettingsInner::onUsername() {
UsernameBox *box = new UsernameBox();
connect(box, SIGNAL(closed()), this, SLOT(usernameChanged()));
Ui::showLayer(box);
}
void SettingsInner::onWorkmodeTray() {
if ((!_workmodeTray.checked() || cPlatform() != dbipWindows) && !_workmodeWindow.checked()) {
_workmodeWindow.setChecked(true);
}
DBIWorkMode newMode = (_workmodeTray.checked() && _workmodeWindow.checked()) ? dbiwmWindowAndTray : (_workmodeTray.checked() ? dbiwmTrayOnly : dbiwmWindowOnly);
if (cWorkMode() != newMode && (newMode == dbiwmWindowAndTray || newMode == dbiwmTrayOnly)) {
cSetSeenTrayTooltip(false);
}
cSetWorkMode(newMode);
App::wnd()->psUpdateWorkmode();
Local::writeSettings();
}
void SettingsInner::onWorkmodeWindow() {
if (!_workmodeTray.checked() && !_workmodeWindow.checked()) {
_workmodeTray.setChecked(true);
}
DBIWorkMode newMode = (_workmodeTray.checked() && _workmodeWindow.checked()) ? dbiwmWindowAndTray : (_workmodeTray.checked() ? dbiwmTrayOnly : dbiwmWindowOnly);
if (cWorkMode() != newMode && (newMode == dbiwmWindowAndTray || newMode == dbiwmTrayOnly)) {
cSetSeenTrayTooltip(false);
}
cSetWorkMode(newMode);
App::wnd()->psUpdateWorkmode();
Local::writeSettings();
}
void SettingsInner::onAutoStart() {
_startMinimized.setDisabled(!_autoStart.checked());
cSetAutoStart(_autoStart.checked());
if (!_autoStart.checked() && _startMinimized.checked()) {
psAutoStart(false);
_startMinimized.setChecked(false);
} else {
psAutoStart(_autoStart.checked());
Local::writeSettings();
}
}
void SettingsInner::onStartMinimized() {
cSetStartMinimized(_startMinimized.checked());
Local::writeSettings();
}
void SettingsInner::onSendToMenu() {
cSetSendToMenu(_sendToMenu.checked());
psSendToMenu(_sendToMenu.checked());
Local::writeSettings();
}
void SettingsInner::onScaleAuto() {
DBIScale newScale = _dpiAutoScale.checked() ? dbisAuto : cEvalScale(cConfigScale());
if (newScale == cScreenScale()) {
if (newScale != cScale()) {
newScale = cScale();
} else {
switch (newScale) {
case dbisOne: newScale = dbisOneAndQuarter; break;
case dbisOneAndQuarter: newScale = dbisOne; break;
case dbisOneAndHalf: newScale = dbisOneAndQuarter; break;
case dbisTwo: newScale = dbisOneAndHalf; break;
}
}
}
setScale(newScale);
}
void SettingsInner::onScaleChange() {
DBIScale newScale = dbisAuto;
switch (_dpiSlider.selected()) {
case 0: newScale = dbisOne; break;
case 1: newScale = dbisOneAndQuarter; break;
case 2: newScale = dbisOneAndHalf; break;
case 3: newScale = dbisTwo; break;
}
if (newScale == cScreenScale()) {
newScale = dbisAuto;
}
setScale(newScale);
}
void SettingsInner::setScale(DBIScale newScale) {
if (cConfigScale() == newScale) return;
cSetConfigScale(newScale);
Local::writeSettings();
App::wnd()->getTitle()->showUpdateBtn();
if (newScale == dbisAuto && !_dpiAutoScale.checked()) {
_dpiAutoScale.setChecked(true);
} else if (newScale != dbisAuto && _dpiAutoScale.checked()) {
_dpiAutoScale.setChecked(false);
}
if (newScale == dbisAuto) newScale = cScreenScale();
if (_dpiSlider.selected() != newScale - 1) {
_dpiSlider.setSelected(newScale - 1);
}
if (cEvalScale(cConfigScale()) != cEvalScale(cRealScale())) {
ConfirmBox *box = new ConfirmBox(lang(lng_settings_need_restart), lang(lng_settings_restart_now), st::defaultBoxButton, lang(lng_settings_restart_later));
connect(box, SIGNAL(confirmed()), this, SLOT(onRestartNow()));
Ui::showLayer(box);
}
}
void SettingsInner::onSoundNotify() {
cSetSoundNotify(_soundNotify.checked());
Local::writeUserSettings();
}
void SettingsInner::onIncludeMuted() {
cSetIncludeMuted(_includeMuted.checked());
Notify::unreadCounterUpdated();
Local::writeUserSettings();
}
void SettingsInner::onWindowsNotifications() {
if (cPlatform() != dbipWindows) return;
cSetWindowsNotifications(!cWindowsNotifications());
App::wnd()->notifyClearFast();
cSetCustomNotifies(!cWindowsNotifications());
Local::writeUserSettings();
}
void SettingsInner::onDesktopNotify() {
cSetDesktopNotify(_desktopNotify.checked());
if (!_desktopNotify.checked()) {
App::wnd()->notifyClear();
_senderName.setDisabled(true);
_messagePreview.setDisabled(true);
} else {
_senderName.setDisabled(false);
_messagePreview.setDisabled(!_senderName.checked());
}
Local::writeUserSettings();
if (App::wnd()) App::wnd()->updateTrayMenu();
}
void SettingsInner::enableDisplayNotify(bool enable)
{
_desktopNotify.setChecked(enable);
}
void SettingsInner::onSenderName() {
_messagePreview.setDisabled(!_senderName.checked());
if (!_senderName.checked() && _messagePreview.checked()) {
_messagePreview.setChecked(false);
} else {
if (_messagePreview.checked()) {
cSetNotifyView(dbinvShowPreview);
} else if (_senderName.checked()) {
cSetNotifyView(dbinvShowName);
} else {
cSetNotifyView(dbinvShowNothing);
}
Local::writeUserSettings();
App::wnd()->notifyUpdateAll();
}
}
void SettingsInner::onMessagePreview() {
if (_messagePreview.checked()) {
cSetNotifyView(dbinvShowPreview);
} else if (_senderName.checked()) {
cSetNotifyView(dbinvShowName);
} else {
cSetNotifyView(dbinvShowNothing);
}
Local::writeUserSettings();
App::wnd()->notifyUpdateAll();
}
void SettingsInner::onReplaceEmojis() {
cSetReplaceEmojis(_replaceEmojis.checked());
Local::writeUserSettings();
if (_replaceEmojis.checked()) {
_viewEmojis.show();
} else {
_viewEmojis.hide();
}
}
void SettingsInner::onViewEmojis() {
Ui::showLayer(new EmojiBox());
}
void SettingsInner::onStickers() {
Ui::showLayer(new StickersBox());
}
void SettingsInner::onEnterSend() {
if (_enterSend.checked()) {
cSetCtrlEnter(false);
if (App::main()) App::main()->ctrlEnterSubmitUpdated();
Local::writeUserSettings();
}
}
void SettingsInner::onCtrlEnterSend() {
if (_ctrlEnterSend.checked()) {
cSetCtrlEnter(true);
if (App::main()) App::main()->ctrlEnterSubmitUpdated();
Local::writeUserSettings();
}
}
void SettingsInner::onBackFromGallery() {
BackgroundBox *box = new BackgroundBox();
Ui::showLayer(box);
}
void SettingsInner::onBackFromFile() {
QStringList imgExtensions(cImgExtensions());
QString filter(qsl("Image files (*") + imgExtensions.join(qsl(" *")) + qsl(");;All files (*.*)"));
QImage img;
QString file;
QByteArray remoteContent;
if (filedialogGetOpenFile(file, remoteContent, lang(lng_choose_images), filter)) {
if (!remoteContent.isEmpty()) {
img = App::readImage(remoteContent);
} else {
if (!file.isEmpty()) {
img = App::readImage(file);
}
}
}
if (img.isNull() || img.width() <= 0 || img.height() <= 0) return;
if (img.width() > 4096 * img.height()) {
img = img.copy((img.width() - 4096 * img.height()) / 2, 0, 4096 * img.height(), img.height());
} else if (img.height() > 4096 * img.width()) {
img = img.copy(0, (img.height() - 4096 * img.width()) / 2, img.width(), 4096 * img.width());
}
App::initBackground(-1, img);
_tileBackground.setChecked(false);
updateChatBackground();
}
void SettingsInner::updateChatBackground() {
int32 size = st::setBackgroundSize * cIntRetinaFactor();
QImage back(size, size, QImage::Format_ARGB32_Premultiplied);
back.setDevicePixelRatio(cRetinaFactor());
{
QPainter p(&back);
const QPixmap &pix(*cChatBackground());
int sx = (pix.width() > pix.height()) ? ((pix.width() - pix.height()) / 2) : 0;
int sy = (pix.height() > pix.width()) ? ((pix.height() - pix.width()) / 2) : 0;
int s = (pix.width() > pix.height()) ? pix.height() : pix.width();
p.setRenderHint(QPainter::SmoothPixmapTransform);
p.drawPixmap(0, 0, st::setBackgroundSize, st::setBackgroundSize, pix, sx, sy, s, s);
}
_background = QPixmap::fromImage(back);
_background.setDevicePixelRatio(cRetinaFactor());
_needBackgroundUpdate = false;
updateBackgroundRect();
}
void SettingsInner::needBackgroundUpdate(bool tile) {
_needBackgroundUpdate = true;
_tileBackground.setChecked(tile);
updateChatBackground();
}
void SettingsInner::onTileBackground() {
if (cTileBackground() != _tileBackground.checked()) {
cSetTileBackground(_tileBackground.checked());
if (App::main()) App::main()->clearCachedBackground();
Local::writeUserSettings();
}
}
void SettingsInner::onAdaptiveForWide() {
if (Global::AdaptiveForWide() != _adaptiveForWide.checked()) {
Global::SetAdaptiveForWide(_adaptiveForWide.checked());
if (App::wnd()) {
App::wnd()->updateAdaptiveLayout();
}
Local::writeUserSettings();
}
}
void SettingsInner::onDontAskDownloadPath() {
cSetAskDownloadPath(!_dontAskDownloadPath.checked());
Local::writeUserSettings();
showAll();
resizeEvent(0);
update();
}
void SettingsInner::onDownloadPathEdit() {
DownloadPathBox *box = new DownloadPathBox();
connect(box, SIGNAL(closed()), this, SLOT(onDownloadPathEdited()));
Ui::showLayer(box);
}
void SettingsInner::onDownloadPathEdited() {
QString path;
if (cDownloadPath().isEmpty()) {
path = lang(lng_download_path_default);
} else if (cDownloadPath() == qsl("tmp")) {
path = lang(lng_download_path_temp);
} else {
path = st::linkFont->elided(QDir::toNativeSeparators(cDownloadPath()), st::setWidth - st::setVersionLeft - _downloadPathWidth);
}
_downloadPathEdit.setText(path);
showAll();
}
void SettingsInner::onDownloadPathClear() {
ConfirmBox *box = new ConfirmBox(lang(lng_sure_clear_downloads));
connect(box, SIGNAL(confirmed()), this, SLOT(onDownloadPathClearSure()));
Ui::showLayer(box);
}
void SettingsInner::onDownloadPathClearSure() {
Ui::hideLayer();
App::wnd()->tempDirDelete(Local::ClearManagerDownloads);
_tempDirClearState = TempDirClearing;
showAll();
update();
}
void SettingsInner::onLocalStorageClear() {
App::wnd()->tempDirDelete(Local::ClearManagerStorage);
_storageClearState = TempDirClearing;
showAll();
update();
}
void SettingsInner::onTempDirCleared(int task) {
if (task & Local::ClearManagerDownloads) {
_tempDirClearState = TempDirCleared;
} else if (task & Local::ClearManagerStorage) {
_storageClearState = TempDirCleared;
}
showAll();
update();
}
void SettingsInner::onTempDirClearFailed(int task) {
if (task & Local::ClearManagerDownloads) {
_tempDirClearState = TempDirClearFailed;
} else if (task & Local::ClearManagerStorage) {
_storageClearState = TempDirClearFailed;
}
showAll();
update();
}
void SettingsInner::onAutoDownload() {
Ui::showLayer(new AutoDownloadBox());
}
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
void SettingsInner::setUpdatingState(UpdatingState state, bool force) {
if (_updatingState != state || force) {
_updatingState = state;
if (cAutoUpdate()) {
switch (state) {
case UpdatingNone:
case UpdatingLatest: _checkNow.show(); _restartNow.hide(); break;
case UpdatingReady: _checkNow.hide(); _restartNow.show(); break;
case UpdatingCheck:
case UpdatingDownload:
case UpdatingFail: _checkNow.hide(); _restartNow.hide(); break;
}
update(0, _restartNow.y() - 10, width(), _restartNow.height() + 20);
} else {
_checkNow.hide();
_restartNow.hide();
}
}
}
void SettingsInner::setDownloadProgress(qint64 ready, qint64 total) {
qint64 readyTenthMb = (ready * 10 / (1024 * 1024)), totalTenthMb = (total * 10 / (1024 * 1024));
QString readyStr = QString::number(readyTenthMb / 10) + '.' + QString::number(readyTenthMb % 10);
QString totalStr = QString::number(totalTenthMb / 10) + '.' + QString::number(totalTenthMb % 10);
QString res = lng_settings_downloading(lt_ready, readyStr, lt_total, totalStr);
if (_newVersionDownload != res) {
_newVersionDownload = res;
if (cAutoUpdate()) {
update(0, _restartNow.y() - 10, width(), _restartNow.height() + 20);
}
}
}
void SettingsInner::onUpdateChecking() {
setUpdatingState(UpdatingCheck);
}
void SettingsInner::onUpdateLatest() {
setUpdatingState(UpdatingLatest);
}
void SettingsInner::onUpdateDownloading(qint64 ready, qint64 total) {
setUpdatingState(UpdatingDownload);
setDownloadProgress(ready, total);
}
void SettingsInner::onUpdateReady() {
setUpdatingState(UpdatingReady);
}
void SettingsInner::onUpdateFailed() {
setUpdatingState(UpdatingFail);
}
#endif
void SettingsInner::onPhotoUpdateStart() {
showAll();
update();
}
void SettingsInner::onPhotoUpdateFail(PeerId peer) {
if (!self() || self()->id != peer) return;
saveError(lang(lng_bad_photo));
showAll();
update();
}
void SettingsInner::onPhotoUpdateDone(PeerId peer) {
if (!self() || self()->id != peer) return;
showAll();
update();
}
SettingsWidget::SettingsWidget(MainWindow *parent) : TWidget(parent)
, _a_show(animation(this, &SettingsWidget::step_show))
, _scroll(this, st::setScroll)
, _inner(this)
, _close(this, st::setClose) {
_scroll.setWidget(&_inner);
connect(App::wnd(), SIGNAL(resized(const QSize&)), this, SLOT(onParentResize(const QSize&)));
connect(&_close, SIGNAL(clicked()), App::wnd(), SLOT(showSettings()));
setGeometry(QRect(0, st::titleHeight, App::wnd()->width(), App::wnd()->height() - st::titleHeight));
showAll();
}
void SettingsWidget::onParentResize(const QSize &newSize) {
resize(newSize);
}
void SettingsWidget::animShow(const QPixmap &bgAnimCache, bool back) {
if (App::app()) App::app()->mtpPause();
(back ? _cacheOver : _cacheUnder) = bgAnimCache;
_a_show.stop();
showAll();
(back ? _cacheUnder : _cacheOver) = myGrab(this);
hideAll();
a_coordUnder = back ? anim::ivalue(-st::slideShift, 0) : anim::ivalue(0, -st::slideShift);
a_coordOver = back ? anim::ivalue(0, width()) : anim::ivalue(width(), 0);
a_shadow = back ? anim::fvalue(1, 0) : anim::fvalue(0, 1);
_a_show.start();
show();
}
void SettingsWidget::step_show(float64 ms, bool timer) {
float64 dt = ms / st::slideDuration;
if (dt >= 1) {
_a_show.stop();
a_coordUnder.finish();
a_coordOver.finish();
a_shadow.finish();
_cacheUnder = _cacheOver = QPixmap();
showAll();
_inner.setFocus();
if (App::app()) App::app()->mtpUnpause();
} else {
a_coordUnder.update(dt, st::slideFunction);
a_coordOver.update(dt, st::slideFunction);
a_shadow.update(dt, st::slideFunction);
}
if (timer) update();
}
void SettingsWidget::stop_show() {
_a_show.stop();
}
void SettingsWidget::paintEvent(QPaintEvent *e) {
QRect r(e->rect());
bool trivial = (rect() == r);
Painter p(this);
if (!trivial) {
p.setClipRect(r);
}
if (_a_show.animating()) {
if (a_coordOver.current() > 0) {
p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current() * cRetinaFactor(), 0, a_coordOver.current() * cRetinaFactor(), height() * cRetinaFactor()));
p.setOpacity(a_shadow.current() * st::slideFadeOut);
p.fillRect(0, 0, a_coordOver.current(), height(), st::black->b);
p.setOpacity(1);
}
p.drawPixmap(a_coordOver.current(), 0, _cacheOver);
p.setOpacity(a_shadow.current());
p.drawPixmap(QRect(a_coordOver.current() - st::slideShadow.pxWidth(), 0, st::slideShadow.pxWidth(), height()), App::sprite(), st::slideShadow.rect());
} else {
p.fillRect(rect(), st::setBG->b);
}
}
void SettingsWidget::showAll() {
_scroll.show();
_inner.show();
_inner.showAll();
if (Adaptive::OneColumn()) {
_close.hide();
} else {
_close.show();
}
}
void SettingsWidget::hideAll() {
_scroll.hide();
_close.hide();
}
void SettingsWidget::resizeEvent(QResizeEvent *e) {
_scroll.resize(size());
_inner.updateSize(width());
_close.move(st::setClosePos.x(), st::setClosePos.y());
}
void SettingsWidget::dragEnterEvent(QDragEnterEvent *e) {
}
void SettingsWidget::dropEvent(QDropEvent *e) {
}
void SettingsWidget::updateAdaptiveLayout() {
if (Adaptive::OneColumn()) {
_close.hide();
} else {
_close.show();
}
_inner.updateAdaptiveLayout();
resizeEvent(0);
}
void SettingsWidget::updateDisplayNotify() {
_inner.enableDisplayNotify(cDesktopNotify());
}
void SettingsWidget::updateOnlineDisplay() {
_inner.updateOnlineDisplay();
}
void SettingsWidget::updateConnectionType() {
_inner.updateConnectionType();
}
void SettingsWidget::rpcClear() {
_inner.rpcClear();
}
void SettingsWidget::setInnerFocus() {
_inner.setFocus();
}
void SettingsWidget::needBackgroundUpdate(bool tile) {
_inner.needBackgroundUpdate(tile);
}
SettingsWidget::~SettingsWidget() {
if (App::wnd()) App::wnd()->noSettings(this);
}