diff --git a/MSVC.md b/MSVC.md index cf8f5acaf..3d7f75689 100644 --- a/MSVC.md +++ b/MSVC.md @@ -14,9 +14,9 @@ or download in ZIP and extract to **D:\TBuild\**, rename **tdesktop-master** to ###Prepare libraries -####OpenSSL 1.0.1g +####OpenSSL 1.0.1h -https://www.openssl.org/related/binaries.html > **OpenSSL for Windows** > Download [**Win32 OpenSSL v1.0.1g** (16 Mb)](http://slproweb.com/download/Win32OpenSSL-1_0_1g.exe) +https://www.openssl.org/related/binaries.html > **OpenSSL for Windows** > Download [**Win32 OpenSSL v1.0.1h** (16 Mb)](http://slproweb.com/download/Win32OpenSSL-1_0_1h.exe) Install to **D:\TBuild\Libraries\OpenSSL-Win32**, while installing **Copy OpenSSL DLLs to** choose **The OpenSSL binaries (/bin) directory** diff --git a/QTCREATOR.md b/QTCREATOR.md index e4d531295..74942a793 100644 --- a/QTCREATOR.md +++ b/QTCREATOR.md @@ -55,13 +55,6 @@ In Terminal go to **/home/user/TBuild/Libraries/QtStatic** and there run building (**make** command) will take really long time. -#####Building pulseaudio plugin - -In Terminal go to **/home/user/TBuild/Libraries/QtStatic/qtmultimedia/src/plugins/pulseaudio** and run - - qmake pulseaudio.pro - make - ###Building Telegram Desktop * Launch Qt Creator, all projects will be taken from **/home/user/TBuild/tdesktop/Telegram** @@ -70,6 +63,6 @@ In Terminal go to **/home/user/TBuild/Libraries/QtStatic/qtmultimedia/src/plugin * Open MetaStyle.pro, configure project with paths **/home/user/TBuild/tdesktop/Linux/DebugIntermediateStyle** and **/home/user/TBuild/tdesktop/Linux/ReleaseIntermediateStyle** and build for Debug * Open MetaEmoji.pro, configure project with paths **/home/user/TBuild/tdesktop/Linux/DebugIntermediateEmoji** and **/home/user/TBuild/tdesktop/Linux/ReleaseIntermediateEmoji** and build for Debug * Open MetaLang.pro, configure project with paths **/home/user/TBuild/tdesktop/Linux/DebugIntermediateLang** and **/home/user/TBuild/tdesktop/Linux/ReleaseIntermediateLang** and build for Debug -* Open Telegram.pro, configure project with paths **/home/user/TBuild/tdesktop/Linux/DebugIntermediate** and **/home/user/TBuild/tdesktop/Linux/ReleaseIntermediate** and build for Debug +* Open Telegram.pro, configure project with paths **/home/user/TBuild/tdesktop/Linux/DebugIntermediate** and **/home/user/TBuild/tdesktop/Linux/ReleaseIntermediate** and build for Debug, if GeneratedFiles are not found click **Run qmake** from **Build** menu and try again * Open Updater.pro, configure project with paths **/home/user/TBuild/tdesktop/Linux/DebugIntermediateUpdater** and **/home/user/TBuild/tdesktop/Linux/ReleaseIntermediateUpdater** and build for Debug -* Release Telegram build will require removing **CUSTOM_API_ID** definition in Telegram.pro project and may require changing paths in **/home/user/TBuild/tdesktop/Telegram/FixMake.sh** or **/home/user/TBuild/tdesktop/Telegram/FixMake32.sh** for static library linking fix +* Release Telegram build will require removing **CUSTOM_API_ID** definition in Telegram.pro project and may require changing paths in **/home/user/TBuild/tdesktop/Telegram/FixMake.sh** or **/home/user/TBuild/tdesktop/Telegram/FixMake32.sh** for static library linking fix, static linking applies only on second Release build (first uses old Makefile) diff --git a/README.md b/README.md index 67f3bc11c..38bb77993 100644 --- a/README.md +++ b/README.md @@ -6,18 +6,17 @@ Source code is published under GPL v3, license is available [here](https://githu ###Supported systems -Only Windows and OS X systems are supported at this moment, Linux builds are on their way. - * Windows XP * Windows Vista * Windows 7 * Windows 8 (**not** RT) * Windows 8.1 (**not** RT) +* OS X 10.7 +* OS X 10.8 * OS X 10.9 -* OS X 10.7-10.8 (not tested) +* Ubuntu 12.04 * Ubuntu 13.04 * Ubuntu 14.04 -* Fedora (not tested) ###Third-party @@ -34,7 +33,7 @@ Only Windows and OS X systems are supported at this moment, Linux builds are on ###[Build instructions for XCode 5.1.1](https://github.com/telegramdesktop/tdesktop/blob/master/XCODE.md) -###[Build instructions for Qt Creator 2.7 Ubuntu](https://github.com/telegramdesktop/tdesktop/blob/master/QTCREATOR.md) +###[Build instructions for Qt Creator 3.1.2 Ubuntu](https://github.com/telegramdesktop/tdesktop/blob/master/QTCREATOR.md) ##Projects in Telegram solution diff --git a/Telegram/FixMake32.sh b/Telegram/FixMake32.sh index 3f63d2d59..4a8692859 100755 --- a/Telegram/FixMake32.sh +++ b/Telegram/FixMake32.sh @@ -1,13 +1,13 @@ -sed -i 's/\-lxcb\-render\-util/\/usr\/lib\/libxcb\-render\-util\.a/g' Makefile +sed -i 's/\-lxcb\-render\-util/\/usr\/lib\/i386\-linux\-gnu\/libxcb\-render\-util\.a/g' Makefile sed -i 's/\-lxcb\-render/\/usr\/lib\/i386\-linux\-gnu\/libxcb\-render\.a/g' Makefile sed -i 's/\-lxcb\-sync/\/usr\/lib\/i386\-linux\-gnu\/libxcb\-sync\.a/g' Makefile -sed -i 's/\-lxcb\-keysyms/\/usr\/lib\/libxcb\-keysyms\.a/g' Makefile -sed -i 's/\-lxcb\-icccm/\/usr\/lib\/libxcb\-icccm\.a/g' Makefile +sed -i 's/\-lxcb\-keysyms/\/usr\/lib\/i386\-linux\-gnu\/libxcb\-keysyms\.a/g' Makefile +sed -i 's/\-lxcb\-icccm/\/usr\/lib\/i386\-linux\-gnu\/libxcb\-icccm\.a/g' Makefile sed -i 's/\-lxcb\-xfixes/\/usr\/lib\/i386\-linux\-gnu\/libxcb\-xfixes\.a/g' Makefile sed -i 's/\-lxcb\-shm/\/usr\/lib\/i386\-linux\-gnu\/libxcb\-shm\.a/g' Makefile sed -i 's/\-lxcb\-randr/\/usr\/lib\/i386\-linux\-gnu\/libxcb\-randr\.a/g' Makefile sed -i 's/\-lxcb\-shape/\/usr\/lib\/i386\-linux\-gnu\/libxcb\-shape\.a/g' Makefile -sed -i 's/\-lxcb\-image/\/usr\/lib\/libxcb\-image\.a \/usr\/lib\/i386\-linux\-gnu\/libxcb\-util\.a/g' Makefile +sed -i 's/\-lxcb\-image/\/usr\/lib\/i386\-linux\-gnu\/libxcb\-image\.a \/usr\/lib\/i386\-linux\-gnu\/libxcb\-util\.a/g' Makefile sed -i 's/\-llzma/\/usr\/lib\/i386\-linux\-gnu\/liblzma\.a/g' Makefile sed -i 's/\-lz/\/usr\/lib\/i386\-linux\-gnu\/libz\.a/g' Makefile sed -i 's/\-lssl/\/usr\/lib\/i386\-linux\-gnu\/libssl\.a/g' Makefile diff --git a/Telegram/PrepareLinux.sh b/Telegram/PrepareLinux.sh index c1ca341cf..dfa0a2a3a 100755 --- a/Telegram/PrepareLinux.sh +++ b/Telegram/PrepareLinux.sh @@ -1,5 +1,5 @@ -AppVersionStr=0.5.8 -AppVersion=5008 +AppVersionStr=0.5.9 +AppVersion=5009 if [ -d "./../Linux/Release/deploy/$AppVersionStr" ]; then echo "Deploy folder for version $AppVersionStr already exists!" diff --git a/Telegram/PrepareLinux32.sh b/Telegram/PrepareLinux32.sh index aa4a5b56d..ef4d22c24 100755 --- a/Telegram/PrepareLinux32.sh +++ b/Telegram/PrepareLinux32.sh @@ -1,5 +1,5 @@ -AppVersionStr=0.5.8 -AppVersion=5008 +AppVersionStr=0.5.9 +AppVersion=5009 if [ -d "./../Linux/Release/deploy/$AppVersionStr" ]; then echo "Deploy folder for version $AppVersionStr already exists!" diff --git a/Telegram/PrepareMac.sh b/Telegram/PrepareMac.sh index ffd792406..79d056d42 100755 --- a/Telegram/PrepareMac.sh +++ b/Telegram/PrepareMac.sh @@ -1,5 +1,5 @@ -AppVersionStr=0.5.8 -AppVersion=5008 +AppVersionStr=0.5.9 +AppVersion=5009 if [ -d "./../Mac/Release/deploy/$AppVersionStr" ]; then echo "Deploy folder for version $AppVersionStr already exists!" @@ -27,7 +27,7 @@ if [ ! -f "./../Mac/Release/Telegram.app/Contents/MacOS/Telegram" ]; then fi if [ ! -f "./../Mac/Release/Telegram.app/Contents/Frameworks/Updater" ]; then - echo "Icon.icns not found in Resources!" + echo "Updater not found in Frameworks!" exit 1 fi diff --git a/Telegram/Resources/lang.txt b/Telegram/Resources/lang.txt index 960bf1426..855e22acf 100644 --- a/Telegram/Resources/lang.txt +++ b/Telegram/Resources/lang.txt @@ -71,6 +71,7 @@ lng_status_lastseen_hours: "%1 hours ago"; lng_status_lastseen_today: "today at {time}"; lng_status_lastseen_yesterday: "yesterday at {time}"; lng_status_lastseen_date: "{date}"; +lng_status_lastseen_date_time: "{date} at {time}"; lng_status_online: "online"; lng_chat_no_members: "Group is unaccessible"; @@ -138,7 +139,12 @@ lng_settings_uploading_photo: "Uploading photo..."; lng_settings_section_notify: "Notifications"; lng_settings_desktop_notify: "Desktop notifications"; -lng_settings_sound_notify: "Sound"; +lng_settings_show_name: "Show sender's name"; +lng_settings_show_preview: "Show message preview"; +lng_settings_sound_notify: "Sound notification"; + +lng_notification_title: "Telegram Desktop"; +lng_notification_preview: "You have a new message"; lng_settings_section_general: "General"; lng_settings_auto_update: "Update automatically"; @@ -154,6 +160,7 @@ lng_settings_workmode_tray: "Show tray icon"; lng_settings_workmode_window: "Show taskbar icon"; lng_settings_auto_start: "Launch Telegram when system starts"; lng_settings_start_min: "Launch minimized"; +lng_settings_add_sendto: "Place Telegram in «Send to» menu"; lng_settings_scale_label: "Interface scale"; lng_settings_scale_auto: "Auto ({cur})"; @@ -338,7 +345,10 @@ lng_really_send_image: "Do you want to send this image?"; lng_forward_choose: "Choose recipient..."; lng_forward_confirm: "Forward to {recipient}?"; lng_forward_share_contact: "Share contact to {recipient}?"; +lng_forward_send_file_confirm: "Send «{name}» to {recipient}?"; +lng_forward_send_files_confirm: "Send selected files to {recipient}?"; lng_forward: "Forward"; +lng_forward_send: "Send"; lng_contact_phone: "Phone number"; lng_enter_contact_data: "New Contact"; diff --git a/Telegram/Resources/style.txt b/Telegram/Resources/style.txt index 1b03a9041..f5a7cb395 100644 --- a/Telegram/Resources/style.txt +++ b/Telegram/Resources/style.txt @@ -198,19 +198,20 @@ cbDefFlat: flatCheckbox { disabledCursor: cursor(default); - imageRect: sprite(144px, 68px, 22px, 22px); - chkImageRect: sprite(119px, 68px, 22px, 22px); - overImageRect: sprite(144px, 68px, 22px, 22px); - chkOverImageRect: sprite(119px, 68px, 22px, 22px); - disImageRect: sprite(193px, 68px, 22px, 22px); - chkDisImageRect: sprite(193px, 68px, 22px, 22px); + imageRect: sprite(140px, 68px, 22px, 22px); + chkImageRect: sprite(115px, 68px, 22px, 22px); + overImageRect: sprite(140px, 68px, 22px, 22px); + chkOverImageRect: sprite(115px, 68px, 22px, 22px); + disImageRect: sprite(140px, 43px, 22px, 22px); + chkDisImageRect: sprite(115px, 43px, 22px, 22px); imagePos: point(0px, 0px); } rbDefFlat: flatCheckbox(cbDefFlat) { - chkImageRect: sprite(169px, 68px, 22px, 22px); - chkOverImageRect: sprite(169px, 68px, 22px, 22px); + chkImageRect: sprite(165px, 68px, 22px, 22px); + chkOverImageRect: sprite(165px, 68px, 22px, 22px); + chkDisImageRect: sprite(165px, 43px, 22px, 22px); } inpDefFont: font(17px); @@ -1243,8 +1244,11 @@ aboutHeight: 441px; aboutHeaderFont: font(24px semibold); aboutSubheaderFont: font(24px); aboutHeaderTop: 139px; -aboutVersionFont: font(16px); -aboutVersionColor: #999; +aboutVersion: flatLabel(labelDefFlat) { + font: font(16px); + width: aboutWidth; + align: align(center); +} aboutVersionTop: 178px; aboutTextFont: font(15px); aboutTextTop: 221px; diff --git a/Telegram/Setup.iss b/Telegram/Setup.iss index d2b584d91..1803535dd 100644 --- a/Telegram/Setup.iss +++ b/Telegram/Setup.iss @@ -3,9 +3,9 @@ #define MyAppShortName "Telegram" #define MyAppName "Telegram Win (Unofficial)" -#define MyAppVersion "0.5.8" -#define MyAppVersionZero "0.5.8" -#define MyAppFullVersion "0.5.8.0" +#define MyAppVersion "0.5.9" +#define MyAppVersionZero "0.5.9" +#define MyAppFullVersion "0.5.9.0" #define MyAppPublisher "Telegram (Unofficial)" #define MyAppURL "https://tdesktop.com" #define MyAppExeName "Telegram.exe" diff --git a/Telegram/SourceFiles/_other/Lang.plist b/Telegram/SourceFiles/_other/Lang.plist deleted file mode 100644 index 2a5b32ce2..000000000 --- a/Telegram/SourceFiles/_other/Lang.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - NSPrincipalClass - NSApplication - CFBundleIconFile - - CFBundlePackageType - APPL - CFBundleGetInfoString - Created by Qt/QMake - CFBundleSignature - ???? - CFBundleExecutable - MetaLang - CFBundleIdentifier - com.yourcompany.${PRODUCT_NAME:rfc1034identifier} - NOTE - This file was generated by Qt/QMake. - - diff --git a/Telegram/SourceFiles/_other/packer.cpp b/Telegram/SourceFiles/_other/packer.cpp index 4df844bc9..716961025 100644 --- a/Telegram/SourceFiles/_other/packer.cpp +++ b/Telegram/SourceFiles/_other/packer.cpp @@ -431,6 +431,7 @@ int main(int argc, char *argv[]) QString outName(QString("tlinux32upd%1").arg(version)); #elif defined Q_OS_LINUX64 QString outName(QString("tlinuxupd%1").arg(version)); +#else #error Unknown platform! #endif QFile out(outName); diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index bea52c951..8c456aa93 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -180,14 +180,25 @@ namespace App { return dNow.secsTo(dTomorrow); } - QString onlineText(int32 online, int32 now) { + QString onlineText(int32 online, int32 now, bool precise) { if (!online) return lang(lng_status_offline); if (online < 0) return lang(lng_status_invisible); if (online > now) { return lang(lng_status_online); } - int32 minutes = (now - online) / 60; QString when; + if (precise) { + QDateTime dOnline(date(online)), dNow(date(now)); + if (dOnline.date() == dNow.date()) { + when = lang(lng_status_lastseen_today).replace(qsl("{time}"), dOnline.time().toString(qsl("hh:mm"))); + } else if (dOnline.date().addDays(1) == dNow.date()) { + when = lang(lng_status_lastseen_yesterday).replace(qsl("{time}"), dOnline.time().toString(qsl("hh:mm"))); + } else { + when = lang(lng_status_lastseen_date_time).replace(qsl("{date}"), dOnline.date().toString(qsl("dd.MM.yy"))).replace(qsl("{time}"), dOnline.time().toString(qsl("hh:mm"))); + } + return lang(lng_status_lastseen).replace(qsl("{when}"), when); + } + int32 minutes = (now - online) / 60; if (!minutes) { when = lang(lng_status_lastseen_now); } else if (minutes == 1) { @@ -211,9 +222,6 @@ namespace App { } } } - if (when.isEmpty()) { - int a = 0; - } return lang(lng_status_lastseen).replace(qsl("{when}"), when); } @@ -1137,6 +1145,9 @@ namespace App { if (::mousedItem == item) { mousedItem(0); } + if (App::wnd()) { + App::wnd()->notifyItemRemoved(item); + } } void historyUnregItem(HistoryItem *item) { @@ -1360,6 +1371,7 @@ namespace App { configStream << quint32(dbiAutoStart) << qint32(cAutoStart()); configStream << quint32(dbiStartMinimized) << qint32(cStartMinimized()); + configStream << quint32(dbiSendToMenu) << qint32(cSendToMenu()); configStream << quint32(dbiWorkMode) << qint32(cWorkMode()); configStream << quint32(dbiSeenTrayTooltip) << qint32(cSeenTrayTooltip()); configStream << quint32(dbiAutoUpdate) << qint32(cAutoUpdate()); @@ -1421,6 +1433,12 @@ namespace App { cSetStartMinimized(v == 1); } break; + case dbiSendToMenu: { + qint32 v; + configStream >> v; + cSetSendToMenu(v == 1); + } break; + case dbiSoundNotify: { if (configVersion < 3008) { qint32 v; @@ -1542,6 +1560,7 @@ namespace App { stream << quint32(dbiDefaultAttach) << qint32(cDefaultAttach()); stream << quint32(dbiSoundNotify) << qint32(cSoundNotify()); stream << quint32(dbiDesktopNotify) << qint32(cDesktopNotify()); + stream << quint32(dbiNotifyView) << qint32(cNotifyView()); stream << quint32(dbiAskDownloadPath) << qint32(cAskDownloadPath()); stream << quint32(dbiDownloadPath) << (cAskDownloadPath() ? QString() : cDownloadPath()); stream << quint32(dbiEmojiTab) << qint32(cEmojiTab()); @@ -1704,6 +1723,16 @@ namespace App { cSetDesktopNotify(v == 1); } break; + case dbiNotifyView: { + qint32 v; + stream >> v; + switch (v) { + case dbinvShowNothing: cSetNotifyView(dbinvShowNothing); break; + case dbinvShowName: cSetNotifyView(dbinvShowName); break; + default: cSetNotifyView(dbinvShowPreview); break; + } + } + case dbiAskDownloadPath: { qint32 v; stream >> v; diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h index c60a1fd18..be6c374c3 100644 --- a/Telegram/SourceFiles/app.h +++ b/Telegram/SourceFiles/app.h @@ -64,7 +64,7 @@ namespace App { int32 chatFromPeer(const PeerId &peer_id); int32 onlineWillChangeIn(int32 onlineOnServer, int32 nowOnServer); - QString onlineText(int32 onlineOnServer, int32 nowOnServer); + QString onlineText(int32 onlineOnServer, int32 nowOnServer, bool precise = false); void feedUsers(const MTPVector &users); void feedChats(const MTPVector &chats); diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index 3430e418b..0ab1ac016 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -73,6 +73,12 @@ namespace { Application::Application(int &argc, char **argv) : PsApplication(argc, argv), serverName(psServerPrefix() + cGUIDStr()), closing(false), updateRequestId(0), updateReply(0), updateThread(0), updateDownloader(0) { + + QByteArray d(QDir((cPlatform() == dbipWindows ? cExeDir() : cWorkingDir()).toLower()).absolutePath().toUtf8()); + char h[33] = { 0 }; + hashMd5Hex(d.constData(), d.size(), h); + serverName = psServerPrefix() + h + '-' + cGUIDStr(); + if (mainApp) { DEBUG_LOG(("Application Error: another Application was created, terminating..")); exit(0); @@ -435,10 +441,57 @@ void Application::startUpdateCheck(bool forceWait) { } } +namespace { + QChar _toHex(ushort v) { + v = v & 0x000F; + return QChar::fromLatin1((v >= 10) ? ('a' + (v - 10)) : ('0' + v)); + } + ushort _fromHex(QChar c) { + return ((c.unicode() >= uchar('a')) ? (c.unicode() - uchar('a') + 10) : (c.unicode() - uchar('0'))) & 0x000F; + } + + QString _escapeTo7bit(const QString &str) { + QString result; + result.reserve(str.size() * 2); + for (int i = 0, l = str.size(); i != l; ++i) { + QChar ch(str.at(i)); + ushort uch(ch.unicode()); + if (uch < 32 || uch > 127 || uch == ushort(uchar('%'))) { + result.append('%').append(_toHex(uch >> 12)).append(_toHex(uch >> 8)).append(_toHex(uch >> 4)).append(_toHex(uch)); + } else { + result.append(ch); + } + } + return result; + } + + QString _escapeFrom7bit(const QString &str) { + QString result; + result.reserve(str.size()); + for (int i = 0, l = str.size(); i != l; ++i) { + QChar ch(str.at(i)); + if (ch == QChar::fromLatin1('%') && i + 4 < l) { + result.append(QChar(ushort((_fromHex(str.at(i + 1)) << 12) | (_fromHex(str.at(i + 2)) << 8) | (_fromHex(str.at(i + 3)) << 4) | _fromHex(str.at(i + 4))))); + i += 4; + } else { + result.append(ch); + } + } + return result; + } +} + void Application::socketConnected() { DEBUG_LOG(("Application Info: socket connected, this is not the first application instance, sending show command..")); closing = true; - socket.write("CMD:show;"); + QString commands; + const QStringList &lst(cSendPaths()); + for (QStringList::const_iterator i = lst.cbegin(), e = lst.cend(); i != e; ++i) { + commands += qsl("SEND:") + _escapeTo7bit(*i) + ';'; + } + commands += qsl("CMD:show;"); + DEBUG_LOG(("Application Info: writing commands %1").arg(commands)); + socket.write(commands.toLocal8Bit()); } void Application::socketWritten(qint64/* bytes*/) { @@ -482,7 +535,7 @@ void Application::socketError(QLocalSocket::LocalSocketError e) { psCheckLocalSocket(serverName); if (!server.listen(serverName)) { - DEBUG_LOG(("Application Error: failed to start listening to %1 server").arg(serverName)); + DEBUG_LOG(("Application Error: failed to start listening to %1 server, error %2").arg(serverName).arg(int(server.serverError()))); return App::quit(); } @@ -551,10 +604,11 @@ void Application::newInstanceConnected() { } void Application::readClients() { + QStringList toSend; for (ClientSockets::iterator i = clients.begin(), e = clients.end(); i != e; ++i) { i->second.append(i->first->readAll()); if (i->second.size()) { - QString cmds(i->second); + QString cmds(QString::fromLocal8Bit(i->second)); int32 from = 0, l = cmds.length(); for (int32 to = cmds.indexOf(QChar(';'), from); to >= from; to = (from < l) ? cmds.indexOf(QChar(';'), from) : -1) { QStringRef cmd(&cmds, from, to - from); @@ -562,6 +616,10 @@ void Application::readClients() { execExternal(cmds.mid(from + 4, to - from - 4)); QByteArray response(QString("RES:%1;").arg(QCoreApplication::applicationPid()).toUtf8()); i->first->write(response.data(), response.size()); + } else if (cmd.indexOf("SEND:") == 0) { + if (cSendPaths().isEmpty()) { + toSend.append(_escapeFrom7bit(cmds.mid(from + 5, to - from - 5))); + } } else { LOG(("Application Error: unknown command %1 passed in local socket").arg(QString(cmd.constData(), cmd.length()))); } @@ -572,6 +630,16 @@ void Application::readClients() { } } } + if (!toSend.isEmpty()) { + QStringList paths(cSendPaths()); + paths.append(toSend); + cSetSendPaths(paths); + } + if (!cSendPaths().isEmpty()) { + if (App::wnd()) { + App::wnd()->sendPaths(); + } + } } void Application::removeClients() { diff --git a/Telegram/SourceFiles/art/sprite.png b/Telegram/SourceFiles/art/sprite.png index 2f5830726..d628343ba 100644 Binary files a/Telegram/SourceFiles/art/sprite.png and b/Telegram/SourceFiles/art/sprite.png differ diff --git a/Telegram/SourceFiles/art/sprite_200x.png b/Telegram/SourceFiles/art/sprite_200x.png index 1d5a6885a..4a9034189 100644 Binary files a/Telegram/SourceFiles/art/sprite_200x.png and b/Telegram/SourceFiles/art/sprite_200x.png differ diff --git a/Telegram/SourceFiles/boxes/aboutbox.cpp b/Telegram/SourceFiles/boxes/aboutbox.cpp index 462ce32b3..5b36c26df 100644 --- a/Telegram/SourceFiles/boxes/aboutbox.cpp +++ b/Telegram/SourceFiles/boxes/aboutbox.cpp @@ -24,20 +24,19 @@ Copyright (c) 2014 John Preston, https://tdesktop.com AboutBox::AboutBox() : _done(this, lang(lng_about_done), st::aboutCloseButton), +_version(this, qsl("[a href=\"https://tdesktop.com/#version_history\"]") + textClean(lang(lng_about_version).replace(qsl("{version}"), QString::fromWCharArray(AppVersionStr))) + qsl("[/a]"), st::aboutVersion, st::defaultTextStyle), _text(this, lang(lng_about_text), st::aboutLabel, st::aboutTextStyle), _hiding(false), a_opacity(0, 1) { - + _width = st::aboutWidth; _height = st::aboutHeight; + _version.move(0, st::aboutVersionTop); _text.move(0, st::aboutTextTop); _headerWidth = st::aboutHeaderFont->m.width(qsl("Telegram ")); _subheaderWidth = st::aboutSubheaderFont->m.width(qsl("Desktop")); - _versionText = lang(lng_about_version).replace(qsl("{version}"), QString::fromWCharArray(AppVersionStr)); - _versionWidth = st::aboutVersionFont->m.width(_versionText); - _done.move(0, _height - _done.height()); connect(&_done, SIGNAL(clicked()), this, SLOT(onClose())); @@ -51,11 +50,13 @@ _hiding(false), a_opacity(0, 1) { void AboutBox::hideAll() { _done.hide(); + _version.hide(); _text.hide(); } void AboutBox::showAll() { _done.show(); + _version.show(); _text.show(); } @@ -88,10 +89,6 @@ void AboutBox::paintEvent(QPaintEvent *e) { p.setFont(st::aboutSubheaderFont->f); p.drawText((_width - (_headerWidth + _subheaderWidth)) / 2 + _headerWidth, st::aboutHeaderTop + st::aboutSubheaderFont->ascent, qsl("Desktop")); - - p.setFont(st::aboutVersionFont->f); - p.setPen(st::aboutVersionColor->p); - p.drawText((_width - _versionWidth) / 2, st::aboutVersionTop + st::aboutVersionFont->ascent, _versionText); } } else { p.setOpacity(a_opacity.current()); diff --git a/Telegram/SourceFiles/boxes/aboutbox.h b/Telegram/SourceFiles/boxes/aboutbox.h index 8e7c32523..58649da1a 100644 --- a/Telegram/SourceFiles/boxes/aboutbox.h +++ b/Telegram/SourceFiles/boxes/aboutbox.h @@ -43,12 +43,9 @@ private: int32 _width, _height; BottomButton _done; - FlatLabel _text; + FlatLabel _version, _text; int32 _headerWidth, _subheaderWidth; - QString _versionText; - int32 _versionWidth; - bool _hiding; QPixmap _cache; diff --git a/Telegram/SourceFiles/config.h b/Telegram/SourceFiles/config.h index bfa84d2c7..043acd435 100644 --- a/Telegram/SourceFiles/config.h +++ b/Telegram/SourceFiles/config.h @@ -17,8 +17,8 @@ Copyright (c) 2014 John Preston, https://tdesktop.com */ #pragma once -static const int32 AppVersion = 5008; -static const wchar_t *AppVersionStr = L"0.5.8"; +static const int32 AppVersion = 5009; +static const wchar_t *AppVersionStr = L"0.5.9"; #ifdef Q_OS_WIN static const wchar_t *AppName = L"Telegram Win (Unofficial)"; #else diff --git a/Telegram/SourceFiles/etc/qt.conf b/Telegram/SourceFiles/etc/qt_linux.conf similarity index 100% rename from Telegram/SourceFiles/etc/qt.conf rename to Telegram/SourceFiles/etc/qt_linux.conf diff --git a/Telegram/SourceFiles/etc/qt_win.conf b/Telegram/SourceFiles/etc/qt_win.conf new file mode 100644 index 000000000..f26ffe77f --- /dev/null +++ b/Telegram/SourceFiles/etc/qt_win.conf @@ -0,0 +1,2 @@ +[Platforms] +WindowsArguments = nomousefromtouch diff --git a/Telegram/SourceFiles/gui/flattextarea.cpp b/Telegram/SourceFiles/gui/flattextarea.cpp index 8383763dc..8a90845f4 100644 --- a/Telegram/SourceFiles/gui/flattextarea.cpp +++ b/Telegram/SourceFiles/gui/flattextarea.cpp @@ -446,8 +446,12 @@ void FlatTextarea::keyPressEvent(QKeyEvent *e) { emit submitted(); } else if (e->key() == Qt::Key_Escape) { emit cancelled(); - } else if (e->key() == Qt::Key_Tab) { - emit tabbed(); + } else if (e->key() == Qt::Key_Tab || ctrl && e->key() == Qt::Key_Backtab) { + if (ctrl) { + e->ignore(); + } else { + emit tabbed(); + } } else { QTextCursor tc(textCursor()); if (enter && ctrl) { diff --git a/Telegram/SourceFiles/gui/text.cpp b/Telegram/SourceFiles/gui/text.cpp index cd1058ac4..69089b667 100644 --- a/Telegram/SourceFiles/gui/text.cpp +++ b/Telegram/SourceFiles/gui/text.cpp @@ -112,6 +112,7 @@ namespace { } const QRegularExpression reDomain(QString::fromUtf8("(?|'\"\\[\\]\\{\\}`\\~\\!\\%\\^\\*\\(\\)\\-\\+=\\x10])#[A-Za-z_\\.0-9]{4,20}([\\s\\.,:;<>|'\"\\[\\]\\{\\}`\\~\\!\\%\\^\\*\\(\\)\\-\\+=\\x10]|$)")); @@ -315,12 +316,15 @@ public: } } QRegularExpressionMatch mDomain = reDomain.match(src, offset); + QRegularExpressionMatch mExplicitDomain = reExplicitDomain.match(src, offset); QRegularExpressionMatch mHashtag = reHashtag.match(src, offset); - if (!mDomain.hasMatch() && !mHashtag.hasMatch()) break; + if (!mDomain.hasMatch() && !mExplicitDomain.hasMatch() && !mHashtag.hasMatch()) break; LinkRange link; int32 domainOffset = mDomain.hasMatch() ? mDomain.capturedStart() : INT_MAX, domainEnd = mDomain.hasMatch() ? mDomain.capturedEnd() : INT_MAX, + explicitDomainOffset = mExplicitDomain.hasMatch() ? mExplicitDomain.capturedStart() : INT_MAX, + explicitDomainEnd = mExplicitDomain.hasMatch() ? mExplicitDomain.capturedEnd() : INT_MAX, hashtagOffset = mHashtag.hasMatch() ? mHashtag.capturedStart() : INT_MAX, hashtagEnd = mHashtag.hasMatch() ? mHashtag.capturedEnd() : INT_MAX; if (mHashtag.hasMatch()) { @@ -331,6 +335,11 @@ public: --hashtagEnd; } } + if (explicitDomainOffset < domainOffset) { + domainOffset = explicitDomainOffset; + domainEnd = explicitDomainEnd; + mDomain = mExplicitDomain; + } if (hashtagOffset < domainOffset) { if (hashtagOffset > nextCmd) { const QChar *after = skipCommand(srcData + nextCmd, srcData + len); @@ -355,7 +364,7 @@ public: QString topDomain = mDomain.captured(3).toLower(); bool isProtocolValid = protocol.isEmpty() || validProtocols.contains(hashCrc32(protocol.constData(), protocol.size() * sizeof(QChar))); - bool isTopDomainValid = validTopDomains.contains(hashCrc32(topDomain.constData(), topDomain.size() * sizeof(QChar))); + bool isTopDomainValid = !protocol.isEmpty() || validTopDomains.contains(hashCrc32(topDomain.constData(), topDomain.size() * sizeof(QChar))); if (!isProtocolValid || !isTopDomainValid) { offset = domainEnd; diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h index 86fa8f59d..152c27706 100644 --- a/Telegram/SourceFiles/history.h +++ b/Telegram/SourceFiles/history.h @@ -1043,7 +1043,7 @@ public: return _block; } void destroy() { - markRead(); + if (!out()) markRead(); bool wasAtBottom = history()->loadedAtBottom(); _history->removeNotification(this); detach(); diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 59561d859..d2835ddd6 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -1256,8 +1256,9 @@ void MessageField::focusInEvent(QFocusEvent *e) { } HistoryHider::HistoryHider(MainWidget *parent, bool forwardSelected) : QWidget(parent) - , sharedContact(0) + , _sharedContact(0) , _forwardSelected(forwardSelected) + , _sendPath(false) , forwardButton(this, lang(lng_forward), st::btnSelectDone) , cancelButton(this, lang(lng_cancel), st::btnSelectCancel) , offered(0) @@ -1268,21 +1269,14 @@ HistoryHider::HistoryHider(MainWidget *parent, bool forwardSelected) : QWidget(p , toTextWidth(0) , shadow(st::boxShadow) { - - connect(&forwardButton, SIGNAL(clicked()), this, SLOT(forward())); - connect(&cancelButton, SIGNAL(clicked()), this, SLOT(startHide())); - connect(App::wnd()->getTitle(), SIGNAL(hiderClicked()), this, SLOT(startHide())); - - _chooseWidth = st::forwardFont->m.width(lang(lng_forward_choose)); - - resizeEvent(0); - anim::start(this); + init(); } HistoryHider::HistoryHider(MainWidget *parent, UserData *sharedContact) : QWidget(parent) - , sharedContact(sharedContact) + , _sharedContact(sharedContact) , _forwardSelected(false) - , forwardButton(this, lang(lng_forward), st::btnSelectDone) + , _sendPath(false) + , forwardButton(this, lang(lng_forward_send), st::btnSelectDone) , cancelButton(this, lang(lng_cancel), st::btnSelectCancel) , offered(0) , aOpacity(0, 1) @@ -1292,7 +1286,27 @@ HistoryHider::HistoryHider(MainWidget *parent, UserData *sharedContact) : QWidge , toTextWidth(0) , shadow(st::boxShadow) { + init(); +} +HistoryHider::HistoryHider(MainWidget *parent) : QWidget(parent) +, _sharedContact(0) +, _forwardSelected(false) +, _sendPath(true) +, forwardButton(this, lang(lng_forward_send), st::btnSelectDone) +, cancelButton(this, lang(lng_cancel), st::btnSelectCancel) +, offered(0) +, aOpacity(0, 1) +, aOpacityFunc(anim::easeOutCirc) +, hiding(false) +, _forwardRequest(0) +, toTextWidth(0) +, shadow(st::boxShadow) +{ + init(); +} + +void HistoryHider::init() { connect(&forwardButton, SIGNAL(clicked()), this, SLOT(forward())); connect(&cancelButton, SIGNAL(clicked()), this, SLOT(startHide())); connect(App::wnd()->getTitle(), SIGNAL(hiderClicked()), this, SLOT(startHide())); @@ -1397,8 +1411,10 @@ void HistoryHider::forward() { if (_forwardRequest) return; if (!hiding && offered) { - if (sharedContact) { - parent()->onShareContact(offered->id, sharedContact); + if (_sharedContact) { + parent()->onShareContact(offered->id, _sharedContact); + } else if (_sendPath) { + parent()->onSendPaths(offered->id); } else { _forwardRequest = parent()->onForward(offered->id, _forwardSelected); } @@ -1434,7 +1450,24 @@ void HistoryHider::resizeEvent(QResizeEvent *e) { void HistoryHider::offerPeer(PeerId peer) { offered = App::peer(peer); - toText.setText(st::boxFont, lang(sharedContact ? lng_forward_share_contact : lng_forward_confirm).replace(qsl("{recipient}"), offered->chat ? '\xAB' + offered->name + '\xBB' : offered->name), _textNameOptions); + QString phrase; + if (_sharedContact) { + phrase = lang(lng_forward_share_contact); + } else if (_sendPath) { + if (cSendPaths().size() > 1) { + phrase = lang(lng_forward_send_files_confirm); + } else { + QString name(QFileInfo(cSendPaths().front()).fileName()); + if (name.size() > 10) { + name = name.mid(0, 8) + '.' + '.'; + } + phrase = lang(lng_forward_send_file_confirm).replace(qsl("{name}"), name); + } + } else { + phrase = lang(lng_forward_confirm); + } + + toText.setText(st::boxFont, phrase.replace(qsl("{recipient}"), offered->chat ? '\xAB' + offered->name + '\xBB' : offered->name), _textNameOptions); toTextWidth = toText.maxWidth(); if (toTextWidth > box.width() - st::boxPadding.left() - st::boxPadding.right()) { toTextWidth = box.width() - st::boxPadding.left() - st::boxPadding.right(); @@ -1450,6 +1483,7 @@ bool HistoryHider::wasOffered() const { } HistoryHider::~HistoryHider() { + if (_sendPath) cSetSendPaths(QStringList()); if (App::wnd()) App::wnd()->getTitle()->setHideLevel(0); parent()->noHider(this); } @@ -2242,6 +2276,13 @@ void HistoryWidget::onShareContact(const PeerId &peer, UserData *contact) { peerMessagesUpdated(); } +void HistoryWidget::onSendPaths(const PeerId &peer) { + App::main()->showPeer(peer, 0, false, true); + if (!hist) return; + + uploadMedias(cSendPaths(), ToPrepareDocument); +} + PeerData *HistoryWidget::peer() const { return histPeer; } @@ -2908,6 +2949,9 @@ void HistoryWidget::keyPressEvent(QKeyEvent *e) { _scroll.scrollToY(_scroll.scrollTop() + _scroll.height() / 10); } else if (e->key() == Qt::Key_Up) { _scroll.scrollToY(_scroll.scrollTop() - _scroll.height() / 10); + } else if ((e->key() == Qt::Key_Tab || e->key() == Qt::Key_Backtab) && (e->modifiers() & Qt::ControlModifier)) { + PeerData *p = ((e->modifiers() & Qt::ShiftModifier) || e->key() == Qt::Key_Backtab) ? App::main()->peerBefore(histPeer) : App::main()->peerAfter(histPeer); + if (p) App::main()->showPeer(p->id); } else { e->ignore(); } @@ -3028,10 +3072,12 @@ void HistoryWidget::updateTopBarSelection() { App::main()->topBar()->showSelected(_selCount > 0 ? _selCount : 0); updateControlsVisibility(); updateListSize(); - if (_selCount) { - _list->setFocus(); - } else { - _field.setFocus(); + if (!App::wnd()->layerShown()) { + if (_selCount) { + _list->setFocus(); + } else { + _field.setFocus(); + } } App::main()->topBar()->update(); update(); diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index 95ddf393e..968a530b2 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -192,8 +192,9 @@ class HistoryHider : public QWidget, public Animated { public: - HistoryHider(MainWidget *parent, bool forwardSelected); - HistoryHider(MainWidget *parent, UserData *sharedContact); + HistoryHider(MainWidget *parent, bool forwardSelected); // forward messages + HistoryHider(MainWidget *parent, UserData *sharedContact); // share contact + HistoryHider(MainWidget *parent); // send path from command line argument bool animStep(float64 ms); @@ -217,10 +218,11 @@ public slots: private: + void init(); MainWidget *parent(); - UserData *sharedContact; - bool _forwardSelected; + UserData *_sharedContact; + bool _forwardSelected, _sendPath; FlatButton forwardButton; FlatButton cancelButton; @@ -301,6 +303,7 @@ public: mtpRequestId onForward(const PeerId &peer, bool forwardSelected); void onShareContact(const PeerId &peer, UserData *contact); + void onSendPaths(const PeerId &peer); PeerData *peer() const; PeerData *activePeer() const; diff --git a/Telegram/SourceFiles/main.cpp b/Telegram/SourceFiles/main.cpp index f579b141c..e4595ee6e 100644 --- a/Telegram/SourceFiles/main.cpp +++ b/Telegram/SourceFiles/main.cpp @@ -41,7 +41,12 @@ int main(int argc, char *argv[]) { } DEBUG_LOG(("Application Info: Telegram started, test mode: %1, exe dir: %2").arg(logBool(cTestMode())).arg(cExeDir())); - if (cDebug()) LOG(("Application Info: Telegram started in debug mode")); + if (cDebug()) { + LOG(("Application Info: Telegram started in debug mode")); + for (int32 i = 0; i < argc; ++i) { + LOG(("Argument: %1").arg(QString::fromLocal8Bit(argv[i]))); + } + } DEBUG_LOG(("Application Info: ideal thread count: %1, using %2 connections per session").arg(QThread::idealThreadCount()).arg(cConnectionsInSession())); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index e889f294e..b9d3eb397 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -301,6 +301,10 @@ void MainWidget::onShareContact(const PeerId &peer, UserData *contact) { history.onShareContact(peer, contact); } +void MainWidget::onSendPaths(const PeerId &peer) { + history.onSendPaths(peer); +} + void MainWidget::noHider(HistoryHider *destroyed) { if (hider == destroyed) { hider = 0; @@ -1380,10 +1384,17 @@ void MainWidget::activate() { } else { dialogs.activate(); } - } else if (history.peer()) { - history.activate(); } else { - dialogs.activate(); + if (!cSendPaths().isEmpty()) { + hider = new HistoryHider(this); + hider->show(); + resizeEvent(0); + dialogs.activate(); + } else if (history.peer()) { + history.activate(); + } else { + dialogs.activate(); + } } } App::wnd()->fixOrder(); diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index d6a3dde9a..523dc9b50 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -159,6 +159,7 @@ public: void noHider(HistoryHider *destroyed); mtpRequestId onForward(const PeerId &peer, bool forwardSelected); void onShareContact(const PeerId &peer, UserData *contact); + void onSendPaths(const PeerId &peer); bool selectingPeer(); void offerPeer(PeerId peer); void hidePeerSelect(); diff --git a/Telegram/SourceFiles/mtproto/mtpFileLoader.cpp b/Telegram/SourceFiles/mtproto/mtpFileLoader.cpp index 6406dcd56..4c662d88e 100644 --- a/Telegram/SourceFiles/mtproto/mtpFileLoader.cpp +++ b/Telegram/SourceFiles/mtproto/mtpFileLoader.cpp @@ -167,7 +167,7 @@ void mtpFileLoader::partLoaded(int32 offset, const MTPupload_File &result) { } removeFromQueue(); App::wnd()->update(); - App::wnd()->notifyUpdateAll(); + App::wnd()->notifyUpdateAllPhotos(); } emit progress(this); } diff --git a/Telegram/SourceFiles/profilewidget.cpp b/Telegram/SourceFiles/profilewidget.cpp index faaadeb6a..b8f6e4aba 100644 --- a/Telegram/SourceFiles/profilewidget.cpp +++ b/Telegram/SourceFiles/profilewidget.cpp @@ -325,7 +325,7 @@ void ProfileInner::reorderParticipants() { } else { _participants.clear(); if (_peerUser) { - _onlineText = App::onlineText(_peerUser->onlineTill, t); + _onlineText = App::onlineText(_peerUser->onlineTill, t, true); } else { _onlineText = lang(lng_chat_no_members); } diff --git a/Telegram/SourceFiles/pspecific_linux.cpp b/Telegram/SourceFiles/pspecific_linux.cpp index 799fbdb9d..ce080255a 100644 --- a/Telegram/SourceFiles/pspecific_linux.cpp +++ b/Telegram/SourceFiles/pspecific_linux.cpp @@ -785,6 +785,7 @@ QString psCurrentExeDirectory(int argc, char *argv[]) { void psDoCleanup() { try { psAutoStart(false, true); + psSendToMenu(false, true); } catch (...) { } } @@ -991,3 +992,6 @@ void psExecTelegram() { void psAutoStart(bool start, bool silent) { } + +void psSendToMenu(bool send, bool silent) { +} diff --git a/Telegram/SourceFiles/pspecific_linux.h b/Telegram/SourceFiles/pspecific_linux.h index 496986d12..bf1adaa5f 100644 --- a/Telegram/SourceFiles/pspecific_linux.h +++ b/Telegram/SourceFiles/pspecific_linux.h @@ -166,6 +166,7 @@ QString psCurrentLanguage(); QString psAppDataPath(); QString psCurrentExeDirectory(int argc, char *argv[]); void psAutoStart(bool start, bool silent = false); +void psSendToMenu(bool send, bool silent = false); QRect psDesktopRect(); diff --git a/Telegram/SourceFiles/pspecific_mac.cpp b/Telegram/SourceFiles/pspecific_mac.cpp index 0b682a66d..d1d8e25f2 100644 --- a/Telegram/SourceFiles/pspecific_mac.cpp +++ b/Telegram/SourceFiles/pspecific_mac.cpp @@ -317,7 +317,10 @@ void PsMainWindow::psNotifyShown(NotifyWindow *w) { } void PsMainWindow::psPlatformNotify(HistoryItem *item) { - _private.showNotify(item->history()->peer->id, item->history()->peer->name, item->notificationHeader(), item->notificationText()); + QString title = (cNotifyView() <= dbinvShowName) ? item->history()->peer->name : lang(lng_notification_title); + QString subtitle = (cNotifyView() <= dbinvShowName) ? item->notificationHeader() : QString(); + QString msg = (cNotifyView() <= dbinvShowPreview) ? item->notificationText() : lang(lng_notification_preview); + _private.showNotify(item->history()->peer->id, title, subtitle, msg, (cNotifyView() <= dbinvShowPreview)); } PsApplication::PsApplication(int &argc, char **argv) : QApplication(argc, argv) { @@ -776,6 +779,7 @@ QString psCurrentExeDirectory(int argc, char *argv[]) { void psDoCleanup() { try { psAutoStart(false, true); + psSendToMenu(false, true); } catch (...) { } } @@ -888,3 +892,6 @@ void psExecTelegram() { void psAutoStart(bool start, bool silent) { } + +void psSendToMenu(bool send, bool silent) { +} diff --git a/Telegram/SourceFiles/pspecific_mac.h b/Telegram/SourceFiles/pspecific_mac.h index 3cfca22dc..08906c3bd 100644 --- a/Telegram/SourceFiles/pspecific_mac.h +++ b/Telegram/SourceFiles/pspecific_mac.h @@ -178,6 +178,7 @@ QString psCurrentLanguage(); QString psAppDataPath(); QString psCurrentExeDirectory(int argc, char *argv[]); void psAutoStart(bool start, bool silent = false); +void psSendToMenu(bool send, bool silent = false); QRect psDesktopRect(); diff --git a/Telegram/SourceFiles/pspecific_mac_p.h b/Telegram/SourceFiles/pspecific_mac_p.h index b11bfc561..4b6ec2dcc 100644 --- a/Telegram/SourceFiles/pspecific_mac_p.h +++ b/Telegram/SourceFiles/pspecific_mac_p.h @@ -30,7 +30,7 @@ public: void holdOnTop(WId winId); void showOverAll(WId winId); void activateWnd(WId winId); - void showNotify(uint64 peer, const QString &title, const QString &subtitle, const QString &msg); + void showNotify(uint64 peer, const QString &title, const QString &subtitle, const QString &msg, bool withReply); void clearNotifies(uint64 peer = 0); void enableShadow(WId winId); diff --git a/Telegram/SourceFiles/pspecific_mac_p.mm b/Telegram/SourceFiles/pspecific_mac_p.mm index 4b3daf1af..98a439f6b 100644 --- a/Telegram/SourceFiles/pspecific_mac_p.mm +++ b/Telegram/SourceFiles/pspecific_mac_p.mm @@ -175,7 +175,7 @@ void PsMacWindowPrivate::activateWnd(WId winId) { [wnd orderFront:wnd]; } -void PsMacWindowPrivate::showNotify(uint64 peer, const QString &title, const QString &subtitle, const QString &msg) { +void PsMacWindowPrivate::showNotify(uint64 peer, const QString &title, const QString &subtitle, const QString &msg, bool withReply) { NSUserNotification *notification = [[NSUserNotification alloc] init]; [notification setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedLongLong:peer],@"peer",[NSNumber numberWithUnsignedLongLong:cInstance()],@"inst",nil]]; @@ -184,7 +184,7 @@ void PsMacWindowPrivate::showNotify(uint64 peer, const QString &title, const QSt [notification setSubtitle:QNSString(subtitle).s()]; [notification setInformativeText:QNSString(msg).s()]; - [notification setHasReplyButton:YES]; + if (withReply) [notification setHasReplyButton:YES]; [notification setSoundName:nil]; diff --git a/Telegram/SourceFiles/pspecific_wnd.cpp b/Telegram/SourceFiles/pspecific_wnd.cpp index cdadb1832..e4561724e 100644 --- a/Telegram/SourceFiles/pspecific_wnd.cpp +++ b/Telegram/SourceFiles/pspecific_wnd.cpp @@ -2011,6 +2011,7 @@ QString psCurrentExeDirectory(int argc, char *argv[]) { void psDoCleanup() { try { psAutoStart(false, true); + psSendToMenu(false, true); } catch (...) { } } @@ -2217,32 +2218,32 @@ void psExecTelegram() { } } -void psAutoStart(bool start, bool silent) { +void _manageAppLnk(bool create, bool silent, int path_csidl, const wchar_t *args, const wchar_t *description) { WCHAR startupFolder[MAX_PATH]; - HRESULT hres = SHGetFolderPath(0, CSIDL_STARTUP, 0, SHGFP_TYPE_CURRENT, startupFolder); + HRESULT hres = SHGetFolderPath(0, path_csidl, 0, SHGFP_TYPE_CURRENT, startupFolder); if (SUCCEEDED(hres)) { - QString lnk = QString::fromWCharArray(startupFolder) + "\\Telegram.lnk"; - if (start) { - IShellLink* psl; - hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); - if (SUCCEEDED(hres)) { - IPersistFile* ppf; - + QString lnk = QString::fromWCharArray(startupFolder) + "\\Telegram.lnk"; + if (create) { + IShellLink* psl; + hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); + if (SUCCEEDED(hres)) { + IPersistFile* ppf; + QString exe = QDir::toNativeSeparators(QDir(cExeDir()).absolutePath() + "//Telegram.exe"), dir = QDir::toNativeSeparators(QDir(cWorkingDir()).absolutePath()); - psl->SetArguments(L"-autostart"); + psl->SetArguments(args); psl->SetPath(exe.toStdWString().c_str()); psl->SetWorkingDirectory(dir.toStdWString().c_str()); - psl->SetDescription(L"Telegram autorun link.\nYou can disable autorun in Telegram settings."); - - hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf); - - if (SUCCEEDED(hres)) { - hres = ppf->Save(lnk.toStdWString().c_str(), TRUE); - ppf->Release(); - } else { + psl->SetDescription(description); + + hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf); + + if (SUCCEEDED(hres)) { + hres = ppf->Save(lnk.toStdWString().c_str(), TRUE); + ppf->Release(); + } else { if (!silent) LOG(("App Error: could not create interface IID_IPersistFile %1").arg(hres)); } - psl->Release(); + psl->Release(); } else { if (!silent) LOG(("App Error: could not create instance of IID_IShellLink %1").arg(hres)); } @@ -2250,10 +2251,18 @@ void psAutoStart(bool start, bool silent) { QFile::remove(lnk); } } else { - if (!silent) LOG(("App Error: could not get CSIDL_STARTUP folder %1").arg(hres)); + if (!silent) LOG(("App Error: could not get CSIDL %1 folder %2").arg(path_csidl).arg(hres)); } } +void psAutoStart(bool start, bool silent) { + _manageAppLnk(start, silent, CSIDL_STARTUP, L"-autostart", L"Telegram autorun link.\nYou can disable autorun in Telegram settings."); +} + +void psSendToMenu(bool send, bool silent) { + _manageAppLnk(send, silent, CSIDL_SENDTO, L"-sendpath", L"Telegram send to link.\nYou can disable send to menu item in Telegram settings."); +} + #ifdef _NEED_WIN_GENERATE_DUMP static const WCHAR *_programName = L"Telegram Win (Unofficial)"; // folder in APPDATA, if current path is unavailable for writing static const WCHAR *_exeName = L"Telegram.exe"; diff --git a/Telegram/SourceFiles/pspecific_wnd.h b/Telegram/SourceFiles/pspecific_wnd.h index 5dfd4341f..7bb2a58a4 100644 --- a/Telegram/SourceFiles/pspecific_wnd.h +++ b/Telegram/SourceFiles/pspecific_wnd.h @@ -175,6 +175,7 @@ QString psCurrentLanguage(); QString psAppDataPath(); QString psCurrentExeDirectory(int argc, char *argv[]); void psAutoStart(bool start, bool silent = false); +void psSendToMenu(bool send, bool silent = false); QRect psDesktopRect(); diff --git a/Telegram/SourceFiles/settings.cpp b/Telegram/SourceFiles/settings.cpp index 98b2f290a..e70a3c25f 100644 --- a/Telegram/SourceFiles/settings.cpp +++ b/Telegram/SourceFiles/settings.cpp @@ -25,12 +25,16 @@ bool gManyInstance = false; QString gKeyFile; QString gWorkingDir, gExeDir; +QStringList gSendPaths; + QString gDialogLastPath, gDialogHelperPath; // optimize QFileDialog bool gSoundNotify = true; bool gDesktopNotify = true; +DBINotifyView gNotifyView = dbinvShowPreview; bool gStartMinimized = false; bool gAutoStart = false; +bool gSendToMenu = false; bool gAutoUpdate = true; TWindowPos gWindowPos; bool gFromAutoStart = false; @@ -107,7 +111,7 @@ void settingsParseArgs(int argc, char *argv[]) { } else if (string("-many") == argv[i]) { gManyInstance = true; } else if (string("-key") == argv[i] && i + 1 < argc) { - gKeyFile = QString(argv[i + 1]); + gKeyFile = QString::fromLocal8Bit(argv[++i]); } else if (string("-autostart") == argv[i]) { gFromAutoStart = true; } else if (string("-noupdate") == argv[i]) { @@ -115,7 +119,11 @@ void settingsParseArgs(int argc, char *argv[]) { } else if (string("-tosettings") == argv[i]) { gStartToSettings = true; } else if (string("-lang") == argv[i] && i + 1 < argc) { - gLangFile = QString(argv[i + 1]); + gLangFile = QString(argv[++i]); + } else if (string("-sendpath") == argv[i] && i + 1 < argc) { + for (++i; i < argc; ++i) { + gSendPaths.push_back(QString::fromLocal8Bit(argv[i])); + } } } } diff --git a/Telegram/SourceFiles/settings.h b/Telegram/SourceFiles/settings.h index 48572950f..ca1ffd73d 100644 --- a/Telegram/SourceFiles/settings.h +++ b/Telegram/SourceFiles/settings.h @@ -54,6 +54,7 @@ DeclareSetting(QString, LoggedPhoneNumber); DeclareReadSetting(uint32, ConnectionsInSession); DeclareSetting(bool, AutoStart); DeclareSetting(bool, StartMinimized); +DeclareSetting(bool, SendToMenu); DeclareReadSetting(bool, FromAutoStart); DeclareSetting(QString, WorkingDir); inline void cForceWorkingDir(const QString &newDir) { @@ -72,6 +73,7 @@ DeclareSetting(bool, CatsAndDogs); DeclareSetting(bool, SoundNotify); DeclareSetting(bool, NeedConfigResave); DeclareSetting(bool, DesktopNotify); +DeclareSetting(DBINotifyView, NotifyView); DeclareSetting(bool, AutoUpdate); struct TWindowPos { @@ -130,6 +132,8 @@ const RecentEmojiPack &cGetRecentEmojis(); DeclareReadSetting(QString, LangFile); +DeclareSetting(QStringList, SendPaths); + DeclareSetting(bool, Retina); DeclareSetting(float64, RetinaFactor); DeclareSetting(int32, IntRetinaFactor); diff --git a/Telegram/SourceFiles/settingswidget.cpp b/Telegram/SourceFiles/settingswidget.cpp index dd359d2ae..45bc5a81e 100644 --- a/Telegram/SourceFiles/settingswidget.cpp +++ b/Telegram/SourceFiles/settingswidget.cpp @@ -106,6 +106,8 @@ SettingsInner::SettingsInner(Settings *parent) : QWidget(parent), // 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), _soundNotify(this, lang(lng_settings_sound_notify), cSoundNotify()), // general @@ -118,6 +120,7 @@ SettingsInner::SettingsInner(Settings *parent) : QWidget(parent), _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, lang(lng_settings_scale_auto).replace(qsl("{cur}"), scaleLabel(cScreenScale())), (cConfigScale() == dbisAuto)), _dpiSlider(this, st::dpiSlider, dbisScaleCount - 1, cEvalScale(cConfigScale()) - 1), @@ -167,7 +170,11 @@ SettingsInner::SettingsInner(Settings *parent) : QWidget(parent), connect(App::app(), SIGNAL(peerPhotoFail(PeerId)), this, SLOT(onPhotoUpdateFail(PeerId))); // 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(&_soundNotify, SIGNAL(changed()), this, SLOT(onSoundNotify())); // general @@ -181,6 +188,7 @@ SettingsInner::SettingsInner(Settings *parent) : QWidget(parent), _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())); @@ -313,6 +321,8 @@ void SettingsInner::paintEvent(QPaintEvent *e) { top += st::setHeaderSkip; top += _desktopNotify.height() + st::setLittleSkip; + top += _senderName.height() + st::setLittleSkip; + top += _messagePreview.height() + st::setSectionSkip; top += _soundNotify.height(); } @@ -346,7 +356,9 @@ void SettingsInner::paintEvent(QPaintEvent *e) { top += _workmodeWindow.height() + st::setSectionSkip; top += _autoStart.height() + st::setLittleSkip; - top += _startMinimized.height(); + top += _startMinimized.height() + st::setSectionSkip; + + top += _sendToMenu.height(); } if (!cRetina()) { @@ -441,6 +453,8 @@ void SettingsInner::resizeEvent(QResizeEvent *e) { // 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; _soundNotify.move(_left, top); top += _soundNotify.height(); } @@ -456,7 +470,9 @@ void SettingsInner::resizeEvent(QResizeEvent *e) { _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(); + _startMinimized.move(_left, top); top += _startMinimized.height() + st::setSectionSkip; + + _sendToMenu.move(_left, top); top += _sendToMenu.height(); } if (!cRetina()) { top += st::setHeaderSkip; @@ -620,9 +636,13 @@ void SettingsInner::showAll() { // notifications if (_self) { _desktopNotify.show(); + _senderName.show(); + _messagePreview.show(); _soundNotify.show(); } else { _desktopNotify.hide(); + _senderName.hide(); + _messagePreview.hide(); _soundNotify.hide(); } @@ -635,13 +655,17 @@ void SettingsInner::showAll() { _autoStart.show(); _startMinimized.show(); + + _sendToMenu.show(); } else { _workmodeTray.hide(); _workmodeWindow.hide(); _autoStart.hide(); _startMinimized.hide(); - } + + _sendToMenu.show(); + } if (cRetina()) { _dpiSlider.hide(); _dpiAutoScale.hide(); @@ -843,6 +867,12 @@ void SettingsInner::onStartMinimized() { App::writeConfig(); } +void SettingsInner::onSendToMenu() { + cSetSendToMenu(_sendToMenu.checked()); + psSendToMenu(_sendToMenu.checked()); + App::writeConfig(); +} + void SettingsInner::onScaleAuto() { DBIScale newScale = _dpiAutoScale.checked() ? dbisAuto : cEvalScale(cConfigScale()); if (newScale == cScreenScale()) { @@ -905,8 +935,43 @@ void SettingsInner::onDesktopNotify() { cSetDesktopNotify(_desktopNotify.checked()); if (!_desktopNotify.checked()) { App::wnd()->notifyClear(); + _senderName.setDisabled(true); + _messagePreview.setDisabled(true); + App::writeUserConfig(); + } else { + _senderName.setDisabled(false); + _messagePreview.setDisabled(!_senderName.checked()); + App::writeUserConfig(); + } +} + +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); + } + App::writeUserConfig(); + App::wnd()->notifyUpdateAll(); + } +} + +void SettingsInner::onMessagePreview() { + if (_messagePreview.checked()) { + cSetNotifyView(dbinvShowPreview); + } else if (_senderName.checked()) { + cSetNotifyView(dbinvShowName); + } else { + cSetNotifyView(dbinvShowNothing); } App::writeUserConfig(); + App::wnd()->notifyUpdateAll(); } void SettingsInner::onReplaceEmojis() { diff --git a/Telegram/SourceFiles/settingswidget.h b/Telegram/SourceFiles/settingswidget.h index 1981bd170..64c114910 100644 --- a/Telegram/SourceFiles/settingswidget.h +++ b/Telegram/SourceFiles/settingswidget.h @@ -99,12 +99,15 @@ public slots: void onAutoStart(); void onStartMinimized(); + void onSendToMenu(); void onScaleAuto(); void onScaleChange(); void onSoundNotify(); void onDesktopNotify(); + void onSenderName(); + void onMessagePreview(); void onReplaceEmojis(); void onViewEmojis(); @@ -158,13 +161,13 @@ private: QString _errorText; // notifications - FlatCheckbox _desktopNotify, _soundNotify; + FlatCheckbox _desktopNotify, _senderName, _messagePreview, _soundNotify; // general FlatCheckbox _autoUpdate; LinkButton _checkNow, _restartNow; FlatCheckbox _workmodeTray, _workmodeWindow; - FlatCheckbox _autoStart, _startMinimized; + FlatCheckbox _autoStart, _startMinimized, _sendToMenu; FlatCheckbox _dpiAutoScale; Slider _dpiSlider; int32 _dpiWidth1, _dpiWidth2, _dpiWidth3, _dpiWidth4; diff --git a/Telegram/SourceFiles/telegram.qrc b/Telegram/SourceFiles/telegram.qrc index 025c2b665..74576d75f 100644 --- a/Telegram/SourceFiles/telegram.qrc +++ b/Telegram/SourceFiles/telegram.qrc @@ -37,4 +37,7 @@ qmime/freedesktop.org.xml + + etc/qt_win.conf + diff --git a/Telegram/SourceFiles/telegram_linux.qrc b/Telegram/SourceFiles/telegram_linux.qrc index e6ebb00de..ac5e08300 100644 --- a/Telegram/SourceFiles/telegram_linux.qrc +++ b/Telegram/SourceFiles/telegram_linux.qrc @@ -38,6 +38,6 @@ qmime/freedesktop.org.xml - etc/qt.conf + etc/qt_linux.conf diff --git a/Telegram/SourceFiles/types.h b/Telegram/SourceFiles/types.h index 501fd4883..71480ed46 100644 --- a/Telegram/SourceFiles/types.h +++ b/Telegram/SourceFiles/types.h @@ -212,6 +212,8 @@ enum DataBlockId { dbiLoggedPhoneNumber = 25, dbiMutedPeers = 26, // 27 reserved + dbiNotifyView = 28, + dbiSendToMenu = 29, dbiEncryptedWithSalt = 333, dbiEncrypted = 444, @@ -224,6 +226,12 @@ enum DBISendKey { dbiskCtrlEnter = 1, }; +enum DBINotifyView { + dbinvShowPreview = 0, + dbinvShowName = 1, + dbinvShowNothing = 2, +}; + enum DBIWorkMode { dbiwmWindowAndTray = 0, dbiwmTrayOnly = 1, diff --git a/Telegram/SourceFiles/window.cpp b/Telegram/SourceFiles/window.cpp index 3e383e113..480988511 100644 --- a/Telegram/SourceFiles/window.cpp +++ b/Telegram/SourceFiles/window.cpp @@ -77,7 +77,7 @@ void TempDirDeleter::onStart() { } -NotifyWindow::NotifyWindow(HistoryItem *item, int32 x, int32 y) : history(item->history()) +NotifyWindow::NotifyWindow(HistoryItem *item, int32 x, int32 y) : item(item), history(item->history()) #ifdef Q_OS_WIN , started(GetTickCount()) #endif @@ -90,52 +90,7 @@ NotifyWindow::NotifyWindow(HistoryItem *item, int32 x, int32 y) : history(item-> , aOpacityFunc(st::notifyFastAnimFunc) , aY(y + st::notifyHeight + st::notifyDeltaY) { - int32 w = st::notifyWidth, h = st::notifyHeight; - QImage img(w * cIntRetinaFactor(), h * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); - if (cRetina()) img.setDevicePixelRatio(cRetinaFactor()); - img.fill(st::notifyBG->c); - - { - QPainter p(&img); - p.fillRect(0, 0, w - st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder->b); - p.fillRect(w - st::notifyBorderWidth, 0, st::notifyBorderWidth, h - st::notifyBorderWidth, st::notifyBorder->b); - p.fillRect(st::notifyBorderWidth, h - st::notifyBorderWidth, w - st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder->b); - p.fillRect(0, st::notifyBorderWidth, st::notifyBorderWidth, h - st::notifyBorderWidth, st::notifyBorder->b); - - if (history->peer->photo->loaded()) { - p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), history->peer->photo->pix(st::notifyPhotoSize)); - } else { - MTP::clearLoaderPriorities(); - peerPhoto = history->peer->photo; - peerPhoto->load(true, true); - } - - int32 itemWidth = w - st::notifyPhotoPos.x() - st::notifyPhotoSize - st::notifyTextLeft - st::notifyClosePos.x() - st::notifyClose.width; - - QRect rectForName(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyTextTop, itemWidth, st::msgNameFont->height); - if (history->peer->chat) { - p.drawPixmap(QPoint(rectForName.left() + st::dlgChatImgLeft, rectForName.top() + st::dlgChatImgTop), App::sprite(), st::dlgChatImg); - rectForName.setLeft(rectForName.left() + st::dlgChatImgSkip); - } - - QDateTime now(QDateTime::currentDateTime()), lastTime(item->date); - QDate nowDate(now.date()), lastDate(lastTime.date()); - QString dt = lastTime.toString(qsl("hh:mm")); - int32 dtWidth = st::dlgHistFont->m.width(dt); - rectForName.setWidth(rectForName.width() - dtWidth - st::dlgDateSkip); - p.setFont(st::dlgDateFont->f); - p.setPen(st::dlgDateColor->p); - p.drawText(rectForName.left() + rectForName.width() + st::dlgDateSkip, rectForName.top() + st::dlgHistFont->ascent, dt); - - const HistoryItem *textCachedFor = 0; - Text itemTextCache(itemWidth); - bool active = false; - item->drawInDialog(p, QRect(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height, itemWidth, 2 * st::dlgFont->height), active, textCachedFor, itemTextCache); - - p.setPen(st::dlgNameColor->p); - history->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); - } - pm = QPixmap::fromImage(img); + updateNotifyDisplay(); hideTimer.setSingleShot(true); connect(&hideTimer, SIGNAL(timeout()), this, SLOT(hideByTimer())); @@ -145,7 +100,7 @@ NotifyWindow::NotifyWindow(HistoryItem *item, int32 x, int32 y) : history(item-> connect(&close, SIGNAL(clicked()), this, SLOT(unlinkHistory())); close.setAcceptBoth(true); - close.move(w - st::notifyClose.width - st::notifyClosePos.x(), st::notifyClosePos.y()); + close.move(st::notifyWidth - st::notifyClose.width - st::notifyClosePos.x(), st::notifyClosePos.y()); close.show(); aY.start(y); @@ -196,6 +151,78 @@ void NotifyWindow::moveTo(int32 x, int32 y, int32 index) { anim::start(this); } +void NotifyWindow::updateNotifyDisplay() { + if (!item) return; + + int32 w = st::notifyWidth, h = st::notifyHeight; + QImage img(w * cIntRetinaFactor(), h * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); + if (cRetina()) img.setDevicePixelRatio(cRetinaFactor()); + img.fill(st::notifyBG->c); + + { + QPainter p(&img); + p.fillRect(0, 0, w - st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder->b); + p.fillRect(w - st::notifyBorderWidth, 0, st::notifyBorderWidth, h - st::notifyBorderWidth, st::notifyBorder->b); + p.fillRect(st::notifyBorderWidth, h - st::notifyBorderWidth, w - st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder->b); + p.fillRect(0, st::notifyBorderWidth, st::notifyBorderWidth, h - st::notifyBorderWidth, st::notifyBorder->b); + + if (cNotifyView() <= dbinvShowName) { + if (history->peer->photo->loaded()) { + p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), history->peer->photo->pix(st::notifyPhotoSize)); + } else { + MTP::clearLoaderPriorities(); + peerPhoto = history->peer->photo; + peerPhoto->load(true, true); + } + } else { + static QPixmap icon = QPixmap::fromImage(App::wnd()->iconLarge().scaled(st::notifyPhotoSize, st::notifyPhotoSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), icon); + } + + int32 itemWidth = w - st::notifyPhotoPos.x() - st::notifyPhotoSize - st::notifyTextLeft - st::notifyClosePos.x() - st::notifyClose.width; + + QRect rectForName(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyTextTop, itemWidth, st::msgNameFont->height); + if (cNotifyView() <= dbinvShowName) { + if (history->peer->chat) { + p.drawPixmap(QPoint(rectForName.left() + st::dlgChatImgLeft, rectForName.top() + st::dlgChatImgTop), App::sprite(), st::dlgChatImg); + rectForName.setLeft(rectForName.left() + st::dlgChatImgSkip); + } + } + + QDateTime now(QDateTime::currentDateTime()), lastTime(item->date); + QDate nowDate(now.date()), lastDate(lastTime.date()); + QString dt = lastTime.toString(qsl("hh:mm")); + int32 dtWidth = st::dlgHistFont->m.width(dt); + rectForName.setWidth(rectForName.width() - dtWidth - st::dlgDateSkip); + p.setFont(st::dlgDateFont->f); + p.setPen(st::dlgDateColor->p); + p.drawText(rectForName.left() + rectForName.width() + st::dlgDateSkip, rectForName.top() + st::dlgHistFont->ascent, dt); + + if (cNotifyView() <= dbinvShowPreview) { + const HistoryItem *textCachedFor = 0; + Text itemTextCache(itemWidth); + bool active = false; + item->drawInDialog(p, QRect(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height, itemWidth, 2 * st::dlgFont->height), active, textCachedFor, itemTextCache); + } else { + static QString notifyText = st::dlgHistFont->m.elidedText(lang(lng_notification_preview), Qt::ElideRight, itemWidth); + p.setPen(st::dlgSystemColor->p); + p.drawText(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height + st::dlgHistFont->ascent, notifyText); + } + + p.setPen(st::dlgNameColor->p); + if (cNotifyView() <= dbinvShowName) { + history->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); + } else { + p.setFont(st::msgNameFont->f); + static QString notifyTitle = st::msgNameFont->m.elidedText(lang(lng_notification_title), Qt::ElideRight, rectForName.width()); + p.drawText(rectForName.left(), rectForName.top() + st::msgNameFont->ascent, notifyTitle); + } + } + + pm = QPixmap::fromImage(img); + update(); +} + void NotifyWindow::updatePeerPhoto() { if (!peerPhoto->isNull() && peerPhoto->loaded()) { QImage img(pm.toImage()); @@ -209,10 +236,17 @@ void NotifyWindow::updatePeerPhoto() { } } +void NotifyWindow::itemRemoved(HistoryItem *del) { + if (item == del) { + unlinkHistory(); + } +} + void NotifyWindow::unlinkHistory(History *hist) { if (!hist || hist == history) { animHide(st::notifyFastAnim, st::notifyFastAnimFunc); history = 0; + item = 0; App::wnd()->notifyShowNext(); } } @@ -559,10 +593,13 @@ void Window::hideLayer() { if (layerBG) { layerBG->onClose(); } + if (layer) { + layer->startHide(); + } } bool Window::layerShown() { - return !!layerBG || !!_topWidget; + return !!layer || !!layerBG || !!_topWidget; } bool Window::historyIsActive(int state) const { @@ -1118,6 +1155,14 @@ void Window::notifyShowNext(NotifyWindow *remove) { } } +void Window::notifyItemRemoved(HistoryItem *item) { + if (cCustomNotifies()) { + for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { + (*i)->itemRemoved(item); + } + } +} + void Window::notifyStopHiding() { if (cCustomNotifies()) { for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { @@ -1134,7 +1179,7 @@ void Window::notifyStartHiding() { } } -void Window::notifyUpdateAll() { +void Window::notifyUpdateAllPhotos() { if (cCustomNotifies()) { for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { (*i)->updatePeerPhoto(); @@ -1142,6 +1187,15 @@ void Window::notifyUpdateAll() { } } +void Window::notifyUpdateAll() { + if (cCustomNotifies()) { + for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { + (*i)->updateNotifyDisplay(); + } + } + psClearNotifies(); +} + void Window::notifyActivateAll() { if (cCustomNotifies()) { for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { @@ -1150,6 +1204,23 @@ void Window::notifyActivateAll() { } } +QImage Window::iconLarge() const { + return icon256; +} + +void Window::sendPaths() { + if (settings) { + hideSettings(); + } else { + if (layerShown()) { + hideLayer(); + } + if (main && !main->animating()) { + main->activate(); + } + } +} + Window::~Window() { notifyClearFast(); delete _tempDeleter; diff --git a/Telegram/SourceFiles/window.h b/Telegram/SourceFiles/window.h index 395219ceb..b4989db4a 100644 --- a/Telegram/SourceFiles/window.h +++ b/Telegram/SourceFiles/window.h @@ -85,8 +85,11 @@ public: void stopHiding(); void moveTo(int32 x, int32 y, int32 index = -1); + void updateNotifyDisplay(); void updatePeerPhoto(); + void itemRemoved(HistoryItem *del); + int32 index() const { return history ? _index : -1; } @@ -106,6 +109,7 @@ private: DWORD started; #endif History *history; + HistoryItem *item; IconedButton close; QPixmap pm; float64 alphaDuration, posDuration; @@ -210,11 +214,17 @@ public: void notifyClear(History *history = 0); void notifyClearFast(); void notifyShowNext(NotifyWindow *remove = 0); + void notifyItemRemoved(HistoryItem *item); void notifyStopHiding(); void notifyStartHiding(); + void notifyUpdateAllPhotos(); void notifyUpdateAll(); void notifyActivateAll(); + QImage iconLarge() const; + + void sendPaths(); + public slots: void checkHistoryActivation(int state = -1); diff --git a/Telegram/Telegram.plist b/Telegram/Telegram.plist index 3ff431313..41727d8f2 100644 --- a/Telegram/Telegram.plist +++ b/Telegram/Telegram.plist @@ -11,7 +11,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.5.8 + 0.5.9 CFBundleSignature ???? NOTE diff --git a/Telegram/Telegram.rc b/Telegram/Telegram.rc index 8e0c995ce..4e67d78c9 100644 Binary files a/Telegram/Telegram.rc and b/Telegram/Telegram.rc differ diff --git a/Telegram/Telegram.xcodeproj/project.pbxproj b/Telegram/Telegram.xcodeproj/project.pbxproj index 54848de0e..7af6996f4 100644 --- a/Telegram/Telegram.xcodeproj/project.pbxproj +++ b/Telegram/Telegram.xcodeproj/project.pbxproj @@ -1453,7 +1453,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.5.8; + CURRENT_PROJECT_VERSION = 0.5.9; DEBUG_INFORMATION_FORMAT = dwarf; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; @@ -1471,7 +1471,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 0.5.8; + CURRENT_PROJECT_VERSION = 0.5.9; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_OPTIMIZATION_LEVEL = fast; GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h; @@ -1495,9 +1495,9 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 0.5.8; + CURRENT_PROJECT_VERSION = 0.5.9; DYLIB_COMPATIBILITY_VERSION = 0.5; - DYLIB_CURRENT_VERSION = 0.5.8; + DYLIB_CURRENT_VERSION = 0.5.9; FRAMEWORK_SEARCH_PATHS = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_OPTIMIZATION_LEVEL = fast; @@ -1620,10 +1620,10 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.5.8; + CURRENT_PROJECT_VERSION = 0.5.9; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 0.5; - DYLIB_CURRENT_VERSION = 0.5.8; + DYLIB_CURRENT_VERSION = 0.5.9; FRAMEWORK_SEARCH_PATHS = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0;