diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 009176a17c..f906731af4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,6 +6,7 @@ This document describes how you can contribute to Telegram Desktop. Please read * [What contributions are accepted](#what-contributions-are-accepted) * [Sign your work](#sign-your-work) + * [Change commit message of a pushed commit](#change-commit-message-of-a-pushed-commit) * [Build instructions](#build-instructions) * [Pull upstream changes into your fork regularly](#pull-upstream-changes-into-your-fork-regularly) * [How to get your pull request accepted](#how-to-get-your-pull-request-accepted) @@ -49,12 +50,26 @@ By making a contribution to this project, I certify that: (e) I am granting this work into the public domain. ``` -Then you just add a line to every git commit message that states: +Then you just add a line to every **git commit message** that states: Signed-off-by: Random J Developer (github: rndjdev_github) Replacing Random Developer’s details with your name, email address and GitHub username. +### Change commit message of a pushed commit + +If you already pushed a commit and forgot to add the signature to the commit message, follow these steps to change the message of the commit: + +1. Open `Git Bash` (or `Git Shell`) +2. Enter following command to change the commit message of the most recent commit: `git commit --amend` +3. Press i to get into Insert-mode +4. Change the commit message (and add the [signature](#sign-your-work) at the and) +5. After editing the message, press ESC to get out of the Insert-mode +6. Write `:wq` and press Enter to save the new message or write `:q!` to discard your changes +7. Enter `git push --force` to push the commit with the new commit message to the remote repository + +For more info, see [GitHub Help][help_change_commit_message]. + ## Build instructions * [Visual Studio 2013][msvc] @@ -122,5 +137,6 @@ Don't forget to [sign your patch](#sign-your-work) to put it in the public domai [xcode_old]: XCODEold.md [qtcreator]: QTCREATOR.md [help_fork_repo]: https://help.github.com/articles/fork-a-repo/ +[help_change_commit_message]: https://help.github.com/articles/changing-a-commit-message/ [commit_message]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html [pr]: ../../compare/ diff --git a/MSVC.md b/MSVC.md index 3232824fac..e3bdafcdf6 100644 --- a/MSVC.md +++ b/MSVC.md @@ -169,6 +169,13 @@ and run #####Apply the patch cd qtbase && git apply ../../../tdesktop/Telegram/_qtbase_5_5_1_patch.diff && cd .. + + +#####Install Windows SDKs + +If you didn't install Windows SDKs before, you need to install them now. To install the SDKs just open Telegram solution at **D:\TBuild\tdesktop\Telegram.sln** and on startup Visual Studio 2015 will popup dialog box and ask to download and install extra components (including Windows 7 SDK). + +If you already have Windows SDKs then find the library folder and correct it at configure's command below (like **C:\Program Files (x86)\Windows Kits\8.0\Lib\win8\um\x86**). #####Building library diff --git a/Telegram/SourceFiles/gui/flatinput.cpp b/Telegram/SourceFiles/gui/flatinput.cpp index 8d5e5731c4..f92a96d0a6 100644 --- a/Telegram/SourceFiles/gui/flatinput.cpp +++ b/Telegram/SourceFiles/gui/flatinput.cpp @@ -917,11 +917,12 @@ QVariant InputArea::InputAreaInner::loadResource(int type, const QUrl &name) { } void InputArea::processDocumentContentsChange(int position, int charsAdded) { - int32 emojiPosition = -1, emojiLen = 0; + int32 replacePosition = -1, replaceLen = 0; const EmojiData *emoji = 0; static QString regular = qsl("Open Sans"), semibold = qsl("Open Sans Semibold"); - bool checkTilde = !cRetina() && (font().pixelSize() == 13) && (font().family() == regular), prevTilde = false; + bool checkTilde = !cRetina() && (_inner.font().pixelSize() == 13) && (_inner.font().family() == regular); + bool wasTildeFragment = false; QTextDocument *doc(_inner.document()); QTextCursor c(_inner.textCursor()); @@ -941,65 +942,66 @@ void InputArea::processDocumentContentsChange(int position, int charsAdded) { continue; } + if (checkTilde) { + wasTildeFragment = (fragment.charFormat().fontFamily() == semibold); + } + QString t(fragment.text()); const QChar *ch = t.constData(), *e = ch + t.size(); for (; ch != e; ++ch, ++fp) { - if (checkTilde && fp >= position) { // tilde fix in OpenSans - bool tilde = (ch->unicode() == '~'); - QString fontfamily; - if (tilde) { - if (fragment.charFormat().fontFamily() != semibold) { - fontfamily = semibold; - } - } else if (prevTilde) { - if (fragment.charFormat().fontFamily() == semibold) { - fontfamily = regular; - } - } - if (!fontfamily.isEmpty()) { - if (!_inner.document()->pageSize().isNull()) { - _inner.document()->setPageSize(QSizeF(0, 0)); - } - emojiPosition = fp; - emojiLen = 1; - QTextCursor c(doc->docHandle(), emojiPosition); - c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor); - QTextCharFormat format; - format.setFontFamily(fontfamily); - c.mergeCharFormat(format); - break; - } - prevTilde = tilde; - } - + int32 emojiLen = 0; emoji = emojiFromText(ch, e, emojiLen); if (emoji) { - emojiPosition = fp; + if (replacePosition >= 0) { + emoji = 0; // replace tilde char format first + } else { + replacePosition = fp; + replaceLen = emojiLen; + } break; } + + if (checkTilde && fp >= position) { // tilde fix in OpenSans + bool tilde = (ch->unicode() == '~'); + if ((tilde && !wasTildeFragment) || (!tilde && wasTildeFragment)) { + if (replacePosition < 0) { + replacePosition = fp; + replaceLen = 1; + } else { + ++replaceLen; + } + } else if (replacePosition >= 0) { + break; + } + } + if (ch + 1 < e && ch->isHighSurrogate() && (ch + 1)->isLowSurrogate()) { ++ch; ++fp; } } - if (emojiPosition >= 0) break; + if (replacePosition >= 0) break; } - if (emojiPosition >= 0) break; + if (replacePosition >= 0) break; } - if (emojiPosition >= 0) { - if (emoji) { - if (!_inner.document()->pageSize().isNull()) { - _inner.document()->setPageSize(QSizeF(0, 0)); - } - QTextCursor c(doc->docHandle(), emojiPosition); - c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor); - insertEmoji(emoji, c); + if (replacePosition >= 0) { + if (!_inner.document()->pageSize().isNull()) { + _inner.document()->setPageSize(QSizeF(0, 0)); } - charsAdded -= emojiPosition + emojiLen - position; - position = emojiPosition + 1; + QTextCursor c(doc->docHandle(), replacePosition); + c.setPosition(replacePosition + replaceLen, QTextCursor::KeepAnchor); + if (emoji) { + insertEmoji(emoji, c); + } else { + QTextCharFormat format; + format.setFontFamily(wasTildeFragment ? regular : semibold); + c.mergeCharFormat(format); + } + charsAdded -= replacePosition + replaceLen - position; + position = replacePosition + (emoji ? 1 : replaceLen); emoji = 0; - emojiPosition = -1; + replacePosition = -1; } else { break; } @@ -1611,11 +1613,13 @@ QVariant InputField::InputFieldInner::loadResource(int type, const QUrl &name) { } void InputField::processDocumentContentsChange(int position, int charsAdded) { - int32 emojiPosition = -1, emojiLen = 0; + int32 replacePosition = -1, replaceLen = 0; const EmojiData *emoji = 0; + bool newlineFound = false; static QString regular = qsl("Open Sans"), semibold = qsl("Open Sans Semibold"), space(' '); - bool checkTilde = !cRetina() && (font().pixelSize() == 13) && (font().family() == regular), prevTilde = false; + bool checkTilde = !cRetina() && (_inner.font().pixelSize() == 13) && (_inner.font().family() == regular); + bool wasTildeFragment = false; QTextDocument *doc(_inner.document()); QTextCursor c(_inner.textCursor()); @@ -1635,87 +1639,91 @@ void InputField::processDocumentContentsChange(int position, int charsAdded) { continue; } + if (checkTilde) { + wasTildeFragment = (fragment.charFormat().fontFamily() == semibold); + } + QString t(fragment.text()); const QChar *ch = t.constData(), *e = ch + t.size(); for (; ch != e; ++ch, ++fp) { - if (checkTilde && fp >= position) { // tilde fix in OpenSans - bool tilde = (ch->unicode() == '~'); - QString fontfamily; - if (tilde) { - if (fragment.charFormat().fontFamily() != semibold) { - fontfamily = semibold; - } - } else if (prevTilde) { - if (fragment.charFormat().fontFamily() == semibold) { - fontfamily = regular; - } - } - if (!fontfamily.isEmpty()) { - if (!_inner.document()->pageSize().isNull()) { - _inner.document()->setPageSize(QSizeF(0, 0)); - } - emojiPosition = fp; - emojiLen = 1; - QTextCursor c(doc->docHandle(), emojiPosition); - c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor); - QTextCharFormat format; - format.setFontFamily(fontfamily); - c.mergeCharFormat(format); - break; - } - prevTilde = tilde; - } - // QTextBeginningOfFrame // QTextEndOfFrame - if (ch->unicode() == 0xfdd0 || ch->unicode() == 0xfdd1 || ch->unicode() == QChar::ParagraphSeparator || ch->unicode() == QChar::LineSeparator || ch->unicode() == '\n' || ch->unicode() == '\r') { - if (!_inner.document()->pageSize().isNull()) { - _inner.document()->setPageSize(QSizeF(0, 0)); + newlineFound = (ch->unicode() == 0xfdd0 || ch->unicode() == 0xfdd1 || ch->unicode() == QChar::ParagraphSeparator || ch->unicode() == QChar::LineSeparator || ch->unicode() == '\n' || ch->unicode() == '\r'); + if (newlineFound) { + if (replacePosition >= 0) { + newlineFound = false; // replace tilde char format first + } else { + replacePosition = fp; + replaceLen = 1; } - emojiPosition = fp; - emojiLen = 1; - QTextCursor c(doc->docHandle(), emojiPosition); - c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor); - c.insertText(space); break; } + int32 emojiLen = 0; emoji = emojiFromText(ch, e, emojiLen); if (emoji) { - emojiPosition = fp; + if (replacePosition >= 0) { + emoji = 0; // replace tilde char format first + } else { + replacePosition = fp; + replaceLen = emojiLen; + } break; } + + if (checkTilde && fp >= position) { // tilde fix in OpenSans + bool tilde = (ch->unicode() == '~'); + if ((tilde && !wasTildeFragment) || (!tilde && wasTildeFragment)) { + if (replacePosition < 0) { + replacePosition = fp; + replaceLen = 1; + } else { + ++replaceLen; + } + } else if (replacePosition >= 0) { + break; + } + } + if (ch + 1 < e && ch->isHighSurrogate() && (ch + 1)->isLowSurrogate()) { ++ch; ++fp; } } - if (emojiPosition >= 0) break; + if (replacePosition >= 0) break; } - if (emojiPosition >= 0) break; + if (replacePosition >= 0) break; if (b.next() != doc->end()) { - emojiPosition = b.next().position() - 1; - emojiLen = 1; - QTextCursor c(doc->docHandle(), emojiPosition); - c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor); - c.insertText(space); + newlineFound = true; + replacePosition = b.next().position() - 1; + replaceLen = 1; break; } } - if (emojiPosition >= 0) { - if (emoji) { - if (!_inner.document()->pageSize().isNull()) { - _inner.document()->setPageSize(QSizeF(0, 0)); - } - QTextCursor c(doc->docHandle(), emojiPosition); - c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor); - insertEmoji(emoji, c); + if (replacePosition >= 0) { + if (!_inner.document()->pageSize().isNull()) { + _inner.document()->setPageSize(QSizeF(0, 0)); } - charsAdded -= emojiPosition + emojiLen - position; - position = emojiPosition + 1; + QTextCursor c(doc->docHandle(), replacePosition); + c.setPosition(replacePosition + replaceLen, QTextCursor::KeepAnchor); + if (newlineFound) { + QTextCharFormat format; + format.setFontFamily(regular); + c.mergeCharFormat(format); + c.insertText(space); + } else if (emoji) { + insertEmoji(emoji, c); + } else { + QTextCharFormat format; + format.setFontFamily(wasTildeFragment ? regular : semibold); + c.mergeCharFormat(format); + } + charsAdded -= replacePosition + replaceLen - position; + position = replacePosition + ((emoji || newlineFound) ? 1 : replaceLen); + newlineFound = false; emoji = 0; - emojiPosition = -1; + replacePosition = -1; } else { break; } diff --git a/Telegram/SourceFiles/gui/flattextarea.cpp b/Telegram/SourceFiles/gui/flattextarea.cpp index 8cb8103b6d..8d917d475e 100644 --- a/Telegram/SourceFiles/gui/flattextarea.cpp +++ b/Telegram/SourceFiles/gui/flattextarea.cpp @@ -619,11 +619,11 @@ void FlatTextarea::checkContentHeight() { } void FlatTextarea::processDocumentContentsChange(int position, int charsAdded) { - int32 emojiPosition = -1, emojiLen = 0; + int32 replacePosition = -1, replaceLen = 0; const EmojiData *emoji = 0; static QString regular = qsl("Open Sans"), semibold = qsl("Open Sans Semibold"); - bool checkTilde = !cRetina() && (font().pixelSize() == 13) && (font().family() == regular), prevTilde = false; + bool checkTilde = !cRetina() && (font().pixelSize() == 13) && (font().family() == regular), wasTildeFragment = false; QTextDocument *doc(document()); while (true) { @@ -640,66 +640,68 @@ void FlatTextarea::processDocumentContentsChange(int position, int charsAdded) { if (fp >= end || fe <= start) { continue; } + + if (checkTilde) { + wasTildeFragment = (fragment.charFormat().fontFamily() == semibold); + } + QString t(fragment.text()); const QChar *ch = t.constData(), *e = ch + t.size(); for (; ch != e; ++ch, ++fp) { - if (checkTilde && fp >= position) { // tilde fix in OpenSans - bool tilde = (ch->unicode() == '~'); - QString fontfamily; - if (tilde) { - if (fragment.charFormat().fontFamily() != semibold) { - fontfamily = semibold; - } - } else if (prevTilde) { - if (fragment.charFormat().fontFamily() == semibold) { - fontfamily = regular; - } - } - if (!fontfamily.isEmpty()) { - if (!document()->pageSize().isNull()) { - document()->setPageSize(QSizeF(0, 0)); - } - emojiPosition = fp; - emojiLen = 1; - QTextCursor c(doc->docHandle(), emojiPosition); - c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor); - QTextCharFormat format; - format.setFontFamily(fontfamily); - c.mergeCharFormat(format); - break; - } - prevTilde = tilde; - } - + int32 emojiLen = 0; emoji = emojiFromText(ch, e, emojiLen); if (emoji) { - emojiPosition = fp; + if (replacePosition >= 0) { + emoji = 0; // replace tilde char format first + } else { + replacePosition = fp; + replaceLen = emojiLen; + } break; } + + if (checkTilde && fp >= position) { // tilde fix in OpenSans + bool tilde = (ch->unicode() == '~'); + if ((tilde && !wasTildeFragment) || (!tilde && wasTildeFragment)) { + if (replacePosition < 0) { + replacePosition = fp; + replaceLen = 1; + } else { + ++replaceLen; + } + } else if (replacePosition >= 0) { + break; + } + } + if (ch + 1 < e && ch->isHighSurrogate() && (ch + 1)->isLowSurrogate()) { ++ch; ++fp; } } - if (emojiPosition >= 0) break; + if (replacePosition >= 0) break; } - if (emojiPosition >= 0) break; + if (replacePosition >= 0) break; } - if (emojiPosition >= 0) { - if (emoji) { - if (!document()->pageSize().isNull()) { - document()->setPageSize(QSizeF(0, 0)); - } - QTextCursor c(doc->docHandle(), emojiPosition); - c.setPosition(emojiPosition + emojiLen, QTextCursor::KeepAnchor); - insertEmoji(emoji, c); + if (replacePosition >= 0) { + if (!document()->pageSize().isNull()) { + document()->setPageSize(QSizeF(0, 0)); } - charsAdded -= emojiPosition + emojiLen - position; - position = emojiPosition + 1; + QTextCursor c(doc->docHandle(), replacePosition); + c.setPosition(replacePosition + replaceLen, QTextCursor::KeepAnchor); + if (emoji) { + insertEmoji(emoji, c); + } else { + QTextCharFormat format; + format.setFontFamily(wasTildeFragment ? regular : semibold); + c.mergeCharFormat(format); + } + charsAdded -= replacePosition + replaceLen - position; + position = replacePosition + (emoji ? 1 : replaceLen); emoji = 0; - emojiPosition = -1; - } else { + replacePosition = -1; + } else { break; } } diff --git a/Telegram/SourceFiles/gui/text.cpp b/Telegram/SourceFiles/gui/text.cpp index a7fb10ad55..2a6be8b760 100644 --- a/Telegram/SourceFiles/gui/text.cpp +++ b/Telegram/SourceFiles/gui/text.cpp @@ -544,7 +544,7 @@ public: int skipBack = 0; ch = ((ptr < end) ? *ptr : 0); chInt = ch.unicode(); - bool skip = false, isNewLine = multiline && chIsNewline(ch), isSpace = chIsSpace(ch), isDiac = chIsDiac(ch), isTilde = (ch == '~'); + bool skip = false, isNewLine = multiline && chIsNewline(ch), isSpace = chIsSpace(ch), isDiac = chIsDiac(ch), isTilde = checkTilde && (ch == '~'); if (chIsBad(ch) || ch.isLowSurrogate()) { skip = true; } else if (isDiac) { @@ -577,12 +577,12 @@ public: } else { if (isTilde) { // tilde fix in OpenSans if (!(flags & TextBlockFTilde)) { - createBlock(); + createBlock(skipBack); flags |= TextBlockFTilde; } } else { if (flags & TextBlockFTilde) { - createBlock(); + createBlock(skipBack); flags &= ~TextBlockFTilde; } } @@ -688,6 +688,7 @@ public: ch = chInt = 0; lastSkipped = false; + checkTilde = !cRetina() && _t->_font->size() == 13 && _t->_font->flags() == 0; // tilde Open Sans fix entitiesEnd = entities.cend(); waitingEntity = entities.cbegin(); while (waitingEntity != entitiesEnd && waitingEntity->length <= 0) ++waitingEntity; @@ -784,6 +785,7 @@ private: QChar ch; // current char (low surrogate, if current char is surrogate pair) uint32 chInt; // full ch, could be surrogate pair bool lastSkipped; // did we skip current char + bool checkTilde; // do we need a special text block for tilde symbol }; namespace { @@ -1785,7 +1787,7 @@ public: } if (flags & TextBlockFItalic) result = result->italic(); if (flags & TextBlockFUnderline) result = result->underline(); - if ((flags & TextBlockFTilde) && !cRetina() && f->size() == 13 && f->flags() == 0) { // tilde fix in OpenSans + if (flags & TextBlockFTilde) { // tilde fix in OpenSans result = st::semiboldFont; } } @@ -3244,7 +3246,7 @@ TextBlock::TextBlock(const style::font &font, const QString &str, QFixed minResi } if (flags & TextBlockFItalic) blockFont = blockFont->italic(); if (flags & TextBlockFUnderline) blockFont = blockFont->underline(); - if ((flags & TextBlockFTilde) && !cRetina() && font->size() == 13 && font->flags() == 0) { // tilde fix in OpenSans + if (flags & TextBlockFTilde) { // tilde fix in OpenSans blockFont = st::semiboldFont; } } diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 0fed0a2deb..d7903726f5 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -2559,7 +2559,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent) , _showAtMsgId(0) , _fixedInScrollMsgId(0) , _fixedInScrollMsgTop(0) -, _preloadRequest(0), _preloadDownRequest(0) +, _firstLoadRequest(0), _preloadRequest(0), _preloadDownRequest(0) , _delayedShowAtMsgId(-1) , _delayedShowAtRequest(0) , _activeAnimMsgId(0) diff --git a/Telegram/Telegram.pro b/Telegram/Telegram.pro index 0be8b08a96..8c851b7b25 100644 --- a/Telegram/Telegram.pro +++ b/Telegram/Telegram.pro @@ -1,6 +1,6 @@ QT += core gui network widgets -CONFIG += plugin static +CONFIG += plugin static c++11 CONFIG(debug, debug|release) { DEFINES += _DEBUG