diff --git a/CMakeLists.txt b/CMakeLists.txt index c8225654e8e483..abea2aaf4e766a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,9 +60,9 @@ include(cmake/options.cmake) if (NOT DESKTOP_APP_USE_PACKAGED) if (WIN32) - set(qt_version 5.15.11) + set(qt_version 5.15.12) elseif (APPLE) - set(qt_version 6.2.6) + set(qt_version 6.2.7) endif() endif() include(cmake/external/qt/package.cmake) diff --git a/Telegram/Resources/icons/win_quit.png b/Telegram/Resources/icons/win_quit.png new file mode 100644 index 00000000000000..a823f133e81b47 Binary files /dev/null and b/Telegram/Resources/icons/win_quit.png differ diff --git a/Telegram/Resources/icons/win_quit@2x.png b/Telegram/Resources/icons/win_quit@2x.png new file mode 100644 index 00000000000000..569097eda9395b Binary files /dev/null and b/Telegram/Resources/icons/win_quit@2x.png differ diff --git a/Telegram/Resources/icons/win_quit@3x.png b/Telegram/Resources/icons/win_quit@3x.png new file mode 100644 index 00000000000000..c11e92bb2a5a99 Binary files /dev/null and b/Telegram/Resources/icons/win_quit@3x.png differ diff --git a/Telegram/Resources/uwp/AppX/AppxManifest.xml b/Telegram/Resources/uwp/AppX/AppxManifest.xml index 6dee69ef629934..bc517dc13f9c29 100644 --- a/Telegram/Resources/uwp/AppX/AppxManifest.xml +++ b/Telegram/Resources/uwp/AppX/AppxManifest.xml @@ -10,7 +10,7 @@ + Version="4.14.3.0" /> Telegram Desktop Telegram Messenger LLP diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index 313110e375fa22..94d6da5383ad25 100644 --- a/Telegram/Resources/winrc/Telegram.rc +++ b/Telegram/Resources/winrc/Telegram.rc @@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 4,14,2,0 - PRODUCTVERSION 4,14,2,0 + FILEVERSION 4,14,3,0 + PRODUCTVERSION 4,14,3,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -62,10 +62,10 @@ BEGIN BEGIN VALUE "CompanyName", "" VALUE "FileDescription", "Telegram Desktop" - VALUE "FileVersion", "4.14.2.0" + VALUE "FileVersion", "4.14.3.0" VALUE "LegalCopyright", "Copyright (C) 2014-2024" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "4.14.2.0" + VALUE "ProductVersion", "4.14.3.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc index c5e60cfee912cb..493495f3bebc38 100644 --- a/Telegram/Resources/winrc/Updater.rc +++ b/Telegram/Resources/winrc/Updater.rc @@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 4,14,2,0 - PRODUCTVERSION 4,14,2,0 + FILEVERSION 4,14,3,0 + PRODUCTVERSION 4,14,3,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -53,10 +53,10 @@ BEGIN BEGIN VALUE "CompanyName", "" VALUE "FileDescription", "Telegram Desktop Updater" - VALUE "FileVersion", "4.14.2.0" + VALUE "FileVersion", "4.14.3.0" VALUE "LegalCopyright", "Copyright (C) 2014-2024" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "4.14.2.0" + VALUE "ProductVersion", "4.14.3.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/api/api_common.h b/Telegram/SourceFiles/api/api_common.h index c8284114255225..155666a5d4ee69 100644 --- a/Telegram/SourceFiles/api/api_common.h +++ b/Telegram/SourceFiles/api/api_common.h @@ -25,6 +25,7 @@ struct SendOptions { bool silent = false; bool handleSupportSwitch = false; bool hideViaBot = false; + crl::time ttlSeconds = 0; }; [[nodiscard]] SendOptions DefaultSendWhenOnlineOptions(); diff --git a/Telegram/SourceFiles/api/api_media.cpp b/Telegram/SourceFiles/api/api_media.cpp index ec8c1e4b26d1f5..a76cb4b67586fa 100644 --- a/Telegram/SourceFiles/api/api_media.cpp +++ b/Telegram/SourceFiles/api/api_media.cpp @@ -79,16 +79,19 @@ MTPInputMedia PrepareUploadedPhoto( not_null item, RemoteFileInfo info) { using Flag = MTPDinputMediaUploadedPhoto::Flag; - const auto spoiler = item->media() - && item->media()->hasSpoiler(); + const auto spoiler = item->media() && item->media()->hasSpoiler(); + const auto ttlSeconds = item->media() + ? item->media()->ttlSeconds() + : 0; const auto flags = (spoiler ? Flag::f_spoiler : Flag()) - | (info.attachedStickers.empty() ? Flag() : Flag::f_stickers); + | (info.attachedStickers.empty() ? Flag() : Flag::f_stickers) + | (ttlSeconds ? Flag::f_ttl_seconds : Flag()); return MTP_inputMediaUploadedPhoto( MTP_flags(flags), info.file, MTP_vector( ranges::to>(info.attachedStickers)), - MTP_int(0)); + MTP_int(ttlSeconds)); } MTPInputMedia PrepareUploadedDocument( @@ -98,12 +101,15 @@ MTPInputMedia PrepareUploadedDocument( return MTP_inputMediaEmpty(); } using Flag = MTPDinputMediaUploadedDocument::Flag; - const auto spoiler = item->media() - && item->media()->hasSpoiler(); + const auto spoiler = item->media() && item->media()->hasSpoiler(); + const auto ttlSeconds = item->media() + ? item->media()->ttlSeconds() + : 0; const auto flags = (spoiler ? Flag::f_spoiler : Flag()) | (info.thumb ? Flag::f_thumb : Flag()) | (item->groupId() ? Flag::f_nosound_video : Flag()) - | (info.attachedStickers.empty() ? Flag::f_stickers : Flag()); + | (info.attachedStickers.empty() ? Flag::f_stickers : Flag()) + | (ttlSeconds ? Flag::f_ttl_seconds : Flag()); const auto document = item->media()->document(); return MTP_inputMediaUploadedDocument( MTP_flags(flags), @@ -113,7 +119,7 @@ MTPInputMedia PrepareUploadedDocument( ComposeSendingDocumentAttributes(document), MTP_vector( ranges::to>(info.attachedStickers)), - MTP_int(0)); + MTP_int(ttlSeconds)); } bool HasAttachedStickers(MTPInputMedia media) { diff --git a/Telegram/SourceFiles/api/api_sending.cpp b/Telegram/SourceFiles/api/api_sending.cpp index 3aa4d26247cafe..f3bdde2496b06f 100644 --- a/Telegram/SourceFiles/api/api_sending.cpp +++ b/Telegram/SourceFiles/api/api_sending.cpp @@ -42,6 +42,9 @@ void InnerFillMessagePostFlags( not_null peer, MessageFlags &flags) { const auto anonymousPost = peer->amAnonymous(); + if (ShouldSendSilent(peer, options)) { + flags |= MessageFlag::Silent; + } if (!anonymousPost || options.sendAs) { flags |= MessageFlag::HasFromId; return; @@ -442,9 +445,6 @@ void SendConfirmedFile( const auto anonymousPost = peer->amAnonymous(); const auto silentPost = ShouldSendSilent(peer, file->to.options); FillMessagePostFlags(action, peer, flags); - if (silentPost) { - flags |= MessageFlag::Silent; - } if (file->to.options.scheduled) { flags |= MessageFlag::IsOrWasScheduled; @@ -484,11 +484,30 @@ void SendConfirmedFile( MTPDocument(), // alt_document MTPint()); } else if (file->type == SendMediaType::Audio) { + const auto ttlSeconds = file->to.options.ttlSeconds; + const auto isVoice = [&] { + return file->document.match([](const MTPDdocumentEmpty &d) { + return false; + }, [](const MTPDdocument &d) { + return ranges::any_of(d.vattributes().v, [&]( + const MTPDocumentAttribute &attribute) { + using Att = MTPDdocumentAttributeAudio; + return attribute.match([](const Att &data) -> bool { + return data.vflags().v & Att::Flag::f_voice; + }, [](const auto &) { + return false; + }); + }); + }); + }(); + using Flag = MTPDmessageMediaDocument::Flag; return MTP_messageMediaDocument( - MTP_flags(MTPDmessageMediaDocument::Flag::f_document), + MTP_flags(Flag::f_document + | (isVoice ? Flag::f_voice : Flag()) + | (ttlSeconds ? Flag::f_ttl_seconds : Flag())), file->document, MTPDocument(), // alt_document - MTPint()); + MTP_int(ttlSeconds)); } else { Unexpected("Type in sendFilesConfirmed."); } diff --git a/Telegram/SourceFiles/boxes/premium_limits_box.cpp b/Telegram/SourceFiles/boxes/premium_limits_box.cpp index 60eb5ecde36867..ad8d313df0e46e 100644 --- a/Telegram/SourceFiles/boxes/premium_limits_box.cpp +++ b/Telegram/SourceFiles/boxes/premium_limits_box.cpp @@ -68,6 +68,8 @@ class InactiveController final : public PeerListController { void prepare() override; void rowClicked(not_null row) override; + [[nodiscard]] rpl::producer countValue() const; + private: void appendRow(not_null peer, TimeId date); [[nodiscard]] std::unique_ptr createRow( @@ -75,6 +77,7 @@ class InactiveController final : public PeerListController { TimeId date) const; const not_null _session; + rpl::variable _count; mtpRequestId _requestId = 0; }; @@ -91,12 +94,15 @@ class PublicsController final : public PeerListController { void rowClicked(not_null row) override; void rowRightActionClicked(not_null row) override; + [[nodiscard]] rpl::producer countValue() const; + private: void appendRow(not_null peer); [[nodiscard]] std::unique_ptr createRow( not_null peer) const; const not_null _navigation; + rpl::variable _count; Fn _closeBox; mtpRequestId _requestId = 0; @@ -210,17 +216,17 @@ void InactiveController::prepare() { _requestId = _session->api().request(MTPchannels_GetInactiveChannels( )).done([=](const MTPmessages_InactiveChats &result) { _requestId = 0; - result.match([&](const MTPDmessages_inactiveChats &data) { - _session->data().processUsers(data.vusers()); - const auto &list = data.vchats().v; - const auto &dates = data.vdates().v; - for (auto i = 0, count = int(list.size()); i != count; ++i) { - const auto peer = _session->data().processChat(list[i]); - const auto date = (i < dates.size()) ? dates[i].v : TimeId(); - appendRow(peer, date); - } - delegate()->peerListRefreshRows(); - }); + const auto &data = result.data(); + _session->data().processUsers(data.vusers()); + const auto &list = data.vchats().v; + const auto &dates = data.vdates().v; + for (auto i = 0, count = int(list.size()); i != count; ++i) { + const auto peer = _session->data().processChat(list[i]); + const auto date = (i < dates.size()) ? dates[i].v : TimeId(); + appendRow(peer, date); + } + delegate()->peerListRefreshRows(); + _count = delegate()->peerListFullRowsCount(); }).send(); } @@ -228,6 +234,10 @@ void InactiveController::rowClicked(not_null row) { delegate()->peerListSetRowChecked(row, !row->checked()); } +rpl::producer InactiveController::countValue() const { + return _count.value(); +} + void InactiveController::appendRow( not_null participant, TimeId date) { @@ -296,6 +306,10 @@ Main::Session &PublicsController::session() const { return _navigation->session(); } +rpl::producer PublicsController::countValue() const { + return _count.value(); +} + void PublicsController::prepare() { _requestId = _navigation->session().api().request( MTPchannels_GetAdminedPublicChannels(MTP_flags(0)) @@ -315,6 +329,7 @@ void PublicsController::prepare() { } delegate()->peerListRefreshRows(); } + _count = delegate()->peerListFullRowsCount(); }).send(); } @@ -571,7 +586,7 @@ void ChannelsLimitBox( {}); using namespace rpl::mappers; - content->heightValue( + controller->countValue( ) | rpl::filter(_1 > 0) | rpl::start_with_next([=] { delete placeholder; }, placeholder->lifetime()); @@ -662,7 +677,7 @@ void PublicLinksLimitBox( {}); using namespace rpl::mappers; - content->heightValue( + controller->countValue( ) | rpl::filter(_1 > 0) | rpl::start_with_next([=] { delete placeholder; }, placeholder->lifetime()); diff --git a/Telegram/SourceFiles/chat_helpers/chat_helpers.style b/Telegram/SourceFiles/chat_helpers/chat_helpers.style index 7a323faeeb2841..c86e98b759851a 100644 --- a/Telegram/SourceFiles/chat_helpers/chat_helpers.style +++ b/Telegram/SourceFiles/chat_helpers/chat_helpers.style @@ -1072,6 +1072,7 @@ historyRecordCancelActive: windowActiveTextFg; historyRecordFont: font(13px); historyRecordDurationSkip: 12px; historyRecordDurationFg: historyComposeAreaFg; +historyRecordTTLLineWidth: 2px; historyRecordMainBlobMinRadius: 23px; historyRecordMainBlobMaxRadius: 37px; diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index f78b93d84def62..452f60cf744bfb 100644 --- a/Telegram/SourceFiles/core/version.h +++ b/Telegram/SourceFiles/core/version.h @@ -24,7 +24,7 @@ constexpr auto AppId = "{53F49750-6209-4FBF-9CA8-7A333C87D1ED}"_cs; constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs; constexpr auto AppName = "Telegram Desktop"_cs; constexpr auto AppFile = "Telegram"_cs; -constexpr auto AppVersion = 4014002; -constexpr auto AppVersionStr = "4.14.2"; +constexpr auto AppVersion = 4014003; +constexpr auto AppVersionStr = "4.14.3"; constexpr auto AppBetaVersion = false; constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION; diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp index 32ff4be7575b82..e5b1f5be67ff5f 100644 --- a/Telegram/SourceFiles/data/data_document.cpp +++ b/Telegram/SourceFiles/data/data_document.cpp @@ -48,6 +48,8 @@ namespace { constexpr auto kDefaultCoverThumbnailSize = 100; constexpr auto kMaxAllowedPreloadPrefix = 6 * 1024 * 1024; +constexpr auto kDefaultWebmEmojiSize = 100; +constexpr auto kDefaultWebmStickerLargerSize = kStickerSideSize; const auto kLottieStickerDimensions = QSize( kStickerSideSize, @@ -430,6 +432,42 @@ void DocumentData::setattributes( _flags |= Flag::HasAttachedStickers; }); } + + // Any "video/webm" file is treated as a video-sticker. + if (hasMimeType(u"video/webm"_q)) { + if (type == FileDocument) { + type = StickerDocument; + _additional = std::make_unique(); + } + if (type == StickerDocument) { + sticker()->type = StickerType::Webm; + } + } + + // If "video/webm" sticker without dimensions we set them to default. + if (const auto info = sticker(); info + && info->set + && info->type == StickerType::Webm + && dimensions.isEmpty()) { + if (info->setType == Data::StickersType::Emoji) { + // Always fixed. + dimensions = { kDefaultWebmEmojiSize, kDefaultWebmEmojiSize }; + } else if (info->setType == Data::StickersType::Stickers) { + // May have aspect != 1, so we count it from the thumbnail. + const auto thumbnail = QSize( + _thumbnail.location.width(), + _thumbnail.location.height() + ).scaled( + kDefaultWebmStickerLargerSize, + kDefaultWebmStickerLargerSize, + Qt::KeepAspectRatio); + if (!thumbnail.isEmpty()) { + dimensions = thumbnail; + } + } + } + + // Check sticker size/dimensions properties (for sticker of any type). if (type == StickerDocument && ((size > Storage::kMaxStickerBytesSize) || (!sticker()->isLottie() @@ -438,14 +476,8 @@ void DocumentData::setattributes( dimensions.height())))) { type = FileDocument; _additional = nullptr; - } else if (type == FileDocument - && hasMimeType(u"video/webm"_q) - && (size < Storage::kMaxStickerBytesSize) - && GoodStickerDimensions(dimensions.width(), dimensions.height())) { - type = StickerDocument; - _additional = std::make_unique(); - sticker()->type = StickerType::Webm; } + if (isAudioFile() || isAnimation() || isVoiceMessage() @@ -483,8 +515,7 @@ bool DocumentData::checkWallPaperProperties() { } if (type != FileDocument || !hasThumbnail() - || !dimensions.width() - || !dimensions.height() + || dimensions.isEmpty() || dimensions.width() > Storage::kMaxWallPaperDimension || dimensions.height() > Storage::kMaxWallPaperDimension || size > Storage::kMaxWallPaperInMemory) { diff --git a/Telegram/SourceFiles/data/data_document_resolver.cpp b/Telegram/SourceFiles/data/data_document_resolver.cpp index 05d23ecdf2d761..2c34719ff3140b 100644 --- a/Telegram/SourceFiles/data/data_document_resolver.cpp +++ b/Telegram/SourceFiles/data/data_document_resolver.cpp @@ -267,17 +267,18 @@ void ResolveDocument( return false; } const auto &location = document->location(true); + const auto mime = u"image/"_q; if (!location.isEmpty() && location.accessEnable()) { const auto guard = gsl::finally([&] { location.accessDisable(); }); const auto path = location.name(); - if (Core::MimeTypeForFile(QFileInfo(path)).name().startsWith("image/") + if (Core::MimeTypeForFile(QFileInfo(path)).name().startsWith(mime) && QImageReader(path).canRead()) { showDocument(); return true; } - } else if (document->mimeString().startsWith("image/") + } else if (document->mimeString().startsWith(mime) && !media->bytes().isEmpty()) { auto bytes = media->bytes(); auto buffer = QBuffer(&bytes); diff --git a/Telegram/SourceFiles/data/data_saved_messages.cpp b/Telegram/SourceFiles/data/data_saved_messages.cpp index 695622bbe2996b..66bc87609b5f2b 100644 --- a/Telegram/SourceFiles/data/data_saved_messages.cpp +++ b/Telegram/SourceFiles/data/data_saved_messages.cpp @@ -233,8 +233,10 @@ void SavedMessages::apply( _chatsList.setLoaded(); } else if (result.type() == mtpc_messages_savedDialogs) { _chatsList.setLoaded(); - } else if (offsetDate < _offsetDate - || (offsetDate == _offsetDate && offsetId == _offsetId && offsetPeer == _offsetPeer)) { + } else if ((_offsetDate > 0 && offsetDate > _offsetDate) + || (offsetDate == _offsetDate + && offsetId == _offsetId + && offsetPeer == _offsetPeer)) { LOG(("API Error: Bad order in messages.savedDialogs.")); _chatsList.setLoaded(); } else { diff --git a/Telegram/SourceFiles/data/stickers/data_custom_emoji.cpp b/Telegram/SourceFiles/data/stickers/data_custom_emoji.cpp index 1f80c53f636a26..5b271b5b629133 100644 --- a/Telegram/SourceFiles/data/stickers/data_custom_emoji.cpp +++ b/Telegram/SourceFiles/data/stickers/data_custom_emoji.cpp @@ -414,7 +414,7 @@ Ui::CustomEmoji::Preview CustomEmojiLoader::preview() { const auto make = [&](not_null document) -> Preview { const auto dimensions = document->dimensions; if (!document->inlineThumbnailIsPath() - || !dimensions.width()) { + || dimensions.isEmpty()) { return {}; } const auto scale = (FrameSizeFromTag(_tag, _sizeOverride) * 1.) diff --git a/Telegram/SourceFiles/dialogs/dialogs_row.cpp b/Telegram/SourceFiles/dialogs/dialogs_row.cpp index 54247193cdee68..29f84995615aa5 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_row.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_row.cpp @@ -86,7 +86,7 @@ constexpr auto kBlurRadius = 24; q.drawArc(innerRect, arc::kQuarterLength, arc::kHalfLength); q.setClipRect(innerRect - - QMargins(innerRect.width() / 2, 0, -penWidth, -penWidth)); + - QMargins(innerRect.width() / 2, -penWidth, -penWidth, -penWidth)); pen.setStyle(Qt::DotLine); q.setPen(pen); q.drawEllipse(innerRect); diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 99e3bd6cd38322..bf4187aea65de2 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -2354,7 +2354,9 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { showContextInFolder(document); }, &st::menuIconShowInFolder); } - if (item && !hasCopyMediaRestriction(item)) { + if (item + && !hasCopyMediaRestriction(item) + && !HistoryView::ItemHasTtl(item)) { HistoryView::AddSaveSoundForNotifications( _menu, item, diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 06e30559201515..232b2b6598d980 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -969,6 +969,16 @@ void HistoryWidget::initVoiceRecordBar() { } return false; }); + _voiceRecordBar->setTTLFilter([=] { + if (const auto peer = _history ? _history->peer.get() : nullptr) { + if (const auto user = peer->asUser()) { + if (!user->isSelf() && !user->isBot()) { + return true; + } + } + } + return false; + }); const auto applyLocalDraft = [=] { if (_history && _history->localDraft({})) { @@ -6369,7 +6379,9 @@ void HistoryWidget::mousePressEvent(QMouseEvent *e) { } else { _forwardPanel->editOptions(controller()->uiShow()); } - } else if (_replyTo && (e->modifiers() & Qt::ControlModifier)) { + } else if (_replyTo + && ((e->modifiers() & Qt::ControlModifier) + || (e->button() != Qt::LeftButton))) { jumpToReply(_replyTo); } else if (_replyTo) { editDraftOptions(); diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp index 73a0a198b0591a..41066d6f937a87 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp @@ -386,6 +386,10 @@ void FieldHeader::init() { } else if (reply) { _editOptionsRequests.fire({}); } + } else if (!isLeftButton) { + if (const auto reply = replyingToMessage()) { + _jumpToItemRequests.fire_copy(reply); + } } } }, lifetime()); diff --git a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp index 3f507ca61bc0b1..d878583eb56e8b 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp @@ -32,6 +32,7 @@ For license and copyright information please follow this link: #include "ui/effects/ripple_animation.h" #include "ui/text/format_values.h" #include "ui/painter.h" +#include "ui/rect.h" #include "styles/style_chat.h" #include "styles/style_chat_helpers.h" #include "styles/style_layers.h" @@ -198,6 +199,181 @@ void PaintWaveform( } } +[[nodiscard]] QRect DrawLockCircle( + QPainter &p, + const QRect &widgetRect, + const style::RecordBarLock &st, + float64 progress) { + const auto &originTop = st.originTop; + const auto &originBottom = st.originBottom; + const auto &originBody = st.originBody; + const auto &shadowTop = st.shadowTop; + const auto &shadowBottom = st.shadowBottom; + const auto &shadowBody = st.shadowBody; + const auto &shadowMargins = st::historyRecordLockMargin; + + const auto bottomMargin = anim::interpolate( + 0, + widgetRect.height() - shadowTop.height() - shadowBottom.height(), + progress); + + const auto topMargin = anim::interpolate( + widgetRect.height() / 4, + 0, + progress); + + const auto full = widgetRect - QMargins(0, topMargin, 0, bottomMargin); + const auto inner = full - shadowMargins; + const auto content = inner + - style::margins(0, originTop.height(), 0, originBottom.height()); + const auto contentShadow = full + - style::margins(0, shadowTop.height(), 0, shadowBottom.height()); + + const auto w = full.width(); + { + shadowTop.paint(p, full.topLeft(), w); + originTop.paint(p, inner.topLeft(), w); + } + { + const auto shadowPos = QPoint( + full.x(), + contentShadow.y() + contentShadow.height()); + const auto originPos = QPoint( + inner.x(), + content.y() + content.height()); + shadowBottom.paint(p, shadowPos, w); + originBottom.paint(p, originPos, w); + } + { + shadowBody.fill(p, contentShadow); + originBody.fill(p, content); + } + if (progress < 1.) { + const auto &arrow = st.arrow; + const auto arrowRect = QRect( + inner.x(), + content.y() + content.height() - arrow.height() / 2, + inner.width(), + arrow.height()); + p.setOpacity(1. - progress); + arrow.paintInCenter(p, arrowRect); + p.setOpacity(1.); + } + + return inner; +} + +class TTLButton final : public Ui::RippleButton { +public: + TTLButton( + not_null parent, + const style::RecordBar &st); + + void clearState() override; + +protected: + QImage prepareRippleMask() const override; + QPoint prepareRippleStartPosition() const override; + +private: + const style::RecordBar &_st; + const QRect _rippleRect; + const QString _text; + + Ui::Animations::Simple _activeAnimation; + +}; + +TTLButton::TTLButton( + not_null parent, + const style::RecordBar &st) +: RippleButton(parent, st.lock.ripple) +, _st(st) +, _rippleRect(Rect(Size(st::historyRecordLockTopShadow.width())) + - (st::historyRecordLockRippleMargin)) +, _text(u"1"_q) { + resize(Size(st::historyRecordLockTopShadow.width())); + + setClickedCallback([=] { + Ui::AbstractButton::setDisabled(!Ui::AbstractButton::isDisabled()); + const auto isActive = !Ui::AbstractButton::isDisabled(); + _activeAnimation.start( + [=] { update(); }, + isActive ? 0. : 1., + isActive ? 1. : 0., + st::historyRecordVoiceShowDuration); + }); + + paintRequest( + ) | rpl::start_with_next([=](const QRect &clip) { + auto p = QPainter(this); + + const auto inner = DrawLockCircle(p, rect(), _st.lock, 1.); + + Ui::RippleButton::paintRipple(p, _rippleRect.x(), _rippleRect.y()); + + const auto innerRect = QRectF(inner) + - st::historyRecordLockMargin * 2; + auto hq = PainterHighQualityEnabler(p); + + p.setFont(st::semiboldFont); + p.setPen(_st.lock.fg); + p.drawText(inner, _text, style::al_center); + + const auto penWidth = st::historyRecordTTLLineWidth; + auto pen = QPen(_st.lock.fg); + pen.setJoinStyle(Qt::RoundJoin); + pen.setCapStyle(Qt::RoundCap); + pen.setWidthF(penWidth); + + p.setPen(pen); + p.setBrush(Qt::NoBrush); + p.drawArc(innerRect, arc::kQuarterLength, arc::kHalfLength); + + { + p.setClipRect(innerRect + - QMarginsF( + innerRect.width() / 2, + -penWidth, + -penWidth, + -penWidth)); + pen.setStyle(Qt::DotLine); + p.setPen(pen); + p.drawEllipse(innerRect); + p.setClipping(false); + } + + const auto activeProgress = _activeAnimation.value( + !Ui::AbstractButton::isDisabled() ? 1 : 0); + if (activeProgress) { + p.setOpacity(activeProgress); + pen.setStyle(Qt::SolidLine); + pen.setBrush(st::windowBgActive); + p.setPen(pen); + p.setBrush(pen.brush()); + p.drawEllipse(innerRect); + + p.setPen(st::windowFgActive); + p.drawText(innerRect, _text, style::al_center); + } + + }, lifetime()); +} + +void TTLButton::clearState() { + Ui::AbstractButton::setDisabled(true); + update(); + Ui::RpWidget::hide(); +} + +QImage TTLButton::prepareRippleMask() const { + return Ui::RippleAnimation::EllipseMask(_rippleRect.size()); +} + +QPoint TTLButton::prepareRippleStartPosition() const { + return mapFromGlobal(QCursor::pos()) - _rippleRect.topLeft(); +} + } // namespace class ListenWrap final { @@ -316,7 +492,7 @@ void ListenWrap::init() { _parent->paintRequest( ) | rpl::start_with_next([=](const QRect &clip) { auto p = QPainter(_parent); - PainterHighQualityEnabler hq(p); + auto hq = PainterHighQualityEnabler(p); const auto progress = _showProgress.current(); p.setOpacity(progress); const auto &remove = _st.remove; @@ -359,7 +535,7 @@ void ListenWrap::init() { } p.setPen(Qt::NoPen); p.setBrush(_st.cancelActive); - QPainterPath path; + auto path = QPainterPath(); path.setFillRule(Qt::WindingFill); path.addEllipse(bgLeftCircleRect); path.addEllipse(bgRightCircleRect); @@ -627,7 +803,7 @@ class RecordLock final : public Ui::RippleButton { private: void init(); - void drawProgress(Painter &p); + void drawProgress(QPainter &p); void setProgress(float64 progress); void startLockingAnimation(float64 to); @@ -648,12 +824,8 @@ RecordLock::RecordLock( const style::RecordBarLock &st) : RippleButton(parent, st.ripple) , _st(st) -, _rippleRect(QRect( - 0, - 0, - st::historyRecordLockTopShadow.width(), - st::historyRecordLockTopShadow.width()) - .marginsRemoved(st::historyRecordLockRippleMargin)) +, _rippleRect(Rect(Size(st::historyRecordLockTopShadow.width())) + - (st::historyRecordLockRippleMargin)) , _arcPen( QColor(Qt::white), st::historyRecordLockIconLineWidth, @@ -687,7 +859,7 @@ void RecordLock::init() { if (!_visibleTopPart) { return; } - Painter p(this); + auto p = QPainter(this); if (_visibleTopPart > 0 && _visibleTopPart < height()) { p.setClipRect(0, 0, width(), _visibleTopPart); } @@ -704,73 +876,13 @@ void RecordLock::init() { }, lifetime()); } -void RecordLock::drawProgress(Painter &p) { +void RecordLock::drawProgress(QPainter &p) { const auto progress = _progress.current(); - const auto &originTop = _st.originTop; - const auto &originBottom = _st.originBottom; - const auto &originBody = _st.originBody; - const auto &shadowTop = _st.shadowTop; - const auto &shadowBottom = _st.shadowBottom; - const auto &shadowBody = _st.shadowBody; - const auto &shadowMargins = st::historyRecordLockMargin; - - const auto bottomMargin = anim::interpolate( - 0, - rect().height() - shadowTop.height() - shadowBottom.height(), - progress); - - const auto topMargin = anim::interpolate( - rect().height() / 4, - 0, - progress); - - const auto full = rect().marginsRemoved( - style::margins(0, topMargin, 0, bottomMargin)); - const auto inner = full.marginsRemoved(shadowMargins); - const auto content = inner.marginsRemoved(style::margins( - 0, - originTop.height(), - 0, - originBottom.height())); - const auto contentShadow = full.marginsRemoved(style::margins( - 0, - shadowTop.height(), - 0, - shadowBottom.height())); + const auto inner = DrawLockCircle(p, rect(), _st, progress); - const auto w = full.width(); - { - shadowTop.paint(p, full.topLeft(), w); - originTop.paint(p, inner.topLeft(), w); - } - { - const auto shadowPos = QPoint( - full.x(), - contentShadow.y() + contentShadow.height()); - const auto originPos = QPoint( - inner.x(), - content.y() + content.height()); - shadowBottom.paint(p, shadowPos, w); - originBottom.paint(p, originPos, w); - } - { - shadowBody.fill(p, contentShadow); - originBody.fill(p, content); - } - { - const auto &arrow = _st.arrow; - const auto arrowRect = QRect( - inner.x(), - content.y() + content.height() - arrow.height() / 2, - inner.width(), - arrow.height()); - p.setOpacity(1. - progress); - arrow.paintInCenter(p, arrowRect); - p.setOpacity(1.); - } if (isLocked()) { - paintRipple(p, _rippleRect.x(), _rippleRect.y()); + Ui::RippleButton::paintRipple(p, _rippleRect.x(), _rippleRect.y()); } { const auto &arcOffset = st::historyRecordLockIconLineSkip; @@ -803,12 +915,12 @@ void RecordLock::drawProgress(Painter &p) { const auto lockTranslation = QPoint( (inner.width() - size.width()) / 2, - (originTop.height() * 2 - size.height()) / 2); + (_st.originTop.height() * 2 - size.height()) / 2); const auto xRadius = anim::interpolate(2, 3, _lockToStopProgress); if (_lockToStopProgress == 1.) { // Paint the block. - PainterHighQualityEnabler hq(p); + auto hq = PainterHighQualityEnabler(p); p.translate(inner.topLeft() + lockTranslation); p.setPen(Qt::NoPen); p.setBrush(_st.fg); @@ -821,8 +933,8 @@ void RecordLock::drawProgress(Painter &p) { frame.setDevicePixelRatio(style::DevicePixelRatio()); frame.fill(Qt::transparent); - Painter q(&frame); - PainterHighQualityEnabler hq(q); + auto q = QPainter(&frame); + auto hq = PainterHighQualityEnabler(q); q.setPen(Qt::NoPen); q.setBrush(_arcPen.brush()); @@ -980,19 +1092,19 @@ void CancelButton::init() { paintRequest( ) | rpl::start_with_next([=] { - Painter p(this); + auto p = QPainter(this); p.setOpacity(_showProgress.current()); - paintRipple(p, _rippleRect.x(), _rippleRect.y()); + Ui::RippleButton::paintRipple(p, _rippleRect.x(), _rippleRect.y()); p.setPen(_st.cancelActive); - _text.draw( - p, - 0, - (height() - _text.minHeight()) / 2, - width(), - style::al_center); + _text.draw(p, { + .position = QPoint(0, (height() - _text.minHeight()) / 2), + .outerWidth = width(), + .availableWidth = width(), + .align = style::al_center, + }); }, lifetime()); } @@ -1018,6 +1130,7 @@ VoiceRecordBar::VoiceRecordBar( , _show(std::move(descriptor.show)) , _send(std::move(descriptor.send)) , _lock(std::make_unique(_outerContainer, _st.lock)) +, _ttlButton(std::make_unique(_outerContainer, _st)) , _level(std::make_unique(_outerContainer, _st)) , _cancel(std::make_unique(this, _st, descriptor.recorderHeight)) , _startTimer([=] { startRecording(); }) @@ -1054,9 +1167,7 @@ VoiceRecordBar::~VoiceRecordBar() { } void VoiceRecordBar::updateMessageGeometry() { - const auto left = _durationRect.x() - + _durationRect.width() - + st::historyRecordTextLeft; + const auto left = rect::right(_durationRect) + st::historyRecordTextLeft; const auto right = width() - _send->width() - st::historyRecordTextRight; @@ -1080,7 +1191,7 @@ void VoiceRecordBar::updateLockGeometry() { - st::historyRecordLockPosition.y() - _lock->height(); const auto finalRight = _outerContainer->width() - - (me.x() + me.width()) + - rect::right(me) + st::historyRecordLockPosition.x(); const auto progress = _showLockAnimation.value( _lockShowing.current() ? 1. : 0.); @@ -1095,6 +1206,33 @@ void VoiceRecordBar::updateLockGeometry() { } } +void VoiceRecordBar::updateTTLGeometry( + TTLAnimationType type, + float64 progress) { + const auto parent = parentWidget(); + const auto me = Ui::MapFrom(_outerContainer, parent, geometry()); + const auto anyTop = me.y() - st::historyRecordLockPosition.y(); + if (type == TTLAnimationType::RightLeft) { + const auto finalRight = _outerContainer->width() + - rect::right(me) + + st::historyRecordLockPosition.x(); + + const auto from = -_ttlButton->width(); + const auto right = anim::interpolate(from, finalRight, progress); + _ttlButton->moveToRight(right, _ttlButton->y()); + } else if (type == TTLAnimationType::TopBottom) { + const auto ttlFrom = anyTop - _ttlButton->height() * 2; + const auto ttlTo = anyTop - _lock->height(); + _ttlButton->moveToLeft( + _ttlButton->x(), + anim::interpolate(ttlFrom, ttlTo, 1. - progress)); + } else if (type == TTLAnimationType::RightTopStatic) { + _ttlButton->moveToRight( + -_ttlButton->width(), + anyTop - _ttlButton->height() * 2); + } +} + void VoiceRecordBar::init() { if (_st.radius > 0) { _backgroundRect.emplace(_st.radius, _st.bg); @@ -1143,7 +1281,7 @@ void VoiceRecordBar::init() { paintRequest( ) | rpl::start_with_next([=](const QRect &clip) { - Painter p(this); + auto p = QPainter(this); if (_showAnimation.animating()) { p.setOpacity(showAnimationRatio()); } @@ -1218,6 +1356,7 @@ void VoiceRecordBar::init() { if (to == value) { _recordingLifetime.destroy(); } + updateTTLGeometry(TTLAnimationType::TopBottom, 1. - value); }; _showListenAnimation.start(std::move(callback), 0., to, duration); }, lifetime()); @@ -1227,6 +1366,11 @@ void VoiceRecordBar::init() { _lock->locks( ) | rpl::start_with_next([=] { + if (_hasTTLFilter && _hasTTLFilter()) { + _ttlButton->show(); + } + updateTTLGeometry(TTLAnimationType::RightTopStatic, 0); + _level->setType(VoiceRecordButton::Type::Send); _level->clicks( @@ -1248,6 +1392,7 @@ void VoiceRecordBar::init() { auto callback = [=](float64 value) { _lock->requestPaintLockToStopProgress(value); update(); + updateTTLGeometry(TTLAnimationType::RightLeft, value); }; _lockToStopAnimation.start(std::move(callback), from, to, duration); }, lifetime()); @@ -1323,6 +1468,9 @@ void VoiceRecordBar::visibilityAnimate(bool show, Fn &&callback) { _listen->requestPaintProgress(value); } update(); + if (!show) { + updateTTLGeometry(TTLAnimationType::RightLeft, value); + } if ((show && value == 1.) || (!show && value == 0.)) { if (callback) { callback(); @@ -1332,10 +1480,14 @@ void VoiceRecordBar::visibilityAnimate(bool show, Fn &&callback) { _showAnimation.start(std::move(animationCallback), from, to, duration); } -void VoiceRecordBar::setStartRecordingFilter(Fn &&callback) { +void VoiceRecordBar::setStartRecordingFilter(FilterCallback &&callback) { _startRecordingFilter = std::move(callback); } +void VoiceRecordBar::setTTLFilter(FilterCallback &&callback) { + _hasTTLFilter = std::move(callback); +} + void VoiceRecordBar::initLockGeometry() { rpl::combine( _lock->heightValue(), @@ -1470,6 +1622,7 @@ void VoiceRecordBar::hideFast() { hide(); _lock->hide(); _level->hide(); + [[maybe_unused]] const auto s = takeTTLState(); } void VoiceRecordBar::stopRecording(StopType type) { @@ -1491,7 +1644,17 @@ void VoiceRecordBar::stopRecording(StopType type) { window()->activateWindow(); const auto duration = Duration(data.samples); if (type == StopType::Send) { - _sendVoiceRequests.fire({ data.bytes, data.waveform, duration }); + const auto options = Api::SendOptions{ + .ttlSeconds = takeTTLState() + ? std::numeric_limits::max() + : 0 + }; + _sendVoiceRequests.fire({ + data.bytes, + data.waveform, + duration, + options, + }); } else if (type == StopType::Listen) { _listen = std::make_unique( this, @@ -1506,7 +1669,7 @@ void VoiceRecordBar::stopRecording(StopType type) { })); } -void VoiceRecordBar::drawDuration(Painter &p) { +void VoiceRecordBar::drawDuration(QPainter &p) { const auto duration = FormatVoiceDuration(_recordingSamples); p.setFont(_cancelFont); p.setPen(_st.durationFg); @@ -1529,8 +1692,8 @@ void VoiceRecordBar::startRedCircleAnimation() { animation->start(); } -void VoiceRecordBar::drawRedCircle(Painter &p) { - PainterHighQualityEnabler hq(p); +void VoiceRecordBar::drawRedCircle(QPainter &p) { + auto hq = PainterHighQualityEnabler(p); p.setPen(Qt::NoPen); p.setBrush(st::historyRecordVoiceFgInactive); @@ -1542,18 +1705,18 @@ void VoiceRecordBar::drawRedCircle(Painter &p) { p.setOpacity(opacity); } -void VoiceRecordBar::drawMessage(Painter &p, float64 recordActive) { +void VoiceRecordBar::drawMessage(QPainter &p, float64 recordActive) { p.setPen(anim::pen(_st.cancel, _st.cancelActive, 1. - recordActive)); const auto opacity = p.opacity(); p.setOpacity(opacity * (1. - _lock->lockToStopProgress())); - _message.draw( - p, - _messageRect.x(), - _messageRect.y(), - _messageRect.width(), - style::al_center); + _message.draw(p, { + .position = _messageRect.topLeft(), + .outerWidth = _messageRect.width(), + .availableWidth = _messageRect.width(), + .align = style::al_center, + }); p.setOpacity(opacity); } @@ -1561,11 +1724,15 @@ void VoiceRecordBar::drawMessage(Painter &p, float64 recordActive) { void VoiceRecordBar::requestToSendWithOptions(Api::SendOptions options) { if (isListenState()) { const auto data = _listen->data(); + if (takeTTLState()) { + options.ttlSeconds = std::numeric_limits::max(); + } _sendVoiceRequests.fire({ data->bytes, data->waveform, Duration(data->samples), - options }); + options, + }); } } @@ -1684,6 +1851,12 @@ void VoiceRecordBar::computeAndSetLockProgress(QPoint globalPos) { _lock->requestPaintProgress(Progress(localPos.y(), higher - lower)); } +bool VoiceRecordBar::takeTTLState() const { + const auto hasTtl = !_ttlButton->isDisabled(); + _ttlButton->clearState(); + return hasTtl; +} + void VoiceRecordBar::orderControls() { stackUnder(_send.get()); _lock->raise(); diff --git a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.h b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.h index 09c4916789596f..31c0eb30e3735b 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.h +++ b/Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.h @@ -21,6 +21,7 @@ struct RecordBar; } // namespace style namespace Ui { +class AbstractButton; class SendButton; } // namespace Ui @@ -53,6 +54,7 @@ class VoiceRecordBar final : public Ui::RpWidget { public: using SendActionUpdate = Controls::SendActionUpdate; using VoiceToSend = Controls::VoiceToSend; + using FilterCallback = Fn; VoiceRecordBar( not_null parent, @@ -87,7 +89,8 @@ class VoiceRecordBar final : public Ui::RpWidget { void requestToSendWithOptions(Api::SendOptions options); - void setStartRecordingFilter(Fn &&callback); + void setStartRecordingFilter(FilterCallback &&callback); + void setTTLFilter(FilterCallback &&callback); [[nodiscard]] bool isRecording() const; [[nodiscard]] bool isRecordingLocked() const; @@ -103,46 +106,56 @@ class VoiceRecordBar final : public Ui::RpWidget { Listen, }; + enum class TTLAnimationType { + RightLeft, + TopBottom, + RightTopStatic, + }; + void init(); void initLockGeometry(); void initLevelGeometry(); void updateMessageGeometry(); void updateLockGeometry(); + void updateTTLGeometry(TTLAnimationType type, float64 progress); void recordUpdated(quint16 level, int samples); - bool recordingAnimationCallback(crl::time now); + [[nodiscard]] bool recordingAnimationCallback(crl::time now); void stop(bool send); void stopRecording(StopType type); void visibilityAnimate(bool show, Fn &&callback); - bool showRecordButton() const; - void drawDuration(Painter &p); - void drawRedCircle(Painter &p); - void drawMessage(Painter &p, float64 recordActive); + [[nodiscard]] bool showRecordButton() const; + void drawDuration(QPainter &p); + void drawRedCircle(QPainter &p); + void drawMessage(QPainter &p, float64 recordActive); void startRedCircleAnimation(); void installListenStateFilter(); - bool isTypeRecord() const; - bool hasDuration() const; + [[nodiscard]] bool isTypeRecord() const; + [[nodiscard]] bool hasDuration() const; void finish(); void activeAnimate(bool active); - float64 showAnimationRatio() const; - float64 showListenAnimationRatio() const; - float64 activeAnimationRatio() const; + [[nodiscard]] float64 showAnimationRatio() const; + [[nodiscard]] float64 showListenAnimationRatio() const; + [[nodiscard]] float64 activeAnimationRatio() const; void computeAndSetLockProgress(QPoint globalPos); + [[nodiscard]] bool takeTTLState() const; + const style::RecordBar &_st; const not_null _outerContainer; const std::shared_ptr _show; const std::shared_ptr _send; const std::unique_ptr _lock; + const std::unique_ptr _ttlButton; const std::unique_ptr _level; const std::unique_ptr _cancel; std::unique_ptr _listen; @@ -161,7 +174,8 @@ class VoiceRecordBar final : public Ui::RpWidget { Ui::Text::String _message; - Fn _startRecordingFilter; + FilterCallback _startRecordingFilter; + FilterCallback _hasTTLFilter; bool _warningShown = false; diff --git a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp index cb8fa5c336fa25..19376b3aa1cae8 100644 --- a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp +++ b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp @@ -220,7 +220,7 @@ void AddSaveDocumentAction( HistoryItem *item, not_null document, not_null list) { - if (list->hasCopyMediaRestriction(item)) { + if (list->hasCopyMediaRestriction(item) || ItemHasTtl(item)) { return; } const auto origin = item ? item->fullId() : FullMsgId(); @@ -556,7 +556,7 @@ bool AddRescheduleAction( ? SendMenu::Type::Reminder : HistoryView::CanScheduleUntilOnline(peer) ? SendMenu::Type::ScheduledToUser - : SendMenu::Type::Scheduled; + : SendMenu::Type::Disabled; const auto itemDate = firstItem->date(); const auto date = (itemDate == Api::kScheduledUntilOnlineTimestamp) @@ -1234,6 +1234,9 @@ void AddSaveSoundForNotifications( not_null item, not_null document, not_null controller) { + if (ItemHasTtl(item)) { + return; + } const auto &ringtones = document->session().api().ringtones(); if (document->size > ringtones.maxSize()) { return; @@ -1531,4 +1534,10 @@ TextWithEntities TransribedText(not_null item) { return {}; } +bool ItemHasTtl(HistoryItem *item) { + return (item && item->media()) + ? (item->media()->ttlSeconds() > 0) + : false; +} + } // namespace HistoryView diff --git a/Telegram/SourceFiles/history/view/history_view_context_menu.h b/Telegram/SourceFiles/history/view/history_view_context_menu.h index 53a45e36c18abe..4979a678918d92 100644 --- a/Telegram/SourceFiles/history/view/history_view_context_menu.h +++ b/Telegram/SourceFiles/history/view/history_view_context_menu.h @@ -110,4 +110,6 @@ void AddEmojiPacksAction( [[nodiscard]] TextWithEntities TransribedText(not_null item); +[[nodiscard]] bool ItemHasTtl(HistoryItem *item); + } // namespace HistoryView diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index a573eace0ea365..d2c56ca8edf470 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -276,6 +276,9 @@ QString DateTooltipText(not_null view) { msgsigned->postAuthor); } } + if (item->isScheduled() && item->isSilent()) { + dateText += '\n' + QChar(0xD83D) + QChar(0xDD15); + } return dateText; } diff --git a/Telegram/SourceFiles/history/view/history_view_reply.cpp b/Telegram/SourceFiles/history/view/history_view_reply.cpp index 527654d9ad83ae..5830bf0c50f832 100644 --- a/Telegram/SourceFiles/history/view/history_view_reply.cpp +++ b/Telegram/SourceFiles/history/view/history_view_reply.cpp @@ -732,7 +732,11 @@ void Reply::paint( const auto textw = w - st::historyReplyPadding.left() - st::historyReplyPadding.right(); - const auto namew = textw - previewSkip; + const auto namew = textw + - previewSkip + - (_hasQuoteIcon + ? st::messageTextStyle.blockquote.icon.width() + : 0); auto firstLineSkip = _nameTwoLines ? 0 : previewSkip; if (namew > 0) { p.setPen(!inBubble diff --git a/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp b/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp index 286edd18964635..c5e60091dd6e1d 100644 --- a/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp +++ b/Telegram/SourceFiles/history/view/history_view_schedule_box.cpp @@ -93,9 +93,10 @@ void ScheduleBox( .style = style.chooseDateTimeArgs, }); + using T = SendMenu::Type; SendMenu::SetupMenuAndShortcuts( descriptor.submit.data(), - [=] { return SendMenu::Type::SilentOnly; }, + [t = type == T::Disabled ? T::Disabled : T::SilentOnly] { return t; }, [=] { save(true, descriptor.collect()); }, nullptr, nullptr); diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_document.cpp index e3e2808cdc2f3d..7ca7bc747f0616 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_document.cpp @@ -23,24 +23,18 @@ For license and copyright information please follow this link: #include "history/view/history_view_cursor_state.h" #include "history/view/history_view_transcribe_button.h" #include "history/view/media/history_view_media_common.h" -#include "ui/image/image.h" #include "ui/text/format_values.h" #include "ui/text/format_song_document_name.h" #include "ui/text/text_utilities.h" -#include "ui/chat/message_bubble.h" #include "ui/chat/chat_style.h" -#include "ui/cached_round_corners.h" #include "ui/painter.h" #include "ui/power_saving.h" #include "ui/rect.h" -#include "ui/ui_utility.h" #include "data/data_session.h" #include "data/data_document.h" #include "data/data_document_media.h" #include "data/data_document_resolver.h" -#include "data/data_media_types.h" #include "data/data_file_click_handler.h" -#include "data/data_file_origin.h" #include "api/api_transcribes.h" #include "apiwrap.h" #include "styles/style_chat.h" @@ -53,30 +47,36 @@ constexpr auto kAudioVoiceMsgUpdateView = crl::time(100); void DrawCornerBadgeTTL( QPainter &p, - const style::color &color, + const style::color &bg, + const style::color &fg, const QRect &circleRect) { p.save(); - const auto partRect = QRect( - circleRect.left() + circleRect.width() - st::dialogsTTLBadgeSize * 0.85, - circleRect.top() + circleRect.height() - st::dialogsTTLBadgeSize * 0.85, + const auto partRect = QRectF( + rect::right(circleRect) + - st::dialogsTTLBadgeSize + + rect::m::sum::h(st::dialogsTTLBadgeInnerMargins), + rect::bottom(circleRect) + - st::dialogsTTLBadgeSize + + rect::m::sum::v(st::dialogsTTLBadgeInnerMargins), st::dialogsTTLBadgeSize, st::dialogsTTLBadgeSize); auto hq = PainterHighQualityEnabler(p); - p.setBrush(color); + p.setPen(Qt::NoPen); + p.setBrush(bg); p.drawEllipse(partRect); const auto innerRect = partRect - st::dialogsTTLBadgeInnerMargins; const auto ttlText = u"1"_q; p.setFont(st::dialogsScamFont); - p.setPen(st::premiumButtonFg); + p.setPen(fg); p.drawText(innerRect, ttlText, style::al_center); constexpr auto kPenWidth = 1.5; const auto penWidth = style::ConvertScaleExact(kPenWidth); - auto pen = QPen(st::premiumButtonFg); + auto pen = QPen(fg); pen.setJoinStyle(Qt::RoundJoin); pen.setCapStyle(Qt::RoundCap); pen.setWidthF(penWidth); @@ -86,7 +86,7 @@ void DrawCornerBadgeTTL( p.drawArc(innerRect, arc::kQuarterLength, arc::kHalfLength); p.setClipRect(innerRect - - QMargins(innerRect.width() / 2, 0, -penWidth, -penWidth)); + - QMarginsF(innerRect.width() / 2, -penWidth, -penWidth, -penWidth)); pen.setStyle(Qt::DotLine); p.setPen(pen); p.drawEllipse(innerRect); @@ -139,6 +139,29 @@ void DrawCornerBadgeTTL( }; } +void FillThumbnailOverlay( + QPainter &p, + QRect rect, + Ui::BubbleRounding rounding, + const PaintContext &context) { + using Corner = Ui::BubbleCornerRounding; + using Radius = Ui::CachedCornerRadius; + auto corners = Ui::CornersPixmaps(); + const auto &st = context.st; + const auto lookup = [&](Corner corner) { + switch (corner) { + case Corner::None: return Radius::Small; + case Corner::Small: return Radius::ThumbSmall; + case Corner::Large: return Radius::ThumbLarge; + } + Unexpected("Corner value in FillThumbnailOverlay."); + }; + for (auto i = 0; i != 4; ++i) { + corners.p[i] = st->msgSelectOverlayCorners(lookup(rounding[i])).p[i]; + } + Ui::FillComplexOverlayRect(p, rect, st->msgSelectOverlay(), corners); +} + [[nodiscard]] QString CleanTagSymbols(const QString &value) { auto result = QString(); const auto begin = value.begin(), end = value.end(); @@ -323,7 +346,8 @@ Document::Document( ::Media::Player::instance()->tracksFinished( ) | rpl::filter([=](AudioMsgId::Type type) { return (type == AudioMsgId::Type::Voice); - }) | rpl::to_empty + }) | rpl::to_empty, + ::Media::Player::instance()->stops(AudioMsgId::Type::Voice) ) | rpl::start_with_next([=]() mutable { _drawTtl = nullptr; const auto item = _parent->data(); @@ -642,7 +666,7 @@ void Document::draw( validateThumbnail(thumbed, st.thumbSize, rounding); p.drawImage(rthumb, thumbed->thumbnail); if (context.selected()) { - fillThumbnailOverlay(p, rthumb, rounding, context); + FillThumbnailOverlay(p, rthumb, rounding, context); } if (radial || (!loaded && !_data->loading()) || _data->waitingForAlbum()) { @@ -718,10 +742,6 @@ void Document::draw( PainterHighQualityEnabler hq(p); p.setBrush(stm->msgFileBg); p.drawEllipse(inner); - - if (_parent->data()->media()->ttlSeconds()) { - DrawCornerBadgeTTL(p, stm->msgFileBg, inner); - } } } @@ -898,6 +918,12 @@ void Document::draw( .highlight = highlightRequest ? &*highlightRequest : nullptr, }); } + if (_parent->data()->media() && _parent->data()->media()->ttlSeconds()) { + const auto &fg = context.outbg + ? st::historyFileOutIconFg + : st::historyFileInIconFg; + DrawCornerBadgeTTL(p, stm->msgFileBg, fg, inner); + } } Ui::BubbleRounding Document::thumbRounding( @@ -962,29 +988,6 @@ void Document::validateThumbnail( thumbed->rounding = rounding; } -void Document::fillThumbnailOverlay( - QPainter &p, - QRect rect, - Ui::BubbleRounding rounding, - const PaintContext &context) const { - using Corner = Ui::BubbleCornerRounding; - using Radius = Ui::CachedCornerRadius; - auto corners = Ui::CornersPixmaps(); - const auto &st = context.st; - const auto lookup = [&](Corner corner) { - switch (corner) { - case Corner::None: return Radius::Small; - case Corner::Small: return Radius::ThumbSmall; - case Corner::Large: return Radius::ThumbLarge; - } - Unexpected("Corner value in Document::fillThumbnailOverlay."); - }; - for (auto i = 0; i != 4; ++i) { - corners.p[i] = st->msgSelectOverlayCorners(lookup(rounding[i])).p[i]; - } - Ui::FillComplexOverlayRect(p, rect, st->msgSelectOverlay(), corners); -} - bool Document::hasHeavyPart() const { return (_dataMedia != nullptr); } @@ -1701,7 +1704,7 @@ bool DrawThumbnailAsSongCover( const style::color &colored, const std::shared_ptr &dataMedia, const QRect &rect, - const bool selected) { + bool selected) { if (!dataMedia) { return false; } diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.h b/Telegram/SourceFiles/history/view/media/history_view_document.h index 5e57308ed57297..5fa8dc1dace5ca 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.h +++ b/Telegram/SourceFiles/history/view/media/history_view_document.h @@ -17,11 +17,9 @@ namespace Data { class DocumentMedia; } // namespace Data -namespace Ui { -namespace Text { +namespace Ui::Text { class String; -} // namespace Text -} // namespace Ui +} // namespace Ui::Text namespace HistoryView { @@ -101,11 +99,6 @@ class Document final bool dataLoaded() const override; private: - struct StateFromPlayback { - int64 statusSize = 0; - bool showPause = false; - TimeId realDuration = 0; - }; enum class LayoutMode { Full, Grouped, @@ -139,11 +132,6 @@ class Document final not_null thumbed, int size, Ui::BubbleRounding rounding) const; - void fillThumbnailOverlay( - QPainter &p, - QRect rect, - Ui::BubbleRounding rounding, - const PaintContext &context) const; void setStatusSize(int64 newSize, TimeId realDuration = 0) const; bool updateStatusText() const; // returns showPause @@ -191,6 +179,6 @@ bool DrawThumbnailAsSongCover( const style::color &colored, const std::shared_ptr &dataMedia, const QRect &rect, - const bool selected = false); + bool selected = false); } // namespace HistoryView diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index a62d538261819e..fe92a6de176d67 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -755,7 +755,6 @@ void MainWidget::handleAudioUpdate(const Media::Player::TrackState &state) { const auto item = session().data().message(state.id.contextId()); if (!Media::Player::IsStoppedOrStopping(state.state)) { const auto ttlSeconds = item - && !item->out() && item->media() && item->media()->ttlSeconds(); if (!ttlSeconds) { diff --git a/Telegram/SourceFiles/payments/ui/payments_panel.cpp b/Telegram/SourceFiles/payments/ui/payments_panel.cpp index 5e5c872de2afa7..bc2817d52b2809 100644 --- a/Telegram/SourceFiles/payments/ui/payments_panel.cpp +++ b/Telegram/SourceFiles/payments/ui/payments_panel.cpp @@ -96,7 +96,7 @@ Panel::Panel(not_null delegate) } Panel::~Panel() { - _webview = nullptr; + base::take(_webview); _progress = nullptr; _widget = nullptr; } @@ -528,6 +528,7 @@ bool Panel::createWebview(const Webview::ThemeParams ¶ms) { auto outer = base::make_unique_q(_widget.get()); const auto container = outer.get(); _widget->showInner(std::move(outer)); + const auto webviewParent = QPointer(container); _webviewBottom = std::make_unique(_widget.get()); const auto bottom = _webviewBottom.get(); @@ -552,7 +553,7 @@ bool Panel::createWebview(const Webview::ThemeParams ¶ms) { const auto raw = &_webview->window; QObject::connect(container, &QObject::destroyed, [=] { if (_webview && &_webview->window == raw) { - _webview = nullptr; + base::take(_webview); if (_webviewProgress) { hideWebviewProgress(); if (_progress && !_progress->shown) { @@ -568,6 +569,16 @@ bool Panel::createWebview(const Webview::ThemeParams ¶ms) { return false; } QObject::connect(raw->widget(), &QObject::destroyed, [=] { + const auto parent = webviewParent.data(); + if (!_webview + || &_webview->window != raw + || !parent + || _widget->inner() != parent) { + // If we destroyed _webview ourselves, + // or if we changed _widget->inner ourselves, + // we don't show any message, nothing crashed. + return; + } crl::on_main(this, [=] { showCriticalError({ "Error: WebView has crashed." }); }); diff --git a/Telegram/SourceFiles/platform/win/integration_win.cpp b/Telegram/SourceFiles/platform/win/integration_win.cpp index b8d53a506ac585..3d8b592e7c2ae0 100644 --- a/Telegram/SourceFiles/platform/win/integration_win.cpp +++ b/Telegram/SourceFiles/platform/win/integration_win.cpp @@ -7,17 +7,24 @@ For license and copyright information please follow this link: */ #include "platform/win/integration_win.h" -#include "platform/platform_integration.h" -#include "platform/platform_specific.h" +#include "base/platform/win/base_windows_winrt.h" #include "core/application.h" #include "core/core_settings.h" #include "core/sandbox.h" +#include "lang/lang_keys.h" +#include "platform/win/windows_app_user_model_id.h" +#include "platform/win/tray_win.h" +#include "platform/platform_integration.h" +#include "platform/platform_specific.h" #include "tray.h" -#include "base/platform/win/base_windows_winrt.h" +#include "styles/style_window.h" #include #include +#include +#include + namespace Platform { void WindowsIntegration::init() { @@ -48,6 +55,78 @@ bool WindowsIntegration::nativeEventFilter( }); } +void WindowsIntegration::createCustomJumpList() { + _jumpList = base::WinRT::TryCreateInstance( + CLSID_DestinationList); + if (_jumpList) { + refreshCustomJumpList(); + } +} + +void WindowsIntegration::refreshCustomJumpList() { + auto added = false; + auto maxSlots = UINT(); + auto removed = (IObjectArray*)nullptr; + auto hr = _jumpList->BeginList(&maxSlots, IID_PPV_ARGS(&removed)); + if (!SUCCEEDED(hr)) { + return; + } + const auto guard = gsl::finally([&] { + if (added) { + _jumpList->CommitList(); + } else { + _jumpList->AbortList(); + } + }); + + auto shellLink = base::WinRT::TryCreateInstance( + CLSID_ShellLink); + if (!shellLink) { + return; + } + + // Set the path to your application and the command-line argument for quitting + const auto exe = QDir::toNativeSeparators(cExeDir() + cExeName()); + const auto dir = QDir::toNativeSeparators(QDir(cWorkingDir()).absolutePath()); + const auto icon = Tray::QuitJumpListIconPath(); + shellLink->SetArguments(L"-quit"); + shellLink->SetPath(exe.toStdWString().c_str()); + shellLink->SetWorkingDirectory(dir.toStdWString().c_str()); + shellLink->SetIconLocation(icon.toStdWString().c_str(), 0); + + if (const auto propertyStore = shellLink.try_as()) { + auto appIdPropVar = PROPVARIANT(); + hr = InitPropVariantFromString( + AppUserModelId::Id().c_str(), + &appIdPropVar); + if (SUCCEEDED(hr)) { + hr = propertyStore->SetValue( + AppUserModelId::Key(), + appIdPropVar); + PropVariantClear(&appIdPropVar); + } + auto titlePropVar = PROPVARIANT(); + hr = InitPropVariantFromString( + tr::lng_quit_from_tray(tr::now).toStdWString().c_str(), + &titlePropVar); + if (SUCCEEDED(hr)) { + hr = propertyStore->SetValue(PKEY_Title, titlePropVar); + PropVariantClear(&titlePropVar); + } + propertyStore->Commit(); + } + + auto collection = base::WinRT::TryCreateInstance( + CLSID_EnumerableObjectCollection); + if (!collection) { + return; + } + collection->AddObject(shellLink.get()); + + _jumpList->AddUserTasks(collection.get()); + added = true; +} + bool WindowsIntegration::processEvent( HWND hWnd, UINT msg, @@ -58,6 +137,9 @@ bool WindowsIntegration::processEvent( _taskbarList = base::WinRT::TryCreateInstance( CLSID_TaskbarList, CLSCTX_ALL); + if (_taskbarList) { + createCustomJumpList(); + } } switch (msg) { @@ -80,10 +162,14 @@ bool WindowsIntegration::processEvent( break; case WM_SETTINGCHANGE: + RefreshTaskbarThemeValue(); #if QT_VERSION < QT_VERSION_CHECK(6, 5, 0) Core::App().settings().setSystemDarkMode(Platform::IsDarkMode()); #endif // Qt < 6.5.0 Core::App().tray().updateIconCounters(); + if (_jumpList) { + refreshCustomJumpList(); + } break; } return false; diff --git a/Telegram/SourceFiles/platform/win/integration_win.h b/Telegram/SourceFiles/platform/win/integration_win.h index dae97841196fad..0b29007d32856f 100644 --- a/Telegram/SourceFiles/platform/win/integration_win.h +++ b/Telegram/SourceFiles/platform/win/integration_win.h @@ -37,8 +37,12 @@ class WindowsIntegration final LPARAM lParam, LRESULT *result); + void createCustomJumpList(); + void refreshCustomJumpList(); + uint32 _taskbarCreatedMsgId = 0; winrt::com_ptr _taskbarList; + winrt::com_ptr _jumpList; }; diff --git a/Telegram/SourceFiles/platform/win/specific_win.cpp b/Telegram/SourceFiles/platform/win/specific_win.cpp index c77b2bdb5f0ff4..d1777e04c433f8 100644 --- a/Telegram/SourceFiles/platform/win/specific_win.cpp +++ b/Telegram/SourceFiles/platform/win/specific_win.cpp @@ -195,8 +195,7 @@ bool ManageAppLink( return true; } const auto shellLink = base::WinRT::TryCreateInstance( - CLSID_ShellLink, - CLSCTX_INPROC_SERVER); + CLSID_ShellLink); if (!shellLink) { if (!silent) LOG(("App Error: could not create instance of IID_IShellLink %1").arg(hr)); return false; diff --git a/Telegram/SourceFiles/platform/win/tray_win.cpp b/Telegram/SourceFiles/platform/win/tray_win.cpp index 8b614caa38077a..a2444354f24bc5 100644 --- a/Telegram/SourceFiles/platform/win/tray_win.cpp +++ b/Telegram/SourceFiles/platform/win/tray_win.cpp @@ -26,6 +26,7 @@ For license and copyright information please follow this link: #include #include #include +#include namespace Platform { @@ -33,18 +34,10 @@ namespace { constexpr auto kTooltipDelay = crl::time(10000); -[[nodiscard]] std::optional IsDarkTaskbar() { - static const auto kSystemVersion = QOperatingSystemVersion::current(); - static const auto kDarkModeAddedVersion = QOperatingSystemVersion( - QOperatingSystemVersion::Windows, - 10, - 0, - 18282); - static const auto kSupported = (kSystemVersion >= kDarkModeAddedVersion); - if (!kSupported) { - return std::nullopt; - } +std::optional DarkTaskbar; +bool DarkTasbarValueValid/* = false*/; +[[nodiscard]] std::optional ReadDarkTaskbarValue() { const auto keyName = L"" "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; const auto valueName = L"SystemUsesLightTheme"; @@ -64,6 +57,23 @@ constexpr auto kTooltipDelay = crl::time(10000); return (value == 0); } +[[nodiscard]] std::optional IsDarkTaskbar() { + static const auto kSystemVersion = QOperatingSystemVersion::current(); + static const auto kDarkModeAddedVersion = QOperatingSystemVersion( + QOperatingSystemVersion::Windows, + 10, + 0, + 18282); + static const auto kSupported = (kSystemVersion >= kDarkModeAddedVersion); + if (!kSupported) { + return std::nullopt; + } else if (!DarkTasbarValueValid) { + DarkTasbarValueValid = true; + DarkTaskbar = ReadDarkTaskbarValue(); + } + return DarkTaskbar; +} + [[nodiscard]] QImage MonochromeIconFor(int size, bool darkMode) { Expects(size > 0); @@ -342,8 +352,99 @@ QPixmap Tray::IconWithCounter( monochrome)); } +void WriteIco(const QString &path, std::vector images) { + Expects(!images.empty()); + + auto buffer = QByteArray(); + const auto write = [&](auto value) { + buffer.append(reinterpret_cast(&value), sizeof(value)); + }; + + const auto count = int(images.size()); + + auto full = 0; + auto pngs = std::vector(); + pngs.reserve(count); + for (const auto &image : images) { + pngs.emplace_back(); + { + auto buffer = QBuffer(&pngs.back()); + image.save(&buffer, "PNG"); + } + full += pngs.back().size(); + } + + // Images directory + constexpr auto entry = sizeof(int8) + + sizeof(int8) + + sizeof(int8) + + sizeof(int8) + + sizeof(int16) + + sizeof(int16) + + sizeof(uint32) + + sizeof(uint32); + static_assert(entry == 16); + + auto offset = 3 * sizeof(int16) + count * entry; + full += offset; + + buffer.reserve(full); + + // Thanks https://stackoverflow.com/a/54289564/6509833 + write(int16(0)); + write(int16(1)); + write(int16(count)); + + for (auto i = 0; i != count; ++i) { + const auto &image = images[i]; + Assert(image.width() <= 256 && image.height() <= 256); + + write(int8(image.width() == 256 ? 0 : image.width())); + write(int8(image.height() == 256 ? 0 : image.height())); + write(int8(0)); // palette size + write(int8(0)); // reserved + write(int16(1)); // color planes + write(int16(image.depth())); // bits-per-pixel + write(uint32(pngs[i].size())); // size of image in bytes + write(uint32(offset)); // offset + offset += pngs[i].size(); + } + for (auto i = 0; i != count; ++i) { + buffer.append(pngs[i]); + } + + auto f = QFile(path); + if (f.open(QIODevice::WriteOnly)) { + f.write(buffer); + } +} + +QString Tray::QuitJumpListIconPath() { + const auto dark = IsDarkTaskbar(); + const auto key = !dark ? 0 : *dark ? 1 : 2; + const auto path = cWorkingDir() + u"tdata/temp/quit_%1.ico"_q.arg(key); + if (QFile::exists(path)) { + return path; + } + const auto color = !dark + ? st::trayCounterBg->c + : *dark + ? QColor(255, 255, 255) + : QColor(0, 0, 0, 228); + WriteIco(path, { + st::winQuitIcon.instance(color, 100, true), + st::winQuitIcon.instance(color, 200, true), + st::winQuitIcon.instance(color, 300, true), + }); + return path; +} + bool HasMonochromeSetting() { return IsDarkTaskbar().has_value(); } +void RefreshTaskbarThemeValue() { + DarkTasbarValueValid = false; +} + } // namespace Platform diff --git a/Telegram/SourceFiles/platform/win/tray_win.h b/Telegram/SourceFiles/platform/win/tray_win.h index 53631e55657a35..cb79c3beb5aeff 100644 --- a/Telegram/SourceFiles/platform/win/tray_win.h +++ b/Telegram/SourceFiles/platform/win/tray_win.h @@ -59,6 +59,7 @@ class Tray final { bool smallIcon, bool monochrome, bool supportMode); + [[nodiscard]] static QString QuitJumpListIconPath(); private: base::unique_qptr _icon; @@ -73,4 +74,6 @@ class Tray final { }; +void RefreshTaskbarThemeValue(); + } // namespace Platform diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp index 209444ff10b007..c94f26294e7fb6 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp @@ -364,7 +364,7 @@ Panel::Panel( } Panel::~Panel() { - _webview = nullptr; + base::take(_webview); _progress = nullptr; _widget = nullptr; } @@ -587,7 +587,7 @@ bool Panel::createWebview(const Webview::ThemeParams ¶ms) { QObject::connect(container, &QObject::destroyed, [=] { if (_webview && &_webview->window == raw) { - _webview = nullptr; + base::take(_webview); if (_webviewProgress) { hideWebviewProgress(); if (_progress && !_progress->shown) { @@ -604,6 +604,16 @@ bool Panel::createWebview(const Webview::ThemeParams ¶ms) { return false; } QObject::connect(raw->widget(), &QObject::destroyed, [=] { + const auto parent = _webviewParent.data(); + if (!_webview + || &_webview->window != raw + || !parent + || _widget->inner() != parent) { + // If we destroyed _webview ourselves, + // or if we changed _widget->inner ourselves, + // we don't show any message, nothing crashed. + return; + } crl::on_main(this, [=] { showCriticalError({ "Error: WebView has crashed." }); }); diff --git a/Telegram/SourceFiles/window/window.style b/Telegram/SourceFiles/window/window.style index d15a67a4ed9d2c..38621c69bc6c4c 100644 --- a/Telegram/SourceFiles/window/window.style +++ b/Telegram/SourceFiles/window/window.style @@ -317,6 +317,10 @@ windowArchiveToast: Toast(defaultToast) { maxWidth: boxWideWidth; } +// Windows specific + +winQuitIcon: icon {{ "win_quit", windowFg }}; + // Mac specific macAccessoryWidth: 450.; diff --git a/Telegram/ThirdParty/minizip/crypt.h b/Telegram/ThirdParty/minizip/crypt.h index 1cc41f19d78ddf..f4b93b78dc31cc 100644 --- a/Telegram/ThirdParty/minizip/crypt.h +++ b/Telegram/ThirdParty/minizip/crypt.h @@ -32,8 +32,7 @@ /*********************************************************************** * Return the next byte in the pseudo-random sequence */ -static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab) -{ +static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab) { unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an * unpredictable manner on 16-bit systems; not a problem * with any known compiler so far, though */ @@ -46,8 +45,7 @@ static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab) /*********************************************************************** * Update the encryption keys with the next byte of plain text */ -static int update_keys(unsigned long* pkeys,const z_crc_t* pcrc_32_tab,int c) -{ +static int update_keys(unsigned long* pkeys, const z_crc_t* pcrc_32_tab, int c) { (*(pkeys+0)) = CRC32((*(pkeys+0)), c); (*(pkeys+1)) += (*(pkeys+0)) & 0xff; (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; @@ -63,8 +61,7 @@ static int update_keys(unsigned long* pkeys,const z_crc_t* pcrc_32_tab,int c) * Initialize the encryption keys and the random header according to * the given password. */ -static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t* pcrc_32_tab) -{ +static void init_keys(const char* passwd, unsigned long* pkeys, const z_crc_t* pcrc_32_tab) { *(pkeys+0) = 305419896L; *(pkeys+1) = 591751049L; *(pkeys+2) = 878082192L; @@ -93,8 +90,7 @@ static unsigned crypthead(const char* passwd, /* password string */ int bufSize, unsigned long* pkeys, const z_crc_t* pcrc_32_tab, - unsigned long crcForCrypting) -{ + unsigned long crcForCrypting) { unsigned n; /* index in random header */ int t; /* temporary */ int c; /* random byte */ diff --git a/Telegram/ThirdParty/minizip/ioapi.c b/Telegram/ThirdParty/minizip/ioapi.c index 0ca29db6af61c3..782d32469ae5d5 100644 --- a/Telegram/ThirdParty/minizip/ioapi.c +++ b/Telegram/ThirdParty/minizip/ioapi.c @@ -14,7 +14,7 @@ #define _CRT_SECURE_NO_WARNINGS #endif -#if defined(__APPLE__) || defined(IOAPI_NO_64) +#if defined(__APPLE__) || defined(IOAPI_NO_64) || defined(__HAIKU__) || defined(MINIZIP_FOPEN_NO_64) // In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions #define FOPEN_FUNC(filename, mode) fopen(filename, mode) #define FTELLO_FUNC(stream) ftello(stream) @@ -28,8 +28,7 @@ #include "ioapi.h" -voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode) -{ +voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc, const void*filename, int mode) { if (pfilefunc->zfile_func64.zopen64_file != NULL) return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode); else @@ -38,8 +37,7 @@ voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename } } -long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) -{ +long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) { if (pfilefunc->zfile_func64.zseek64_file != NULL) return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin); else @@ -52,8 +50,7 @@ long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZP } } -ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream) -{ +ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc, voidpf filestream) { if (pfilefunc->zfile_func64.zseek64_file != NULL) return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); else @@ -66,11 +63,9 @@ ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream } } -void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32) -{ +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32, const zlib_filefunc_def* p_filefunc32) { p_filefunc64_32->zfile_func64.zopen64_file = NULL; p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; - p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; p_filefunc64_32->zfile_func64.ztell64_file = NULL; @@ -84,16 +79,7 @@ void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filef -static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode)); -static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); -static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size)); -static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream)); -static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); -static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream)); -static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); - -static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode) -{ +static voidpf ZCALLBACK fopen_file_func(voidpf opaque, const char* filename, int mode) { FILE* file = NULL; const char* mode_fopen = NULL; (void)opaque; @@ -111,8 +97,7 @@ static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, in return file; } -static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode) -{ +static voidpf ZCALLBACK fopen64_file_func(voidpf opaque, const void* filename, int mode) { FILE* file = NULL; const char* mode_fopen = NULL; (void)opaque; @@ -131,24 +116,21 @@ static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, } -static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) -{ +static uLong ZCALLBACK fread_file_func(voidpf opaque, voidpf stream, void* buf, uLong size) { uLong ret; (void)opaque; ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); return ret; } -static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size) -{ +static uLong ZCALLBACK fwrite_file_func(voidpf opaque, voidpf stream, const void* buf, uLong size) { uLong ret; (void)opaque; ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); return ret; } -static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) -{ +static long ZCALLBACK ftell_file_func(voidpf opaque, voidpf stream) { long ret; (void)opaque; ret = ftell((FILE *)stream); @@ -156,16 +138,14 @@ static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) } -static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) -{ +static ZPOS64_T ZCALLBACK ftell64_file_func(voidpf opaque, voidpf stream) { ZPOS64_T ret; (void)opaque; ret = (ZPOS64_T)FTELLO_FUNC((FILE *)stream); return ret; } -static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin) -{ +static long ZCALLBACK fseek_file_func(voidpf opaque, voidpf stream, uLong offset, int origin) { int fseek_origin=0; long ret; (void)opaque; @@ -188,8 +168,7 @@ static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offs return ret; } -static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) -{ +static long ZCALLBACK fseek64_file_func(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) { int fseek_origin=0; long ret; (void)opaque; @@ -208,31 +187,28 @@ static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T } ret = 0; - if(FSEEKO_FUNC((FILE *)stream, (z_off_t)offset, fseek_origin) != 0) + if(FSEEKO_FUNC((FILE *)stream, (z_off64_t)offset, fseek_origin) != 0) ret = -1; return ret; } -static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) -{ +static int ZCALLBACK fclose_file_func(voidpf opaque, voidpf stream) { int ret; (void)opaque; ret = fclose((FILE *)stream); return ret; } -static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream) -{ +static int ZCALLBACK ferror_file_func(voidpf opaque, voidpf stream) { int ret; (void)opaque; ret = ferror((FILE *)stream); return ret; } -void fill_fopen_filefunc (zlib_filefunc_def* pzlib_filefunc_def) -{ +void fill_fopen_filefunc(zlib_filefunc_def* pzlib_filefunc_def) { pzlib_filefunc_def->zopen_file = fopen_file_func; pzlib_filefunc_def->zread_file = fread_file_func; pzlib_filefunc_def->zwrite_file = fwrite_file_func; @@ -243,8 +219,7 @@ void fill_fopen_filefunc (zlib_filefunc_def* pzlib_filefunc_def) pzlib_filefunc_def->opaque = NULL; } -void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def) -{ +void fill_fopen64_filefunc(zlib_filefunc64_def* pzlib_filefunc_def) { pzlib_filefunc_def->zopen64_file = fopen64_file_func; pzlib_filefunc_def->zread_file = fread_file_func; pzlib_filefunc_def->zwrite_file = fwrite_file_func; diff --git a/Telegram/ThirdParty/minizip/ioapi.h b/Telegram/ThirdParty/minizip/ioapi.h index ae9ca7e8337d2f..a2d2e6e60d9250 100644 --- a/Telegram/ThirdParty/minizip/ioapi.h +++ b/Telegram/ThirdParty/minizip/ioapi.h @@ -50,7 +50,7 @@ #define ftello64 ftell #define fseeko64 fseek #else -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__) || defined(MINIZIP_FOPEN_NO_64) #define fopen64 fopen #define ftello64 ftello #define fseeko64 fseeko @@ -82,7 +82,7 @@ #include "mz64conf.h" #endif -/* a type choosen by DEFINE */ +/* a type chosen by DEFINE */ #ifdef HAVE_64BIT_INT_CUSTOM typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; #else @@ -134,17 +134,17 @@ extern "C" { -typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); -typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); -typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); -typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); -typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); +typedef voidpf (ZCALLBACK *open_file_func) (voidpf opaque, const char* filename, int mode); +typedef uLong (ZCALLBACK *read_file_func) (voidpf opaque, voidpf stream, void* buf, uLong size); +typedef uLong (ZCALLBACK *write_file_func) (voidpf opaque, voidpf stream, const void* buf, uLong size); +typedef int (ZCALLBACK *close_file_func) (voidpf opaque, voidpf stream); +typedef int (ZCALLBACK *testerror_file_func) (voidpf opaque, voidpf stream); -typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); -typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); +typedef long (ZCALLBACK *tell_file_func) (voidpf opaque, voidpf stream); +typedef long (ZCALLBACK *seek_file_func) (voidpf opaque, voidpf stream, uLong offset, int origin); -/* here is the "old" 32 bits structure structure */ +/* here is the "old" 32 bits structure */ typedef struct zlib_filefunc_def_s { open_file_func zopen_file; @@ -157,9 +157,9 @@ typedef struct zlib_filefunc_def_s voidpf opaque; } zlib_filefunc_def; -typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); -typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); -typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode)); +typedef ZPOS64_T (ZCALLBACK *tell64_file_func) (voidpf opaque, voidpf stream); +typedef long (ZCALLBACK *seek64_file_func) (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin); +typedef voidpf (ZCALLBACK *open64_file_func) (voidpf opaque, const void* filename, int mode); typedef struct zlib_filefunc64_def_s { @@ -173,8 +173,8 @@ typedef struct zlib_filefunc64_def_s voidpf opaque; } zlib_filefunc64_def; -void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); -void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); +void fill_fopen64_filefunc(zlib_filefunc64_def* pzlib_filefunc_def); +void fill_fopen_filefunc(zlib_filefunc_def* pzlib_filefunc_def); /* now internal definition, only for zip.c and unzip.h */ typedef struct zlib_filefunc64_32_def_s @@ -193,11 +193,11 @@ typedef struct zlib_filefunc64_32_def_s #define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) #define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) -voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)); -long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); -ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)); +voidpf call_zopen64(const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode); +long call_zseek64(const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin); +ZPOS64_T call_ztell64(const zlib_filefunc64_32_def* pfilefunc,voidpf filestream); -void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); #define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) #define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) diff --git a/Telegram/ThirdParty/minizip/unzip.c b/Telegram/ThirdParty/minizip/unzip.c index 3036b470b72b83..ed763f89f1f87d 100644 --- a/Telegram/ThirdParty/minizip/unzip.c +++ b/Telegram/ThirdParty/minizip/unzip.c @@ -49,12 +49,12 @@ Copyright (C) 2007-2008 Even Rouault - Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again). + Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again). Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G should only read the compressed/uncompressed size from the Zip64 format if the size from normal header was 0xFFFFFFFF - Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant - Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required) + Oct-2009 - Mathias Svensson - Applied some bug fixes from patches received from Gilles Vollant + Oct-2009 - Mathias Svensson - Applied support to unzip files with compression method BZIP2 (bzip2 lib is required) Patch created by Daniel Borca Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer @@ -77,8 +77,6 @@ #ifdef STDC # include -# include -# include #endif #ifdef NO_ERRNO_H extern int errno; @@ -111,9 +109,6 @@ #ifndef ALLOC # define ALLOC(size) (malloc(size)) #endif -#ifndef TRYFREE -# define TRYFREE(p) { free(p);} -#endif #define SIZECENTRALDIRITEM (0x2e) #define SIZEZIPLOCALHEADER (0x1e) @@ -153,7 +148,7 @@ typedef struct ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ zlib_filefunc64_32_def z_filefunc; - voidpf filestream; /* io structore of the zipfile */ + voidpf filestream; /* io structure of the zipfile */ uLong compression_method; /* compression method (0==store) */ ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ int raw; @@ -166,7 +161,7 @@ typedef struct { zlib_filefunc64_32_def z_filefunc; int is64bitOpenFunction; - voidpf filestream; /* io structore of the zipfile */ + voidpf filestream; /* io structure of the zipfile */ unz_global_info64 gi; /* public global information */ ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ ZPOS64_T num_file; /* number of the current file in the zipfile*/ @@ -197,29 +192,24 @@ typedef struct #include "crypt.h" #endif + /* =========================================================================== - Read a byte from a gz_stream; update next_in and avail_in. Return EOF - for end of file. - IN assertion: the stream s has been successfully opened for reading. + Reads a long in LSB order from the given gz_stream. Sets */ - -local int unz64local_getByte OF(( - const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - int *pi)); - -local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi) -{ - unsigned char c; - int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); - if (err==1) +local int unz64local_getShort(const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) { + unsigned char c[2]; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,c,2); + if (err==2) { - *pi = (int)c; + *pX = c[0] | ((uLong)c[1] << 8); return UNZ_OK; } else { + *pX = 0; if (ZERROR64(*pzlib_filefunc_def,filestream)) return UNZ_ERRNO; else @@ -227,127 +217,50 @@ local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, v } } - -/* =========================================================================== - Reads a long in LSB order from the given gz_stream. Sets -*/ -local int unz64local_getShort OF(( - const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX)); - -local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, +local int unz64local_getLong(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, - uLong *pX) -{ - uLong x ; - int i = 0; - int err; - - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x = (uLong)i; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((uLong)i)<<8; - - if (err==UNZ_OK) - *pX = x; - else - *pX = 0; - return err; -} - -local int unz64local_getLong OF(( - const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX)); - -local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX) -{ - uLong x ; - int i = 0; - int err; - - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x = (uLong)i; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((uLong)i)<<8; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((uLong)i)<<16; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<24; - - if (err==UNZ_OK) - *pX = x; + uLong *pX) { + unsigned char c[4]; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,c,4); + if (err==4) + { + *pX = c[0] | ((uLong)c[1] << 8) | ((uLong)c[2] << 16) | ((uLong)c[3] << 24); + return UNZ_OK; + } else + { *pX = 0; - return err; + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } } -local int unz64local_getLong64 OF(( - const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - ZPOS64_T *pX)); - - -local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - ZPOS64_T *pX) -{ - ZPOS64_T x ; - int i = 0; - int err; - - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x = (ZPOS64_T)i; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<8; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<16; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<24; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<32; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<40; - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<48; - - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<56; - - if (err==UNZ_OK) - *pX = x; +local int unz64local_getLong64(const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T *pX) { + unsigned char c[8]; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,c,8); + if (err==8) + { + *pX = c[0] | ((ZPOS64_T)c[1] << 8) | ((ZPOS64_T)c[2] << 16) | ((ZPOS64_T)c[3] << 24) + | ((ZPOS64_T)c[4] << 32) | ((ZPOS64_T)c[5] << 40) | ((ZPOS64_T)c[6] << 48) | ((ZPOS64_T)c[7] << 56); + return UNZ_OK; + } else + { *pX = 0; - return err; + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } } /* My own strcmpi / strcasecmp */ -local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) -{ +local int strcmpcasenosensitive_internal(const char* fileName1, const char* fileName2) { for (;;) { char c1=*(fileName1++); @@ -379,19 +292,17 @@ local int strcmpcasenosensitive_internal (const char* fileName1, const char* fil #endif /* - Compare two filename (fileName1,fileName2). - If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) - If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + Compare two filenames (fileName1,fileName2). + If iCaseSensitivity = 1, comparison is case sensitive (like strcmp) + If iCaseSensitivity = 2, comparison is not case sensitive (like strcmpi or strcasecmp) - If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + If iCaseSensitivity = 0, case sensitivity is default of your operating system (like 1 on Unix, 2 on Windows) */ extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, - const char* fileName2, - int iCaseSensitivity) - -{ + const char* fileName2, + int iCaseSensitivity) { if (iCaseSensitivity==0) iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; @@ -405,21 +316,23 @@ extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, #define BUFREADCOMMENT (0x400) #endif +#ifndef CENTRALDIRINVALID +#define CENTRALDIRINVALID ((ZPOS64_T)(-1)) +#endif + /* Locate the Central directory of a zipfile (at the end, just before the global comment) */ -local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); -local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) -{ +local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { unsigned char* buf; ZPOS64_T uSizeFile; ZPOS64_T uBackRead; ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ - ZPOS64_T uPosFound=0; + ZPOS64_T uPosFound=CENTRALDIRINVALID; if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; + return CENTRALDIRINVALID; uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); @@ -429,7 +342,7 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); if (buf==NULL) - return 0; + return CENTRALDIRINVALID; uBackRead = 4; while (uBackReadz_filefunc, s->filestream); - TRYFREE(s); + free(s); return UNZ_OK; } @@ -825,8 +727,7 @@ extern int ZEXPORT unzClose (unzFile file) Write info about the ZipFile in the *pglobal_info structure. No preparation of the structure is needed return UNZ_OK if there is no problem. */ -extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info) -{ +extern int ZEXPORT unzGetGlobalInfo64(unzFile file, unz_global_info64* pglobal_info) { unz64_s* s; if (file==NULL) return UNZ_PARAMERROR; @@ -835,8 +736,7 @@ extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_ return UNZ_OK; } -extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32) -{ +extern int ZEXPORT unzGetGlobalInfo(unzFile file, unz_global_info* pglobal_info32) { unz64_s* s; if (file==NULL) return UNZ_PARAMERROR; @@ -847,10 +747,9 @@ extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info return UNZ_OK; } /* - Translate date/time from Dos format to tm_unz (readable more easilty) + Translate date/time from Dos format to tm_unz (readable more easily) */ -local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) -{ +local void unz64local_DosDateToTmuDate(ZPOS64_T ulDosDate, tm_unz* ptm) { ZPOS64_T uDate; uDate = (ZPOS64_T)(ulDosDate>>16); ptm->tm_mday = (int)(uDate&0x1f) ; @@ -865,28 +764,16 @@ local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) /* Get Info about the current file in the zipfile, with internal only info */ -local int unz64local_GetCurrentFileInfoInternal OF((unzFile file, - unz_file_info64 *pfile_info, - unz_file_info64_internal - *pfile_info_internal, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize)); - -local int unz64local_GetCurrentFileInfoInternal (unzFile file, - unz_file_info64 *pfile_info, - unz_file_info64_internal - *pfile_info_internal, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize) -{ +local int unz64local_GetCurrentFileInfoInternal(unzFile file, + unz_file_info64 *pfile_info, + unz_file_info64_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize) { unz64_s* s; unz_file_info64 file_info; unz_file_info64_internal file_info_internal; @@ -1038,33 +925,31 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file, /* ZIP64 extra fields */ if (headerId == 0x0001) { - uLong uL; - - if(file_info.uncompressed_size == MAXU32) - { - if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) - err=UNZ_ERRNO; - } - - if(file_info.compressed_size == MAXU32) - { - if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) - err=UNZ_ERRNO; - } - - if(file_info_internal.offset_curfile == MAXU32) - { - /* Relative Header offset */ - if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) - err=UNZ_ERRNO; - } - - if(file_info.disk_num_start == MAXU32) - { - /* Disk Start Number */ - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) - err=UNZ_ERRNO; - } + if(file_info.uncompressed_size == MAXU32) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.compressed_size == MAXU32) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info_internal.offset_curfile == MAXU32) + { + /* Relative Header offset */ + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.disk_num_start == 0xffff) + { + /* Disk Start Number */ + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + } } else @@ -1121,24 +1006,22 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file, No preparation of the structure is needed return UNZ_OK if there is no problem. */ -extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file, - unz_file_info64 * pfile_info, - char * szFileName, uLong fileNameBufferSize, - void *extraField, uLong extraFieldBufferSize, - char* szComment, uLong commentBufferSize) -{ +extern int ZEXPORT unzGetCurrentFileInfo64(unzFile file, + unz_file_info64 * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) { return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, - szFileName,fileNameBufferSize, - extraField,extraFieldBufferSize, - szComment,commentBufferSize); + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); } -extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, - unz_file_info * pfile_info, - char * szFileName, uLong fileNameBufferSize, - void *extraField, uLong extraFieldBufferSize, - char* szComment, uLong commentBufferSize) -{ +extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, + unz_file_info * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) { int err; unz_file_info64 file_info64; err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, @@ -1162,7 +1045,7 @@ extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, pfile_info->internal_fa = file_info64.internal_fa; pfile_info->external_fa = file_info64.external_fa; - pfile_info->tmu_date = file_info64.tmu_date, + pfile_info->tmu_date = file_info64.tmu_date; pfile_info->compressed_size = (uLong)file_info64.compressed_size; @@ -1175,8 +1058,7 @@ extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, Set the current file of the zipfile to the first file. return UNZ_OK if there is no problem */ -extern int ZEXPORT unzGoToFirstFile (unzFile file) -{ +extern int ZEXPORT unzGoToFirstFile(unzFile file) { int err=UNZ_OK; unz64_s* s; if (file==NULL) @@ -1196,8 +1078,7 @@ extern int ZEXPORT unzGoToFirstFile (unzFile file) return UNZ_OK if there is no problem return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. */ -extern int ZEXPORT unzGoToNextFile (unzFile file) -{ +extern int ZEXPORT unzGoToNextFile(unzFile file) { unz64_s* s; int err; @@ -1229,8 +1110,7 @@ extern int ZEXPORT unzGoToNextFile (unzFile file) UNZ_OK if the file is found. It becomes the current file. UNZ_END_OF_LIST_OF_FILE if the file is not found */ -extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) -{ +extern int ZEXPORT unzLocateFile(unzFile file, const char *szFileName, int iCaseSensitivity) { unz64_s* s; int err; @@ -1305,8 +1185,7 @@ typedef struct unz_file_pos_s } unz_file_pos; */ -extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) -{ +extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) { unz64_s* s; if (file==NULL || file_pos==NULL) @@ -1321,10 +1200,7 @@ extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) return UNZ_OK; } -extern int ZEXPORT unzGetFilePos( - unzFile file, - unz_file_pos* file_pos) -{ +extern int ZEXPORT unzGetFilePos(unzFile file, unz_file_pos* file_pos) { unz64_file_pos file_pos64; int err = unzGetFilePos64(file,&file_pos64); if (err==UNZ_OK) @@ -1335,8 +1211,7 @@ extern int ZEXPORT unzGetFilePos( return err; } -extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) -{ +extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) { unz64_s* s; int err; @@ -1357,10 +1232,7 @@ extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos return err; } -extern int ZEXPORT unzGoToFilePos( - unzFile file, - unz_file_pos* file_pos) -{ +extern int ZEXPORT unzGoToFilePos(unzFile file, unz_file_pos* file_pos) { unz64_file_pos file_pos64; if (file_pos == NULL) return UNZ_PARAMERROR; @@ -1382,10 +1254,9 @@ extern int ZEXPORT unzGoToFilePos( store in *piSizeVar the size of extra info in local header (filename and size of extra field data) */ -local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar, - ZPOS64_T * poffset_local_extrafield, - uInt * psize_local_extrafield) -{ +local int unz64local_CheckCurrentFileCoherencyHeader(unz64_s* s, uInt* piSizeVar, + ZPOS64_T * poffset_local_extrafield, + uInt * psize_local_extrafield) { uLong uMagic,uData,uFlags; uLong size_filename; uLong size_extra_field; @@ -1469,9 +1340,8 @@ local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVa Open for reading data the current file in the zipfile. If there is no error and the file is opened, the return value is UNZ_OK. */ -extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, - int* level, int raw, const char* password) -{ +extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int* method, + int* level, int raw, const char* password) { int err=UNZ_OK; uInt iSizeVar; unz64_s* s; @@ -1509,7 +1379,7 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, if (pfile_in_zip_read_info->read_buffer==NULL) { - TRYFREE(pfile_in_zip_read_info); + free(pfile_in_zip_read_info); return UNZ_INTERNALERROR; } @@ -1566,8 +1436,8 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; else { - TRYFREE(pfile_in_zip_read_info->read_buffer); - TRYFREE(pfile_in_zip_read_info); + free(pfile_in_zip_read_info->read_buffer); + free(pfile_in_zip_read_info); return err; } #else @@ -1587,8 +1457,8 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; else { - TRYFREE(pfile_in_zip_read_info->read_buffer); - TRYFREE(pfile_in_zip_read_info); + free(pfile_in_zip_read_info->read_buffer); + free(pfile_in_zip_read_info); return err; } /* windowBits is passed < 0 to tell that there is no zlib header. @@ -1640,25 +1510,21 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, return UNZ_OK; } -extern int ZEXPORT unzOpenCurrentFile (unzFile file) -{ +extern int ZEXPORT unzOpenCurrentFile(unzFile file) { return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); } -extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password) -{ +extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, const char* password) { return unzOpenCurrentFile3(file, NULL, NULL, 0, password); } -extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw) -{ +extern int ZEXPORT unzOpenCurrentFile2(unzFile file, int* method, int* level, int raw) { return unzOpenCurrentFile3(file, method, level, raw, NULL); } /** Addition for GDAL : START */ -extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) -{ +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64(unzFile file) { unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; s=(unz64_s*)file; @@ -1678,13 +1544,12 @@ extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) buf contain buffer where data must be copied len the size of buf. - return the number of byte copied if somes bytes are copied + return the number of byte copied if some bytes are copied return 0 if the end of file was reached return <0 with error code if there is an error (UNZ_ERRNO for IO error, or zLib error for uncompress error) */ -extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) -{ +extern int ZEXPORT unzReadCurrentFile(unzFile file, voidp buf, unsigned len) { int err=UNZ_OK; uInt iRead = 0; unz64_s* s; @@ -1891,8 +1756,7 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) /* Give the current position in uncompressed data */ -extern z_off_t ZEXPORT unztell (unzFile file) -{ +extern z_off_t ZEXPORT unztell(unzFile file) { unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; if (file==NULL) @@ -1906,8 +1770,7 @@ extern z_off_t ZEXPORT unztell (unzFile file) return (z_off_t)pfile_in_zip_read_info->stream.total_out; } -extern ZPOS64_T ZEXPORT unztell64 (unzFile file) -{ +extern ZPOS64_T ZEXPORT unztell64(unzFile file) { unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; @@ -1926,8 +1789,7 @@ extern ZPOS64_T ZEXPORT unztell64 (unzFile file) /* return 1 if the end of file was reached, 0 elsewhere */ -extern int ZEXPORT unzeof (unzFile file) -{ +extern int ZEXPORT unzeof(unzFile file) { unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; if (file==NULL) @@ -1958,8 +1820,7 @@ more info in the local-header version than in the central-header) the return value is the number of bytes copied in buf, or (if <0) the error code */ -extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) -{ +extern int ZEXPORT unzGetLocalExtrafield(unzFile file, voidp buf, unsigned len) { unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; uInt read_now; @@ -2006,8 +1867,7 @@ extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) Close the file in zip opened with unzOpenCurrentFile Return UNZ_CRCERROR if all the file was read but the CRC is not good */ -extern int ZEXPORT unzCloseCurrentFile (unzFile file) -{ +extern int ZEXPORT unzCloseCurrentFile(unzFile file) { int err=UNZ_OK; unz64_s* s; @@ -2029,7 +1889,7 @@ extern int ZEXPORT unzCloseCurrentFile (unzFile file) } - TRYFREE(pfile_in_zip_read_info->read_buffer); + free(pfile_in_zip_read_info->read_buffer); pfile_in_zip_read_info->read_buffer = NULL; if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) inflateEnd(&pfile_in_zip_read_info->stream); @@ -2040,7 +1900,7 @@ extern int ZEXPORT unzCloseCurrentFile (unzFile file) pfile_in_zip_read_info->stream_initialised = 0; - TRYFREE(pfile_in_zip_read_info); + free(pfile_in_zip_read_info); s->pfile_in_zip_read=NULL; @@ -2053,8 +1913,7 @@ extern int ZEXPORT unzCloseCurrentFile (unzFile file) uSizeBuf is the size of the szComment buffer. return the number of byte copied or an error code <0 */ -extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf) -{ +extern int ZEXPORT unzGetGlobalComment(unzFile file, char * szComment, uLong uSizeBuf) { unz64_s* s; uLong uReadThis ; if (file==NULL) @@ -2081,8 +1940,7 @@ extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uS } /* Additions by RX '2004 */ -extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) -{ +extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) { unz64_s* s; if (file==NULL) @@ -2096,8 +1954,7 @@ extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) return s->pos_in_central_dir; } -extern uLong ZEXPORT unzGetOffset (unzFile file) -{ +extern uLong ZEXPORT unzGetOffset(unzFile file) { ZPOS64_T offset64; if (file==NULL) @@ -2106,8 +1963,7 @@ extern uLong ZEXPORT unzGetOffset (unzFile file) return (uLong)offset64; } -extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) -{ +extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) { unz64_s* s; int err; @@ -2124,7 +1980,6 @@ extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) return err; } -extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) -{ +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) { return unzSetOffset64(file,pos); } diff --git a/Telegram/ThirdParty/minizip/unzip.h b/Telegram/ThirdParty/minizip/unzip.h index 6f95e94d7568f6..14105840f6d247 100644 --- a/Telegram/ThirdParty/minizip/unzip.h +++ b/Telegram/ThirdParty/minizip/unzip.h @@ -150,21 +150,21 @@ typedef struct unz_file_info_s tm_unz tmu_date; } unz_file_info; -extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, - const char* fileName2, - int iCaseSensitivity)); +extern int ZEXPORT unzStringFileNameCompare(const char* fileName1, + const char* fileName2, + int iCaseSensitivity); /* - Compare two filename (fileName1,fileName2). - If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) - If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + Compare two filenames (fileName1,fileName2). + If iCaseSensitivity = 1, comparison is case sensitive (like strcmp) + If iCaseSensitivity = 2, comparison is not case sensitive (like strcmpi or strcasecmp) - If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + If iCaseSensitivity = 0, case sensitivity is default of your operating system (like 1 on Unix, 2 on Windows) */ -extern unzFile ZEXPORT unzOpen OF((const char *path)); -extern unzFile ZEXPORT unzOpen64 OF((const void *path)); +extern unzFile ZEXPORT unzOpen(const char *path); +extern unzFile ZEXPORT unzOpen64(const void *path); /* Open a Zip file. path contain the full pathname (by example, on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer @@ -181,41 +181,41 @@ extern unzFile ZEXPORT unzOpen64 OF((const void *path)); */ -extern unzFile ZEXPORT unzOpen2 OF((const char *path, - zlib_filefunc_def* pzlib_filefunc_def)); +extern unzFile ZEXPORT unzOpen2(const char *path, + zlib_filefunc_def* pzlib_filefunc_def); /* Open a Zip file, like unzOpen, but provide a set of file low level API for read/write the zip file (see ioapi.h) */ -extern unzFile ZEXPORT unzOpen2_64 OF((const void *path, - zlib_filefunc64_def* pzlib_filefunc_def)); +extern unzFile ZEXPORT unzOpen2_64(const void *path, + zlib_filefunc64_def* pzlib_filefunc_def); /* Open a Zip file, like unz64Open, but provide a set of file low level API for read/write the zip file (see ioapi.h) */ -extern int ZEXPORT unzClose OF((unzFile file)); +extern int ZEXPORT unzClose(unzFile file); /* Close a ZipFile opened with unzOpen. If there is files inside the .Zip opened with unzOpenCurrentFile (see later), these files MUST be closed with unzCloseCurrentFile before call unzClose. return UNZ_OK if there is no problem. */ -extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, - unz_global_info *pglobal_info)); +extern int ZEXPORT unzGetGlobalInfo(unzFile file, + unz_global_info *pglobal_info); -extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, - unz_global_info64 *pglobal_info)); +extern int ZEXPORT unzGetGlobalInfo64(unzFile file, + unz_global_info64 *pglobal_info); /* Write info about the ZipFile in the *pglobal_info structure. No preparation of the structure is needed return UNZ_OK if there is no problem. */ -extern int ZEXPORT unzGetGlobalComment OF((unzFile file, - char *szComment, - uLong uSizeBuf)); +extern int ZEXPORT unzGetGlobalComment(unzFile file, + char *szComment, + uLong uSizeBuf); /* Get the global comment string of the ZipFile, in the szComment buffer. uSizeBuf is the size of the szComment buffer. @@ -226,22 +226,22 @@ extern int ZEXPORT unzGetGlobalComment OF((unzFile file, /***************************************************************************/ /* Unzip package allow you browse the directory of the zipfile */ -extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); +extern int ZEXPORT unzGoToFirstFile(unzFile file); /* Set the current file of the zipfile to the first file. return UNZ_OK if there is no problem */ -extern int ZEXPORT unzGoToNextFile OF((unzFile file)); +extern int ZEXPORT unzGoToNextFile(unzFile file); /* Set the current file of the zipfile to the next file. return UNZ_OK if there is no problem return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. */ -extern int ZEXPORT unzLocateFile OF((unzFile file, - const char *szFileName, - int iCaseSensitivity)); +extern int ZEXPORT unzLocateFile(unzFile file, + const char *szFileName, + int iCaseSensitivity); /* Try locate the file szFileName in the zipfile. For the iCaseSensitivity signification, see unzStringFileNameCompare @@ -285,26 +285,26 @@ extern int ZEXPORT unzGoToFilePos64( /* ****************************************** */ -extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file, - unz_file_info64 *pfile_info, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize)); - -extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, - unz_file_info *pfile_info, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize)); +extern int ZEXPORT unzGetCurrentFileInfo64(unzFile file, + unz_file_info64 *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize); + +extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize); /* Get Info about the current file - if pfile_info!=NULL, the *pfile_info structure will contain somes info about + if pfile_info!=NULL, the *pfile_info structure will contain some info about the current file if szFileName!=NULL, the filemane string will be copied in szFileName (fileNameBufferSize is the size of the buffer) @@ -318,7 +318,7 @@ extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, /** Addition for GDAL : START */ -extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64(unzFile file); /** Addition for GDAL : END */ @@ -328,24 +328,24 @@ extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); from it, and close it (you can close it before reading all the file) */ -extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); +extern int ZEXPORT unzOpenCurrentFile(unzFile file); /* Open for reading data the current file in the zipfile. If there is no error, the return value is UNZ_OK. */ -extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, - const char* password)); +extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, + const char* password); /* Open for reading data the current file in the zipfile. password is a crypting password If there is no error, the return value is UNZ_OK. */ -extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, - int* method, - int* level, - int raw)); +extern int ZEXPORT unzOpenCurrentFile2(unzFile file, + int* method, + int* level, + int raw); /* Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) if raw==1 @@ -355,11 +355,11 @@ extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, but you CANNOT set method parameter as NULL */ -extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, - int* method, - int* level, - int raw, - const char* password)); +extern int ZEXPORT unzOpenCurrentFile3(unzFile file, + int* method, + int* level, + int raw, + const char* password); /* Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) if raw==1 @@ -370,41 +370,41 @@ extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, */ -extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); +extern int ZEXPORT unzCloseCurrentFile(unzFile file); /* Close the file in zip opened with unzOpenCurrentFile Return UNZ_CRCERROR if all the file was read but the CRC is not good */ -extern int ZEXPORT unzReadCurrentFile OF((unzFile file, - voidp buf, - unsigned len)); +extern int ZEXPORT unzReadCurrentFile(unzFile file, + voidp buf, + unsigned len); /* Read bytes from the current file (opened by unzOpenCurrentFile) buf contain buffer where data must be copied len the size of buf. - return the number of byte copied if somes bytes are copied + return the number of byte copied if some bytes are copied return 0 if the end of file was reached return <0 with error code if there is an error (UNZ_ERRNO for IO error, or zLib error for uncompress error) */ -extern z_off_t ZEXPORT unztell OF((unzFile file)); +extern z_off_t ZEXPORT unztell(unzFile file); -extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file)); +extern ZPOS64_T ZEXPORT unztell64(unzFile file); /* Give the current position in uncompressed data */ -extern int ZEXPORT unzeof OF((unzFile file)); +extern int ZEXPORT unzeof(unzFile file); /* return 1 if the end of file was reached, 0 elsewhere */ -extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, - voidp buf, - unsigned len)); +extern int ZEXPORT unzGetLocalExtrafield(unzFile file, + voidp buf, + unsigned len); /* Read extra field from the current file (opened by unzOpenCurrentFile) This is the local-header version of the extra field (sometimes, there is diff --git a/Telegram/ThirdParty/minizip/zip.c b/Telegram/ThirdParty/minizip/zip.c index 66d693f85a5809..e2e9da07c5f307 100644 --- a/Telegram/ThirdParty/minizip/zip.c +++ b/Telegram/ThirdParty/minizip/zip.c @@ -14,7 +14,7 @@ Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions. Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data - It is used when recreting zip archive with RAW when deleting items from a zip. + It is used when recreating zip archive with RAW when deleting items from a zip. ZIP64 data is automatically added to items that needs it, and existing ZIP64 data need to be removed. Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required) Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer @@ -25,14 +25,13 @@ #include #include #include +#include #include #include "zlib.h" #include "zip.h" #ifdef STDC # include -# include -# include #endif #ifdef NO_ERRNO_H extern int errno; @@ -47,7 +46,7 @@ /* compile with -Dlocal if your debugger can't find static symbols */ #ifndef VERSIONMADEBY -# define VERSIONMADEBY (0x0) /* platform depedent */ +# define VERSIONMADEBY (0x0) /* platform dependent */ #endif #ifndef Z_BUFSIZE @@ -61,9 +60,6 @@ #ifndef ALLOC # define ALLOC(size) (malloc(size)) #endif -#ifndef TRYFREE -# define TRYFREE(p) {if (p) free(p);} -#endif /* #define SIZECENTRALDIRITEM (0x2e) @@ -138,20 +134,20 @@ typedef struct uInt pos_in_buffered_data; /* last written byte in buffered_data */ ZPOS64_T pos_local_header; /* offset of the local header of the file - currenty writing */ + currently writing */ char* central_header; /* central header data for the current file */ uLong size_centralExtra; uLong size_centralheader; /* size of the central header for cur file */ uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */ uLong flag; /* flag of the file currently writing */ - int method; /* compression method of file currenty wr.*/ + int method; /* compression method of file currently wr.*/ int raw; /* 1 for directly writing raw data */ Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ uLong dosDate; uLong crc32; int encrypt; - int zip64; /* Add ZIP64 extened information in the extra field */ + int zip64; /* Add ZIP64 extended information in the extra field */ ZPOS64_T pos_zip64extrainfo; ZPOS64_T totalCompressedData; ZPOS64_T totalUncompressedData; @@ -165,10 +161,10 @@ typedef struct typedef struct { zlib_filefunc64_32_def z_filefunc; - voidpf filestream; /* io structore of the zipfile */ + voidpf filestream; /* io structure of the zipfile */ linkedlist_data central_dir;/* datablock with central dir in construction*/ int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ - curfile64_info ci; /* info on the file curretly writing */ + curfile64_info ci; /* info on the file currently writing */ ZPOS64_T begin_pos; /* position of the beginning of the zipfile */ ZPOS64_T add_position_when_writing_offset; @@ -186,8 +182,7 @@ typedef struct #include "crypt.h" #endif -local linkedlist_datablock_internal* allocate_new_datablock() -{ +local linkedlist_datablock_internal* allocate_new_datablock(void) { linkedlist_datablock_internal* ldi; ldi = (linkedlist_datablock_internal*) ALLOC(sizeof(linkedlist_datablock_internal)); @@ -200,30 +195,26 @@ local linkedlist_datablock_internal* allocate_new_datablock() return ldi; } -local void free_datablock(linkedlist_datablock_internal* ldi) -{ +local void free_datablock(linkedlist_datablock_internal* ldi) { while (ldi!=NULL) { linkedlist_datablock_internal* ldinext = ldi->next_datablock; - TRYFREE(ldi); + free(ldi); ldi = ldinext; } } -local void init_linkedlist(linkedlist_data* ll) -{ +local void init_linkedlist(linkedlist_data* ll) { ll->first_block = ll->last_block = NULL; } -local void free_linkedlist(linkedlist_data* ll) -{ +local void free_linkedlist(linkedlist_data* ll) { free_datablock(ll->first_block); ll->first_block = ll->last_block = NULL; } -local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) -{ +local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) { linkedlist_datablock_internal* ldi; const unsigned char* from_copy; @@ -238,7 +229,7 @@ local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) } ldi = ll->last_block; - from_copy = (unsigned char*)buf; + from_copy = (const unsigned char*)buf; while (len>0) { @@ -283,9 +274,7 @@ local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) */ -local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)); -local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) -{ +local int zip64local_putValue(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) { unsigned char buf[8]; int n; for (n = 0; n < nbByte; n++) @@ -307,9 +296,7 @@ local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, return ZIP_OK; } -local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte)); -local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) -{ +local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) { unsigned char* buf=(unsigned char*)dest; int n; for (n = 0; n < nbByte; n++) { @@ -329,8 +316,7 @@ local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) /****************************************************************************/ -local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) -{ +local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) { uLong year = (uLong)ptm->tm_year; if (year>=1980) year-=1980; @@ -344,10 +330,7 @@ local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) /****************************************************************************/ -local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)); - -local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi) -{ +local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int* pi) { unsigned char c; int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); if (err==1) @@ -368,10 +351,7 @@ local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,vo /* =========================================================================== Reads a long in LSB order from the given gz_stream. Sets */ -local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); - -local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) -{ +local int zip64local_getShort(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) { uLong x ; int i = 0; int err; @@ -390,10 +370,7 @@ local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, return err; } -local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); - -local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) -{ +local int zip64local_getLong(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) { uLong x ; int i = 0; int err; @@ -420,11 +397,8 @@ local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, return err; } -local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)); - -local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) -{ +local int zip64local_getLong64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) { ZPOS64_T x; int i = 0; int err; @@ -475,10 +449,7 @@ local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def Locate the Central directory of a zipfile (at the end, just before the global comment) */ -local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); - -local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) -{ +local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { unsigned char* buf; ZPOS64_T uSizeFile; ZPOS64_T uBackRead; @@ -529,7 +500,7 @@ local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f if (uPosFound!=0) break; } - TRYFREE(buf); + free(buf); return uPosFound; } @@ -537,10 +508,7 @@ local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before the global comment) */ -local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); - -local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) -{ +local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { unsigned char* buf; ZPOS64_T uSizeFile; ZPOS64_T uBackRead; @@ -595,7 +563,7 @@ local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib break; } - TRYFREE(buf); + free(buf); if (uPosFound == 0) return 0; @@ -637,8 +605,7 @@ local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib return relativeOffset; } -local int LoadCentralDirectoryRecord(zip64_internal* pziinit) -{ +local int LoadCentralDirectoryRecord(zip64_internal* pziinit) { int err=ZIP_OK; ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ @@ -647,10 +614,10 @@ local int LoadCentralDirectoryRecord(zip64_internal* pziinit) ZPOS64_T central_pos; uLong uL; - uLong number_disk; /* number of the current dist, used for - spaning ZIP, unsupported, always 0*/ - uLong number_disk_with_CD; /* number the the disk with central dir, used - for spaning ZIP, unsupported, always 0*/ + uLong number_disk; /* number of the current disk, used for + spanning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number of the disk with central dir, used + for spanning ZIP, unsupported, always 0*/ ZPOS64_T number_entry; ZPOS64_T number_entry_CD; /* total number of entries in the central dir @@ -830,7 +797,7 @@ local int LoadCentralDirectoryRecord(zip64_internal* pziinit) size_central_dir_to_read-=read_this; } - TRYFREE(buf_read); + free(buf_read); } pziinit->begin_pos = byte_before_the_zipfile; pziinit->number_entry = number_entry_CD; @@ -846,8 +813,7 @@ local int LoadCentralDirectoryRecord(zip64_internal* pziinit) /************************************************************/ -extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) -{ +extern zipFile ZEXPORT zipOpen3(const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) { zip64_internal ziinit; zip64_internal* zi; int err=ZIP_OK; @@ -905,9 +871,9 @@ extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* gl if (err != ZIP_OK) { # ifndef NO_ADDFILEINEXISTINGZIP - TRYFREE(ziinit.globalcomment); + free(ziinit.globalcomment); # endif /* !NO_ADDFILEINEXISTINGZIP*/ - TRYFREE(zi); + free(zi); return NULL; } else @@ -917,8 +883,7 @@ extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* gl } } -extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) -{ +extern zipFile ZEXPORT zipOpen2(const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) { if (pzlib_filefunc32_def != NULL) { zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; @@ -929,8 +894,7 @@ extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* gl return zipOpen3(pathname, append, globalcomment, NULL); } -extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) -{ +extern zipFile ZEXPORT zipOpen2_64(const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) { if (pzlib_filefunc_def != NULL) { zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; @@ -945,18 +909,15 @@ extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* -extern zipFile ZEXPORT zipOpen (const char* pathname, int append) -{ +extern zipFile ZEXPORT zipOpen(const char* pathname, int append) { return zipOpen3((const void*)pathname,append,NULL,NULL); } -extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append) -{ +extern zipFile ZEXPORT zipOpen64(const void* pathname, int append) { return zipOpen3(pathname,append,NULL,NULL); } -local int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) -{ +local int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) { /* write the local header */ int err; uInt size_filename = (uInt)strlen(filename); @@ -1052,14 +1013,13 @@ local int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt s It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize unnecessary allocations. */ -extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, - int windowBits,int memLevel, int strategy, - const char* password, uLong crcForCrypting, - uLong versionMadeBy, uLong flagBase, int zip64) -{ +extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase, int zip64) { zip64_internal* zi; uInt size_filename; uInt size_comment; @@ -1083,6 +1043,17 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, return ZIP_PARAMERROR; #endif + // The filename and comment length must fit in 16 bits. + if ((filename!=NULL) && (strlen(filename)>0xffff)) + return ZIP_PARAMERROR; + if ((comment!=NULL) && (strlen(comment)>0xffff)) + return ZIP_PARAMERROR; + // The extra field length must fit in 16 bits. If the member also requires + // a Zip64 extra block, that will also need to fit within that 16-bit + // length, but that will be checked for later. + if ((size_extrafield_local>0xffff) || (size_extrafield_global>0xffff)) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; if (zi->in_opened_file_inzip == 1) @@ -1262,35 +1233,33 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, return err; } -extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, - int windowBits,int memLevel, int strategy, - const char* password, uLong crcForCrypting, - uLong versionMadeBy, uLong flagBase) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - windowBits, memLevel, strategy, - password, crcForCrypting, versionMadeBy, flagBase, 0); +extern int ZEXPORT zipOpenNewFileInZip4(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase) { + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, versionMadeBy, flagBase, 0); } -extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, - int windowBits,int memLevel, int strategy, - const char* password, uLong crcForCrypting) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - windowBits, memLevel, strategy, - password, crcForCrypting, VERSIONMADEBY, 0, 0); +extern int ZEXPORT zipOpenNewFileInZip3(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting) { + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, 0); } extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, @@ -1298,70 +1267,64 @@ extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, c const void* extrafield_global, uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits,int memLevel, int strategy, - const char* password, uLong crcForCrypting, int zip64) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - windowBits, memLevel, strategy, - password, crcForCrypting, VERSIONMADEBY, 0, zip64); + const char* password, uLong crcForCrypting, int zip64) { + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, zip64); } extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi, const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0, VERSIONMADEBY, 0, 0); + const char* comment, int method, int level, int raw) { + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); } extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, int zip64) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0, VERSIONMADEBY, 0, zip64); + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, int zip64) { + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); } -extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void*extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int zip64) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, 0, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0, VERSIONMADEBY, 0, zip64); +extern int ZEXPORT zipOpenNewFileInZip64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void*extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int zip64) { + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); } -extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void*extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level) -{ - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, 0, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0, VERSIONMADEBY, 0, 0); +extern int ZEXPORT zipOpenNewFileInZip(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void*extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level) { + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); } -local int zip64FlushWriteBuffer(zip64_internal* zi) -{ +local int zip64FlushWriteBuffer(zip64_internal* zi) { int err=ZIP_OK; if (zi->ci.encrypt != 0) @@ -1399,8 +1362,7 @@ local int zip64FlushWriteBuffer(zip64_internal* zi) return err; } -extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len) -{ +extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void* buf, unsigned int len) { zip64_internal* zi; int err=ZIP_OK; @@ -1450,7 +1412,7 @@ extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned in else #endif { - zi->ci.stream.next_in = (Bytef*)buf; + zi->ci.stream.next_in = (Bytef*)(uintptr_t)buf; zi->ci.stream.avail_in = len; while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) @@ -1501,13 +1463,11 @@ extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned in return err; } -extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32) -{ +extern int ZEXPORT zipCloseFileInZipRaw(zipFile file, uLong uncompressed_size, uLong crc32) { return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32); } -extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32) -{ +extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_size, uLong crc32) { zip64_internal* zi; ZPOS64_T compressed_size; uLong invalidValue = 0xffffffff; @@ -1742,13 +1702,11 @@ extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_s return err; } -extern int ZEXPORT zipCloseFileInZip (zipFile file) -{ +extern int ZEXPORT zipCloseFileInZip(zipFile file) { return zipCloseFileInZipRaw (file,0,0); } -local int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) -{ +local int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) { int err = ZIP_OK; ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writing_offset; @@ -1769,8 +1727,7 @@ local int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T z return err; } -local int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) -{ +local int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) { int err = ZIP_OK; uLong Zip64DataSize = 44; @@ -1808,8 +1765,8 @@ local int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_ } return err; } -local int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) -{ + +local int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) { int err = ZIP_OK; /*signature*/ @@ -1856,8 +1813,7 @@ local int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centr return err; } -local int Write_GlobalComment(zip64_internal* zi, const char* global_comment) -{ +local int Write_GlobalComment(zip64_internal* zi, const char* global_comment) { int err = ZIP_OK; uInt size_global_comment = 0; @@ -1874,8 +1830,7 @@ local int Write_GlobalComment(zip64_internal* zi, const char* global_comment) return err; } -extern int ZEXPORT zipClose (zipFile file, const char* global_comment) -{ +extern int ZEXPORT zipClose(zipFile file, const char* global_comment) { zip64_internal* zi; int err = 0; uLong size_centraldir = 0; @@ -1917,7 +1872,7 @@ extern int ZEXPORT zipClose (zipFile file, const char* global_comment) free_linkedlist(&(zi->central_dir)); pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; - if(pos >= 0xffffffff || zi->number_entry > 0xFFFF) + if(pos >= 0xffffffff || zi->number_entry >= 0xFFFF) { ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); @@ -1936,15 +1891,14 @@ extern int ZEXPORT zipClose (zipFile file, const char* global_comment) err = ZIP_ERRNO; #ifndef NO_ADDFILEINEXISTINGZIP - TRYFREE(zi->globalcomment); + free(zi->globalcomment); #endif - TRYFREE(zi); + free(zi); return err; } -extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader) -{ +extern int ZEXPORT zipRemoveExtraInfoBlock(char* pData, int* dataLen, short sHeader) { char* p = pData; int size = 0; char* pNewHeader; @@ -1996,7 +1950,7 @@ extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHe else retVal = ZIP_ERRNO; - TRYFREE(pNewHeader); + free(pNewHeader); return retVal; } diff --git a/Telegram/ThirdParty/minizip/zip.h b/Telegram/ThirdParty/minizip/zip.h index 7e4509d77bee59..3e230d3405f603 100644 --- a/Telegram/ThirdParty/minizip/zip.h +++ b/Telegram/ThirdParty/minizip/zip.h @@ -113,8 +113,8 @@ typedef const char* zipcharpc; #define APPEND_STATUS_CREATEAFTER (1) #define APPEND_STATUS_ADDINZIP (2) -extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); -extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append)); +extern zipFile ZEXPORT zipOpen(const char *pathname, int append); +extern zipFile ZEXPORT zipOpen64(const void *pathname, int append); /* Create a zipfile. pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on @@ -131,55 +131,55 @@ extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append)); /* Note : there is no delete function into a zipfile. If you want delete file into a zipfile, you must open a zipfile, and create another - Of couse, you can use RAW reading and writing to copy the file you did not want delte + Of course, you can use RAW reading and writing to copy the file you did not want delete */ -extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, - int append, - zipcharpc* globalcomment, - zlib_filefunc_def* pzlib_filefunc_def)); +extern zipFile ZEXPORT zipOpen2(const char *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc_def* pzlib_filefunc_def); -extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname, +extern zipFile ZEXPORT zipOpen2_64(const void *pathname, int append, zipcharpc* globalcomment, - zlib_filefunc64_def* pzlib_filefunc_def)); - -extern zipFile ZEXPORT zipOpen3 OF((const void *pathname, - int append, - zipcharpc* globalcomment, - zlib_filefunc64_32_def* pzlib_filefunc64_32_def)); - -extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level)); - -extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int zip64)); + zlib_filefunc64_def* pzlib_filefunc_def); + +extern zipFile ZEXPORT zipOpen3(const void *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc64_32_def* pzlib_filefunc64_32_def); + +extern int ZEXPORT zipOpenNewFileInZip(zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level); + +extern int ZEXPORT zipOpenNewFileInZip64(zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int zip64); /* Open a file in the ZIP for writing. filename : the filename in zip (if NULL, '-' without quote will be used *zipfi contain supplemental information if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local - contains the extrafield data the the local header + contains the extrafield data for the local header if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global - contains the extrafield data the the local header + contains the extrafield data for the global header if comment != NULL, comment contain the comment string method contain the compression method (0 for store, Z_DEFLATED for deflate) level contain the level of compression (can be Z_DEFAULT_COMPRESSION) @@ -189,70 +189,69 @@ extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, */ -extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw)); - - -extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int zip64)); +extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw); + + +extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int zip64); /* Same than zipOpenNewFileInZip, except if raw=1, we write raw file */ -extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCrypting)); - -extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCrypting, - int zip64 - )); +extern int ZEXPORT zipOpenNewFileInZip3(zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting); + +extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + int zip64); /* Same than zipOpenNewFileInZip2, except @@ -261,47 +260,45 @@ extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, crcForCrypting : crc of file to compress (needed for crypting) */ -extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCrypting, - uLong versionMadeBy, - uLong flagBase - )); - - -extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCrypting, - uLong versionMadeBy, - uLong flagBase, - int zip64 - )); +extern int ZEXPORT zipOpenNewFileInZip4(zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase); + + +extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase, + int zip64); /* Same than zipOpenNewFileInZip4, except versionMadeBy : value for Version made by field @@ -309,25 +306,25 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, */ -extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, - const void* buf, - unsigned len)); +extern int ZEXPORT zipWriteInFileInZip(zipFile file, + const void* buf, + unsigned len); /* Write data in the zipfile */ -extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); +extern int ZEXPORT zipCloseFileInZip(zipFile file); /* Close the current file in the zipfile */ -extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, - uLong uncompressed_size, - uLong crc32)); +extern int ZEXPORT zipCloseFileInZipRaw(zipFile file, + uLong uncompressed_size, + uLong crc32); -extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, - ZPOS64_T uncompressed_size, - uLong crc32)); +extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, + ZPOS64_T uncompressed_size, + uLong crc32); /* Close the current file in the zipfile, for file opened with @@ -335,14 +332,14 @@ extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, uncompressed_size and crc32 are value for the uncompressed size */ -extern int ZEXPORT zipClose OF((zipFile file, - const char* global_comment)); +extern int ZEXPORT zipClose(zipFile file, + const char* global_comment); /* Close the zipfile */ -extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader)); +extern int ZEXPORT zipRemoveExtraInfoBlock(char* pData, int* dataLen, short sHeader); /* zipRemoveExtraInfoBlock - Added by Mathias Svensson diff --git a/Telegram/build/docker/centos_env/Dockerfile b/Telegram/build/docker/centos_env/Dockerfile index 253b0207a991ce..95e11eed36f243 100644 --- a/Telegram/build/docker/centos_env/Dockerfile +++ b/Telegram/build/docker/centos_env/Dockerfile @@ -54,7 +54,7 @@ FROM builder AS patches RUN git init patches \ && cd patches \ && git remote add origin {{ GIT }}/desktop-app/patches.git \ - && git fetch --depth=1 origin 78fe199b743df0358c04502d6947cd42bb5d16ed \ + && git fetch --depth=1 origin 5f434041ae25d0ae0f7936bfe76c4535f6151ba9 \ && git reset --hard FETCH_HEAD \ && rm -rf .git @@ -70,8 +70,11 @@ RUN git clone -b nasm-2.15.05 --depth=1 {{ GIT }}/netwide-assembler/nasm.git \ && rm -rf nasm FROM builder AS zlib -RUN git clone -b v1.2.13 --depth=1 {{ GIT }}/madler/zlib.git \ +RUN git init zlib \ && cd zlib \ + && git remote add origin {{ GIT }}/madler/zlib.git \ + && git fetch --depth=1 origin 643e17b7498d12ab8d15565662880579692f769d \ + && git reset --hard FETCH_HEAD \ && ./configure \ && make -j$(nproc) \ && make DESTDIR="{{ LibrariesPath }}/zlib-cache" install \ diff --git a/Telegram/build/prepare/prepare.py b/Telegram/build/prepare/prepare.py index c29d931785d9ec..51cc2c2982de18 100644 --- a/Telegram/build/prepare/prepare.py +++ b/Telegram/build/prepare/prepare.py @@ -418,7 +418,7 @@ def runStages(): stage('patches', """ git clone https://github.com/desktop-app/patches.git cd patches - git checkout 58c8cd0c0f + git checkout d3107bf4a5 """) stage('msys64', """ @@ -513,8 +513,9 @@ def runStages(): """) stage('zlib', """ - git clone -b v1.3 https://github.com/madler/zlib.git + git clone https://github.com/madler/zlib.git cd zlib + git checkout 643e17b749 win: cmake . ^ -A %WIN32X64% ^ @@ -1299,23 +1300,23 @@ def runStages(): """) if buildQt5: - stage('qt_5_15_11', """ - git clone https://github.com/qt/qt5.git qt_5_15_11 - cd qt_5_15_11 + stage('qt_5_15_12', """ + git clone https://github.com/qt/qt5.git qt_5_15_12 + cd qt_5_15_12 perl init-repository --module-subset=qtbase,qtimageformats,qtsvg - git checkout v5.15.11-lts-lgpl + git checkout v5.15.12-lts-lgpl git submodule update qtbase qtimageformats qtsvg -depends:patches/qtbase_5.15.11/*.patch +depends:patches/qtbase_5.15.12/*.patch cd qtbase win: - for /r %%i in (..\\..\\patches\\qtbase_5.15.11\\*) do git apply %%i -v + for /r %%i in (..\\..\\patches\\qtbase_5.15.12\\*) do git apply %%i -v cd .. SET CONFIGURATIONS=-debug release: SET CONFIGURATIONS=-debug-and-release win: - """ + removeDir("\"%LIBS_DIR%\\Qt-5.15.11\"") + """ + """ + removeDir("\"%LIBS_DIR%\\Qt-5.15.12\"") + """ SET ANGLE_DIR=%LIBS_DIR%\\tg_angle SET ANGLE_LIBS_DIR=%ANGLE_DIR%\\out SET MOZJPEG_DIR=%LIBS_DIR%\\mozjpeg @@ -1323,7 +1324,7 @@ def runStages(): SET OPENSSL_LIBS_DIR=%OPENSSL_DIR%\\out SET ZLIB_LIBS_DIR=%LIBS_DIR%\\zlib SET WEBP_DIR=%LIBS_DIR%\\libwebp - configure -prefix "%LIBS_DIR%\\Qt-5.15.11" ^ + configure -prefix "%LIBS_DIR%\\Qt-5.15.12" ^ %CONFIGURATIONS% ^ -force-debug-info ^ -opensource ^ @@ -1358,14 +1359,14 @@ def runStages(): jom -j16 jom -j16 install mac: - find ../../patches/qtbase_5.15.11 -type f -print0 | sort -z | xargs -0 git apply + find ../../patches/qtbase_5.15.12 -type f -print0 | sort -z | xargs -0 git apply cd .. CONFIGURATIONS=-debug release: CONFIGURATIONS=-debug-and-release mac: - ./configure -prefix "$USED_PREFIX/Qt-5.15.11" \ + ./configure -prefix "$USED_PREFIX/Qt-5.15.12" \ $CONFIGURATIONS \ -force-debug-info \ -opensource \ @@ -1386,14 +1387,14 @@ def runStages(): """) if buildQt6: - stage('qt_6_2_6', """ + stage('qt_6_2_7', """ mac: - git clone -b v6.2.6-lts-lgpl https://github.com/qt/qt5.git qt_6_2_6 - cd qt_6_2_6 + git clone -b v6.2.7-lts-lgpl https://github.com/qt/qt5.git qt_6_2_7 + cd qt_6_2_7 perl init-repository --module-subset=qtbase,qtimageformats,qtsvg -depends:patches/qtbase_6.2.6/*.patch +depends:patches/qtbase_6.2.7/*.patch cd qtbase - find ../../patches/qtbase_6.2.6 -type f -print0 | sort -z | xargs -0 git apply -v + find ../../patches/qtbase_6.2.7 -type f -print0 | sort -z | xargs -0 git apply -v cd .. sed -i.bak 's/tqtc-//' {qtimageformats,qtsvg}/dependencies.yaml @@ -1401,7 +1402,7 @@ def runStages(): release: CONFIGURATIONS=-debug-and-release mac: - ./configure -prefix "$USED_PREFIX/Qt-6.2.6" \ + ./configure -prefix "$USED_PREFIX/Qt-6.2.7" \ $CONFIGURATIONS \ -force-debug-info \ -opensource \ diff --git a/Telegram/build/version b/Telegram/build/version index b024a191106c55..beba60eed6c384 100644 --- a/Telegram/build/version +++ b/Telegram/build/version @@ -1,7 +1,7 @@ -AppVersion 4014002 +AppVersion 4014003 AppVersionStrMajor 4.14 -AppVersionStrSmall 4.14.2 -AppVersionStr 4.14.2 +AppVersionStrSmall 4.14.3 +AppVersionStr 4.14.3 BetaChannel 0 AlphaVersion 0 -AppVersionOriginal 4.14.2 +AppVersionOriginal 4.14.3 diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 989bd888271191..dec6e2ac0ed38b 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 989bd888271191d721fbb9800204037d854d2bf1 +Subproject commit dec6e2ac0ed38bfda2249233f00be2cba37cc6c5 diff --git a/changelog.txt b/changelog.txt index a69fb91442902e..da9a23547ff8dd 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,11 @@ +4.14.3 (04.01.24) + +- Allow sending single-time voice messages. +- Fix payments card validation. +- Fix crash when trying to join channels above the limit. +- Add "Quit Telegram" to the Taskbar context menu. (Windows) +- Fix opened windows list in the Dock icon context menu. (macOS) + 4.14.2 (02.01.24) - Show original senders name in reply to forward information. diff --git a/cmake b/cmake index 4005d7befb3ffb..9620c467404f15 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 4005d7befb3ffbbbb7851ed767d5b58373958e6d +Subproject commit 9620c467404f15a01bb5271af02b2676c2aaf306