From 916068447ad405fd2514ae00f9eab5038ba37f82 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 31 May 2016 12:46:31 +0300 Subject: [PATCH] Cloud stored drafts started. --- Telegram/Resources/icons/dialogs_draft.png | Bin 0 -> 247 bytes Telegram/Resources/icons/dialogs_draft@2x.png | Bin 0 -> 464 bytes Telegram/SourceFiles/app.h | 2 - Telegram/SourceFiles/data/drafts.cpp | 33 +++++ Telegram/SourceFiles/data/drafts.h | 27 ++++ Telegram/SourceFiles/dialogs/dialogs.style | 25 ++++ .../SourceFiles/dialogs/dialogs_layout.cpp | 19 ++- Telegram/SourceFiles/dialogswidget.cpp | 135 ++++++++---------- Telegram/SourceFiles/history.cpp | 16 ++- Telegram/SourceFiles/localstorage.cpp | 6 +- Telegram/SourceFiles/localstorage.h | 1 + Telegram/SourceFiles/mainwidget.cpp | 15 ++ Telegram/SourceFiles/mtproto/scheme.tl | 2 +- Telegram/SourceFiles/mtproto/scheme_auto.cpp | 1 + Telegram/SourceFiles/mtproto/scheme_auto.h | 17 ++- Telegram/SourceFiles/stdafx.h | 1 + Telegram/Telegram.vcxproj | 5 + Telegram/Telegram.vcxproj.filters | 18 +++ 18 files changed, 230 insertions(+), 93 deletions(-) create mode 100644 Telegram/Resources/icons/dialogs_draft.png create mode 100644 Telegram/Resources/icons/dialogs_draft@2x.png create mode 100644 Telegram/SourceFiles/data/drafts.cpp create mode 100644 Telegram/SourceFiles/data/drafts.h create mode 100644 Telegram/SourceFiles/dialogs/dialogs.style diff --git a/Telegram/Resources/icons/dialogs_draft.png b/Telegram/Resources/icons/dialogs_draft.png new file mode 100644 index 0000000000000000000000000000000000000000..af8676033435e7662bb18fdfd0d348336cb83bc2 GIT binary patch literal 247 zcmV_nhWLBL+aB5`_VpgIQ?Iz!Vf3L8qm`2>iG3ytv7`ZzZeyva+)!iNETc zqw6}#vP2Tb^E^ER$T_FBZIz~}@;nzH8DqG6FZF%TGwZq{V+_{XuV@@c!Z5txf5`X! z`)(0M5!<$XplO<(2n9hvk|Z3*@onj9Q54j5jU<+3Vc+*(be|;&HBAFR(==pRMjXdT x!dm+Q&Fl42RaKhjS;H{sJWm;81YH07$s3|c#S0WbcEP)322NV0QUQR#&OJ7 zS!ksRJ;RtAvdEzI}*Qj-NiP~5VrW-!-vtE~BF5uvsHXsfPiivvJB7g2W2G)*}e404x~0~%u} zA{>v$rC`J1F!!-P+W~;b;{gC@Hk+u`YWSr4{f^0Gg6(z-V+=&({Us4$uh(Oz(;)yZ z7K^WwJ?CCheight + st::dlgSep; - if (unread) { + bool hasDraftIcon = active ? false : Local::hasDraft(history->peer->id); + if (unread || hasDraftIcon) { + QString counter; + bool mutedCounter = false; + bool showUnreadCounter = unread && (!hasDraftIcon || !history->mute()); + if (showUnreadCounter) { + counter = QString::number(unread); + mutedCounter = history->mute(); + } int unreadTop = texttop + st::dlgHistFont->ascent - st::dlgUnreadFont->ascent - st::dlgUnreadTop; - paintUnreadCount(p, QString::number(unread), unreadTop, w, active, history->mute(), &availableWidth); + paintUnreadCount(p, counter, unreadTop, w, active, mutedCounter, &availableWidth); + if (!showUnreadCounter) { + st::dialogsDraft.paint(p, QPoint(w - st::dlgPaddingHor - st::dlgUnreadHeight, unreadTop), w); + } } if (history->typing.isEmpty() && history->sendActions.isEmpty()) { item->drawInDialog(p, QRect(nameleft, texttop, availableWidth, st::dlgFont->height), active, history->textCachedFor, history->lastItemTextCache); diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index 62b0c3299..2e4ba2522 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "dialogs/dialogs_indexed_list.h" #include "dialogs/dialogs_layout.h" +#include "data/drafts.h" #include "lang.h" #include "application.h" #include "mainwindow.h" @@ -977,42 +978,47 @@ void DialogsInner::itemRemoved(HistoryItem *item) { void DialogsInner::dialogsReceived(const QVector &added) { for_const (auto &dialog, added) { - History *history = nullptr; - switch (dialog.type()) { - case mtpc_dialog: { - auto &d(dialog.c_dialog()); - history = App::historyFromDialog(peerFromMTP(d.vpeer), d.vunread_count.v, d.vread_inbox_max_id.v, d.vread_outbox_max_id.v); - if (auto channel = history->peer->asChannel()) { - if (d.has_pts()) { - channel->ptsReceived(d.vpts.v); - } - if (!channel->amCreator()) { - if (auto topMsg = App::histItemById(channel, d.vtop_message.v)) { - if (topMsg->date <= date(channel->date) && App::api()) { - App::api()->requestSelfParticipant(channel); - } + if (dialog.type() != mtpc_dialog) { + continue; + } + + auto &d = dialog.c_dialog(); + auto peerId = peerFromMTP(d.vpeer); + if (!peerId) { + continue; + } + + auto history = App::historyFromDialog(peerId, d.vunread_count.v, d.vread_inbox_max_id.v, d.vread_outbox_max_id.v); + auto peer = history->peer; + if (auto channel = peer->asChannel()) { + if (d.has_pts()) { + channel->ptsReceived(d.vpts.v); + } + if (!channel->amCreator()) { + if (auto topMsg = App::histItemById(channel, d.vtop_message.v)) { + if (topMsg->date <= date(channel->date) && App::api()) { + App::api()->requestSelfParticipant(channel); } } } - if (App::main()) { - App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, history); - } - } break; + } + App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, history); + + if (!history->lastMsgDate.isNull()) { + addSavedPeersAfter(history->lastMsgDate); + } + contactsNoDialogs->del(peer); + if (peer->migrateFrom()) { + removeDialog(App::historyLoaded(peer->migrateFrom()->id)); + } else if (peer->migrateTo() && peer->migrateTo()->amIn()) { + removeDialog(history); } - if (history) { - if (!history->lastMsgDate.isNull()) { - addSavedPeersAfter(history->lastMsgDate); - } - contactsNoDialogs->del(history->peer); - if (history->peer->migrateFrom()) { - removeDialog(App::historyLoaded(history->peer->migrateFrom()->id)); - } else if (history->peer->migrateTo() && history->peer->migrateTo()->amIn()) { - removeDialog(history); - } + if (d.has_draft() && d.vdraft.type() == mtpc_draftMessage) { + auto &draft = d.vdraft.c_draftMessage(); + Data::applyPeerCloudDraft(peerId, draft); } } - Notify::unreadCounterUpdated(); if (!_sel && !shownDialogs()->isEmpty()) { _sel = *shownDialogs()->cbegin(); @@ -1914,46 +1920,28 @@ void DialogsWidget::notify_historyMuteUpdated(History *history) { } void DialogsWidget::unreadCountsReceived(const QVector &dialogs) { - for_const (auto &dialog, dialogs) { - switch (dialog.type()) { - case mtpc_dialog: { - auto &d(dialog.c_dialog()); - if (auto h = App::historyLoaded(peerFromMTP(d.vpeer))) { - if (h->peer->isChannel() && d.has_pts()) { - h->peer->asChannel()->ptsReceived(d.vpts.v); - } - App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, h); - if (d.vunread_count.v >= h->unreadCount()) { - h->setUnreadCount(d.vunread_count.v); - h->inboxReadBefore = d.vread_inbox_max_id.v + 1; - } - accumulate_max(h->outboxReadBefore, d.vread_outbox_max_id.v + 1); - } - } break; - } - } } void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpRequestId req) { if (_dialogsRequest != req) return; - const QVector *v = 0; - const QVector *m = 0; + const QVector *dialogsList = 0; + const QVector *messagesList = 0; switch (dialogs.type()) { case mtpc_messages_dialogs: { const auto &data(dialogs.c_messages_dialogs()); App::feedUsers(data.vusers); App::feedChats(data.vchats); - m = &data.vmessages.c_vector().v; - v = &data.vdialogs.c_vector().v; + messagesList = &data.vmessages.c_vector().v; + dialogsList = &data.vdialogs.c_vector().v; _dialogsFull = true; } break; case mtpc_messages_dialogsSlice: { const auto &data(dialogs.c_messages_dialogsSlice()); App::feedUsers(data.vusers); App::feedChats(data.vchats); - m = &data.vmessages.c_vector().v; - v = &data.vdialogs.c_vector().v; + messagesList = &data.vmessages.c_vector().v; + dialogsList = &data.vdialogs.c_vector().v; } break; } @@ -1961,36 +1949,33 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpReque _contactsRequest = MTP::send(MTPcontacts_GetContacts(MTP_string("")), rpcDone(&DialogsWidget::contactsReceived), rpcFail(&DialogsWidget::contactsFailed)); } - if (m) { - App::feedMsgs(*m, NewMessageLast); + if (messagesList) { + App::feedMsgs(*messagesList, NewMessageLast); } - if (v) { - unreadCountsReceived(*v); - _inner.dialogsReceived(*v); + if (dialogsList) { + unreadCountsReceived(*dialogsList); + _inner.dialogsReceived(*dialogsList); onListScroll(); - int32 lastDate = 0; + TimeId lastDate = 0; PeerId lastPeer = 0; MsgId lastMsgId = 0; - for (int32 i = v->size(); i > 0;) { - PeerId peer = 0; - MsgId msgId = 0; - const auto &d(v->at(--i)); - switch (d.type()) { - case mtpc_dialog: - msgId = d.c_dialog().vtop_message.v; - peer = peerFromMTP(d.c_dialog().vpeer); - break; + for (int i = dialogsList->size(); i > 0;) { + auto &dialog = dialogsList->at(--i); + if (dialog.type() != mtpc_dialog) { + continue; } - if (peer) { + + if (auto peer = peerFromMTP(dialog.c_dialog().vpeer)) { if (!lastPeer) lastPeer = peer; - if (msgId) { + if (auto msgId = dialog.c_dialog().vtop_message.v) { if (!lastMsgId) lastMsgId = msgId; - for (int32 j = m->size(); j > 0;) { - const auto &d(m->at(--j)); - if (idFromMessage(d) == msgId && peerFromMessage(d) == peer) { - int32 date = dateFromMessage(d); - if (date) lastDate = date; + for (int j = messagesList->size(); j > 0;) { + auto &message = messagesList->at(--j); + if (idFromMessage(message) == msgId && peerFromMessage(message) == peer) { + if (auto date = dateFromMessage(message)) { + lastDate = date; + } break; } } diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index 65d25a519..baaaff393 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -474,10 +474,18 @@ History *Histories::find(const PeerId &peerId) { History *Histories::findOrInsert(const PeerId &peerId, int32 unreadCount, int32 maxInboxRead, int32 maxOutboxRead) { auto i = map.constFind(peerId); if (i == map.cend()) { - i = map.insert(peerId, peerIsChannel(peerId) ? static_cast(new ChannelHistory(peerId)) : (new History(peerId))); - i.value()->setUnreadCount(unreadCount); - i.value()->inboxReadBefore = maxInboxRead + 1; - i.value()->outboxReadBefore = maxOutboxRead + 1; + auto history = peerIsChannel(peerId) ? static_cast(new ChannelHistory(peerId)) : (new History(peerId)); + i = map.insert(peerId, history); + history->setUnreadCount(unreadCount); + history->inboxReadBefore = maxInboxRead + 1; + history->outboxReadBefore = maxOutboxRead + 1; + } else { + auto history = i.value(); + if (unreadCount >= history->unreadCount()) { + history->setUnreadCount(unreadCount); + history->inboxReadBefore = maxInboxRead + 1; + } + accumulate_max(history->outboxReadBefore, maxOutboxRead + 1); } return i.value(); } diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index 8df89e4c0..7b233f1d4 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -2439,7 +2439,11 @@ namespace Local { } bool hasDraftCursors(const PeerId &peer) { - return (_draftCursorsMap.constFind(peer) != _draftCursorsMap.cend()); + return _draftCursorsMap.contains(peer); + } + + bool hasDraft(const PeerId &peer) { + return _draftsMap.contains(peer); } void writeFileLocation(MediaKey location, const FileLocation &local) { diff --git a/Telegram/SourceFiles/localstorage.h b/Telegram/SourceFiles/localstorage.h index ee5e8ba6e..de30ce75e 100644 --- a/Telegram/SourceFiles/localstorage.h +++ b/Telegram/SourceFiles/localstorage.h @@ -120,6 +120,7 @@ namespace Local { void readDraftsWithCursors(History *h); void writeDraftCursors(const PeerId &peer, const MessageCursor &msgCursor, const MessageCursor &editCursor); bool hasDraftCursors(const PeerId &peer); + bool hasDraft(const PeerId &peer); void writeFileLocation(MediaKey location, const FileLocation &local); FileLocation readFileLocation(MediaKey location, bool check = true); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 32af1c33e..4f194e436 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "ui/buttons/peer_avatar_button.h" #include "window/top_bar_widget.h" +#include "data/drafts.h" #include "apiwrap.h" #include "dialogswidget.h" #include "historywidget.h" @@ -4554,9 +4555,23 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { App::main()->updateStickers(); } break; + ////// Cloud saved GIFs case mtpc_updateSavedGifs: { cSetLastSavedGifsUpdate(0); App::main()->updateStickers(); } break; + + ////// Cloud drafts + case mtpc_updateDraftMessage: { + auto &peerDraft = update.c_updateDraftMessage(); + auto peerId = peerFromMTP(peerDraft.vpeer); + + auto &draftMessage = peerDraft.vdraft; + if (draftMessage.type() == mtpc_draftMessage) { + auto &draft = draftMessage.c_draftMessage(); + Data::applyPeerCloudDraft(peerId, draft); + } + } break; + } } diff --git a/Telegram/SourceFiles/mtproto/scheme.tl b/Telegram/SourceFiles/mtproto/scheme.tl index 5845ac894..9bf59c656 100644 --- a/Telegram/SourceFiles/mtproto/scheme.tl +++ b/Telegram/SourceFiles/mtproto/scheme.tl @@ -693,7 +693,7 @@ contacts.topPeersNotModified#de266ef5 = contacts.TopPeers; contacts.topPeers#70b772a8 categories:Vector chats:Vector users:Vector = contacts.TopPeers; draftMessageEmpty#ba4baec5 = DraftMessage; -draftMessage#2a280746 flags:# no_webpage:flags.1?true reply_to_msg_id:flags.0?int message:string entities:flags.3?Vector = DraftMessage; +draftMessage#fd8e711f flags:# no_webpage:flags.1?true reply_to_msg_id:flags.0?int message:string entities:flags.3?Vector date:int = DraftMessage; ---functions--- diff --git a/Telegram/SourceFiles/mtproto/scheme_auto.cpp b/Telegram/SourceFiles/mtproto/scheme_auto.cpp index 2d076a6a1..4b3d3736c 100644 --- a/Telegram/SourceFiles/mtproto/scheme_auto.cpp +++ b/Telegram/SourceFiles/mtproto/scheme_auto.cpp @@ -5731,6 +5731,7 @@ void _serialize_draftMessage(MTPStringLogger &to, int32 stage, int32 lev, Types case 2: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPDdraftMessage::Flag::f_reply_to_msg_id) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break; case 3: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; case 4: to.add(" entities: "); ++stages.back(); if (flag & MTPDdraftMessage::Flag::f_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break; + case 5: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break; default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break; } } diff --git a/Telegram/SourceFiles/mtproto/scheme_auto.h b/Telegram/SourceFiles/mtproto/scheme_auto.h index 3a28c53e0..54c767164 100644 --- a/Telegram/SourceFiles/mtproto/scheme_auto.h +++ b/Telegram/SourceFiles/mtproto/scheme_auto.h @@ -499,7 +499,7 @@ enum { mtpc_contacts_topPeersNotModified = 0xde266ef5, mtpc_contacts_topPeers = 0x70b772a8, mtpc_draftMessageEmpty = 0xba4baec5, - mtpc_draftMessage = 0x2a280746, + mtpc_draftMessage = 0xfd8e711f, mtpc_invokeAfterMsg = 0xcb9f372d, mtpc_invokeAfterMsgs = 0x3dc4b4f0, mtpc_initConnection = 0x69796de9, @@ -14388,13 +14388,14 @@ public: MTPDdraftMessage() { } - MTPDdraftMessage(const MTPflags &_flags, MTPint _reply_to_msg_id, const MTPstring &_message, const MTPVector &_entities) : vflags(_flags), vreply_to_msg_id(_reply_to_msg_id), vmessage(_message), ventities(_entities) { + MTPDdraftMessage(const MTPflags &_flags, MTPint _reply_to_msg_id, const MTPstring &_message, const MTPVector &_entities, MTPint _date) : vflags(_flags), vreply_to_msg_id(_reply_to_msg_id), vmessage(_message), ventities(_entities), vdate(_date) { } MTPflags vflags; MTPint vreply_to_msg_id; MTPstring vmessage; MTPVector ventities; + MTPint vdate; }; // RPC methods @@ -23552,8 +23553,8 @@ public: inline static MTPdraftMessage new_draftMessageEmpty() { return MTPdraftMessage(mtpc_draftMessageEmpty); } - inline static MTPdraftMessage new_draftMessage(const MTPflags &_flags, MTPint _reply_to_msg_id, const MTPstring &_message, const MTPVector &_entities) { - return MTPdraftMessage(new MTPDdraftMessage(_flags, _reply_to_msg_id, _message, _entities)); + inline static MTPdraftMessage new_draftMessage(const MTPflags &_flags, MTPint _reply_to_msg_id, const MTPstring &_message, const MTPVector &_entities, MTPint _date) { + return MTPdraftMessage(new MTPDdraftMessage(_flags, _reply_to_msg_id, _message, _entities, _date)); } }; @@ -34814,7 +34815,7 @@ inline uint32 MTPdraftMessage::innerLength() const { switch (_type) { case mtpc_draftMessage: { const MTPDdraftMessage &v(c_draftMessage()); - return v.vflags.innerLength() + (v.has_reply_to_msg_id() ? v.vreply_to_msg_id.innerLength() : 0) + v.vmessage.innerLength() + (v.has_entities() ? v.ventities.innerLength() : 0); + return v.vflags.innerLength() + (v.has_reply_to_msg_id() ? v.vreply_to_msg_id.innerLength() : 0) + v.vmessage.innerLength() + (v.has_entities() ? v.ventities.innerLength() : 0) + v.vdate.innerLength(); } } return 0; @@ -34834,6 +34835,7 @@ inline void MTPdraftMessage::read(const mtpPrime *&from, const mtpPrime *end, mt if (v.has_reply_to_msg_id()) { v.vreply_to_msg_id.read(from, end); } else { v.vreply_to_msg_id = MTPint(); } v.vmessage.read(from, end); if (v.has_entities()) { v.ventities.read(from, end); } else { v.ventities = MTPVector(); } + v.vdate.read(from, end); } break; default: throw mtpErrorUnexpected(cons, "MTPdraftMessage"); } @@ -34846,6 +34848,7 @@ inline void MTPdraftMessage::write(mtpBuffer &to) const { if (v.has_reply_to_msg_id()) v.vreply_to_msg_id.write(to); v.vmessage.write(to); if (v.has_entities()) v.ventities.write(to); + v.vdate.write(to); } break; } } @@ -34862,8 +34865,8 @@ inline MTPdraftMessage MTP_draftMessageEmpty() { return MTP::internal::TypeCreator::new_draftMessageEmpty(); } Q_DECLARE_OPERATORS_FOR_FLAGS(MTPDdraftMessage::Flags) -inline MTPdraftMessage MTP_draftMessage(const MTPflags &_flags, MTPint _reply_to_msg_id, const MTPstring &_message, const MTPVector &_entities) { - return MTP::internal::TypeCreator::new_draftMessage(_flags, _reply_to_msg_id, _message, _entities); +inline MTPdraftMessage MTP_draftMessage(const MTPflags &_flags, MTPint _reply_to_msg_id, const MTPstring &_message, const MTPVector &_entities, MTPint _date) { + return MTP::internal::TypeCreator::new_draftMessage(_flags, _reply_to_msg_id, _message, _entities, _date); } inline MTPDmessage::Flags mtpCastFlags(MTPDmessageService::Flags flags) { return MTPDmessage::Flags(QFlag(flags)); } inline MTPDmessage::Flags mtpCastFlags(MTPflags flags) { return mtpCastFlags(flags.v); } diff --git a/Telegram/SourceFiles/stdafx.h b/Telegram/SourceFiles/stdafx.h index 1d9f12f90..2cb99c4b7 100644 --- a/Telegram/SourceFiles/stdafx.h +++ b/Telegram/SourceFiles/stdafx.h @@ -71,5 +71,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "ui/flatlabel.h" #include "app.h" +#include "facades.h" #endif // __cplusplus diff --git a/Telegram/Telegram.vcxproj b/Telegram/Telegram.vcxproj index 72d35e0f7..20d0bf557 100644 --- a/Telegram/Telegram.vcxproj +++ b/Telegram/Telegram.vcxproj @@ -1075,6 +1075,7 @@ + @@ -1102,6 +1103,7 @@ + @@ -1283,12 +1285,14 @@ + + @@ -2457,6 +2461,7 @@ Compiling style %(Identity)... + diff --git a/Telegram/Telegram.vcxproj.filters b/Telegram/Telegram.vcxproj.filters index 78319ff25..9b4f71cab 100644 --- a/Telegram/Telegram.vcxproj.filters +++ b/Telegram/Telegram.vcxproj.filters @@ -91,6 +91,9 @@ {6b33ddc0-a7e2-4961-81dc-e1b5de2e2c60} + + {606a297a-0b85-4df9-a6bc-39de5beed362} + @@ -1131,6 +1134,12 @@ GeneratedFiles\Release + + GeneratedFiles\styles + + + SourceFiles\data + @@ -1307,6 +1316,12 @@ GeneratedFiles\styles + + GeneratedFiles\styles + + + SourceFiles\data + @@ -1624,6 +1639,9 @@ SourceFiles\history + + SourceFiles\dialogs +