mirror of
https://github.com/telegramdesktop/tdesktop
synced 2024-12-31 19:12:17 +00:00
Radial progress in settings when loading a new background from gallery.
MediaView handling of screen resolution change fixed. Media messages now display both name/type and caption in dialogs list. When viewing group profile photo delete affects either photo or message.
This commit is contained in:
parent
6af6ffa1b2
commit
5957382a67
@ -16,6 +16,23 @@ index eec9e1f..ec3015e 100644
|
||||
QMAKE_CFLAGS_YACC =
|
||||
QMAKE_CFLAGS_LTCG = -GL
|
||||
QMAKE_CFLAGS_SSE2 = -arch:SSE2
|
||||
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
|
||||
index f1a6019..81ff6ef 100644
|
||||
--- a/src/corelib/io/qfilesystemengine_win.cpp
|
||||
+++ b/src/corelib/io/qfilesystemengine_win.cpp
|
||||
@@ -1416,8 +1416,10 @@ bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSyst
|
||||
COPYFILE2_EXTENDED_PARAMETERS copyParams = {
|
||||
sizeof(copyParams), COPY_FILE_FAIL_IF_EXISTS, NULL, NULL, NULL
|
||||
};
|
||||
- bool ret = ::CopyFile2((const wchar_t*)source.nativeFilePath().utf16(),
|
||||
- (const wchar_t*)target.nativeFilePath().utf16(), ©Params) != 0;
|
||||
+ // CopyFile2 returns HRESULT, not BOOL, so it should be tested for S_OK, not 0.
|
||||
+ HRESULT hres = ::CopyFile2((const wchar_t*)source.nativeFilePath().utf16(),
|
||||
+ (const wchar_t*)target.nativeFilePath().utf16(), ©Params);
|
||||
+ bool ret = SUCCEEDED(hres);
|
||||
#endif // Q_OS_WINRT
|
||||
if(!ret)
|
||||
error = QSystemError(::GetLastError(), QSystemError::NativeError);
|
||||
diff --git a/src/corelib/tools/qunicodetables.cpp b/src/corelib/tools/qunicodetables.cpp
|
||||
index 14e4fd1..c31c62b 100644
|
||||
--- a/src/corelib/tools/qunicodetables.cpp
|
||||
@ -82,14 +99,14 @@ index 918c989..55ef783 100644
|
||||
+#endif
|
||||
+ }
|
||||
}
|
||||
|
||||
|
||||
// Make sure we're inside the viewport.
|
||||
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
|
||||
index 39c228f..b72fdc0 100644
|
||||
--- a/src/gui/text/qtextengine_p.h
|
||||
+++ b/src/gui/text/qtextengine_p.h
|
||||
@@ -283,7 +283,8 @@ private:
|
||||
|
||||
|
||||
struct QScriptItem;
|
||||
/// Internal QTextItem
|
||||
-class QTextItemInt : public QTextItem
|
||||
@ -119,14 +136,14 @@ index 9e2a23a..4466a4e 100644
|
||||
- while (oldPos < len && attributes[oldPos].whiteSpace)
|
||||
- oldPos++;
|
||||
}
|
||||
|
||||
|
||||
return oldPos;
|
||||
@@ -1644,6 +1645,7 @@ namespace {
|
||||
int maxGlyphs;
|
||||
int currentPosition;
|
||||
glyph_t previousGlyph;
|
||||
+ QFontEngine *previousGlyphFontEngine;
|
||||
|
||||
|
||||
QFixed minw;
|
||||
QFixed softHyphenWidth;
|
||||
@@ -1677,13 +1679,14 @@ namespace {
|
||||
@ -136,14 +153,14 @@ index 9e2a23a..4466a4e 100644
|
||||
+ previousGlyphFontEngine = fontEngine;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- inline void calculateRightBearing(glyph_t glyph)
|
||||
+ inline void calculateRightBearing(QFontEngine *engine, glyph_t glyph)
|
||||
{
|
||||
qreal rb;
|
||||
- fontEngine->getGlyphBearings(glyph, 0, &rb);
|
||||
+ engine->getGlyphBearings(glyph, 0, &rb);
|
||||
|
||||
|
||||
// We only care about negative right bearings, so we limit the range
|
||||
// of the bearing here so that we can assume it's negative in the rest
|
||||
@@ -1696,13 +1699,13 @@ namespace {
|
||||
@ -153,14 +170,14 @@ index 9e2a23a..4466a4e 100644
|
||||
- calculateRightBearing(currentGlyph());
|
||||
+ calculateRightBearing(fontEngine, currentGlyph());
|
||||
}
|
||||
|
||||
|
||||
inline void calculateRightBearingForPreviousGlyph()
|
||||
{
|
||||
if (previousGlyph > 0)
|
||||
- calculateRightBearing(previousGlyph);
|
||||
+ calculateRightBearing(previousGlyphFontEngine, previousGlyph);
|
||||
}
|
||||
|
||||
|
||||
static const QFixed RightBearingNotCalculated;
|
||||
diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h
|
||||
index f74d4d4..57d449a 100644
|
||||
@ -174,8 +191,8 @@ index f74d4d4..57d449a 100644
|
||||
+ // allow access to private constructor
|
||||
+ friend class TextBlock;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
|
||||
index ca0a8b9..26ee865 100644
|
||||
--- a/src/network/socket/qnativesocketengine_win.cpp
|
||||
@ -199,9 +216,9 @@ index 728b166..12364db 100644
|
||||
--- a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
|
||||
+++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
|
||||
@@ -172,6 +172,79 @@ void QBasicFontDatabase::releaseHandle(void *handle)
|
||||
|
||||
|
||||
extern FT_Library qt_getFreetype();
|
||||
|
||||
|
||||
+// Enable Open Sans Semibold font family reading.
|
||||
+// Copied from freetype with some modifications.
|
||||
+
|
||||
@ -295,9 +312,9 @@ index a5fe888..5878a4f 100644
|
||||
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
|
||||
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
|
||||
@@ -381,6 +381,17 @@ static void populateFromPattern(FcPattern *pattern)
|
||||
|
||||
|
||||
familyName = QString::fromUtf8((const char *)value);
|
||||
|
||||
|
||||
+ // Enable Open Sans Semibold font family reading.
|
||||
+ if (familyName == QLatin1String("Open Sans")) {
|
||||
+ FcChar8 *styl = 0;
|
||||
@ -356,7 +373,7 @@ index 0af7790..c16f154 100644
|
||||
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
|
||||
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
|
||||
@@ -259,6 +259,13 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
|
||||
|
||||
|
||||
fd->foundryName = QStringLiteral("CoreText");
|
||||
fd->familyName = (CFStringRef) CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute);
|
||||
+
|
||||
@ -11193,13 +11210,13 @@ index faea54b..7d85080 100644
|
||||
+++ b/src/plugins/platforminputcontexts/platforminputcontexts.pro
|
||||
@@ -1,7 +1,8 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
|
||||
qtHaveModule(dbus) {
|
||||
-!mac:!win32:SUBDIRS += ibus
|
||||
+# Adding fcitx input context plugin to our static build.
|
||||
+!mac:!win32:SUBDIRS += ibus fcitx
|
||||
}
|
||||
|
||||
|
||||
contains(QT_CONFIG, xcb-plugin): SUBDIRS += compose
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
|
||||
index caa8884..b083e65 100644
|
||||
@ -11213,7 +11230,7 @@ index caa8884..b083e65 100644
|
||||
+ // Don't terminate if reflectionDelegate does not respond to that selector, just use the default.
|
||||
+ //return NSTerminateNow;
|
||||
}
|
||||
|
||||
|
||||
if ([self canQuit]) {
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h
|
||||
index 5a199de..5622728 100644
|
||||
@ -11227,7 +11244,7 @@ index 5a199de..5622728 100644
|
||||
+ // Optimize redraw - don't clear image if it will be fully redrawn.
|
||||
+ bool m_qImageNeedsClear;
|
||||
};
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
|
||||
index ca92103..225d85f 100644
|
||||
@ -11235,14 +11252,14 @@ index ca92103..225d85f 100644
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
|
||||
@@ -38,7 +38,8 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
QCocoaBackingStore::QCocoaBackingStore(QWindow *window)
|
||||
- : QPlatformBackingStore(window)
|
||||
+ // Optimize redraw - don't clear image if it will be fully redrawn.
|
||||
+ : QPlatformBackingStore(window), m_qImageNeedsClear(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -59,9 +60,11 @@ QPaintDevice *QCocoaBackingStore::paintDevice()
|
||||
if (m_qImage.size() != effectiveBufferSize) {
|
||||
QImage::Format format = (window()->format().hasAlpha() || cocoaWindow->m_drawContentBorderGradient)
|
||||
@ -11257,7 +11274,7 @@ index ca92103..225d85f 100644
|
||||
}
|
||||
return &m_qImage;
|
||||
@@ -100,7 +103,8 @@ bool QCocoaBackingStore::scroll(const QRegion &area, int dx, int dy)
|
||||
|
||||
|
||||
void QCocoaBackingStore::beginPaint(const QRegion ®ion)
|
||||
{
|
||||
- if (m_qImage.hasAlphaChannel()) {
|
||||
@ -11282,7 +11299,7 @@ index c2d206f..0f9b512 100644
|
||||
+
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -466,7 +472,8 @@ QList<int> QCocoaKeyMapper::possibleKeys(const QKeyEvent *event) const
|
||||
Qt::KeyboardModifiers neededMods = ModsTbl[i];
|
||||
int key = kbItem->qtKey[i];
|
||||
@ -11316,7 +11333,7 @@ index 8152c57..a7c1ca0 100644
|
||||
+ const int padding = 0;
|
||||
const int menuHeight = [[NSStatusBar systemStatusBar] thickness];
|
||||
const int maxImageHeight = menuHeight - padding;
|
||||
|
||||
|
||||
@@ -207,8 +211,11 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
|
||||
// devicePixelRatio for the "best" screen on the system.
|
||||
qreal devicePixelRatio = qApp->devicePixelRatio();
|
||||
@ -11331,21 +11348,21 @@ index 8152c57..a7c1ca0 100644
|
||||
// with a height smaller or equal to maxPixmapHeight. The pixmap
|
||||
// may rectangular; assume it has a reasonable size. If there is
|
||||
@@ -224,9 +231,9 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
|
||||
|
||||
|
||||
// Handle SVG icons, which do not return anything for availableSizes().
|
||||
if (!selectedSize.isValid())
|
||||
- selectedSize = icon.actualSize(QSize(maxPixmapHeight, maxPixmapHeight));
|
||||
+ selectedSize = icon.actualSize(QSize(maxPixmapHeight, maxPixmapHeight), mode);
|
||||
|
||||
|
||||
- QPixmap pixmap = icon.pixmap(selectedSize);
|
||||
+ QPixmap pixmap = icon.pixmap(selectedSize, mode);
|
||||
|
||||
|
||||
// Draw a low-resolution icon if there is not enough pixels for a retina
|
||||
// icon. This prevents showing a small icon on retina displays.
|
||||
@@ -374,6 +381,11 @@ QT_END_NAMESPACE
|
||||
Q_UNUSED(notification);
|
||||
down = NO;
|
||||
|
||||
|
||||
+ // Create a rich os x tray icon (pixel-perfect, theme switching).
|
||||
+ parent->iconSelected = false;
|
||||
+ parent->systray->updateIcon(parent->icon);
|
||||
@ -11353,11 +11370,11 @@ index 8152c57..a7c1ca0 100644
|
||||
+
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
|
||||
@@ -383,6 +395,10 @@ QT_END_NAMESPACE
|
||||
int clickCount = [mouseEvent clickCount];
|
||||
[self setNeedsDisplay:YES];
|
||||
|
||||
|
||||
+ // Create a rich os x tray icon (pixel-perfect, theme switching).
|
||||
+ parent->iconSelected = (clickCount != 2) && parent->menu;
|
||||
+ parent->systray->updateIcon(parent->icon);
|
||||
@ -11376,7 +11393,7 @@ index 8152c57..a7c1ca0 100644
|
||||
+
|
||||
[self menuTrackingDone:nil];
|
||||
}
|
||||
|
||||
|
||||
@@ -410,6 +431,11 @@ QT_END_NAMESPACE
|
||||
-(void)rightMouseUp:(NSEvent *)mouseEvent
|
||||
{
|
||||
@ -11388,10 +11405,10 @@ index 8152c57..a7c1ca0 100644
|
||||
+
|
||||
[self menuTrackingDone:nil];
|
||||
}
|
||||
|
||||
|
||||
@@ -425,7 +451,8 @@ QT_END_NAMESPACE
|
||||
}
|
||||
|
||||
|
||||
-(void)drawRect:(NSRect)rect {
|
||||
- [[parent item] drawStatusBarBackgroundInRect:rect withHighlight:down];
|
||||
+ // Create a rich os x tray icon (pixel-perfect, theme switching).
|
||||
@ -11428,7 +11445,7 @@ index 00cb43c..4530862 100644
|
||||
@@ -141,7 +141,8 @@ static bool isMouseEvent(NSEvent *ev)
|
||||
if (!self.window.delegate)
|
||||
return; // Already detached, pending NSAppKitDefined event
|
||||
|
||||
|
||||
- if (pw && pw->frameStrutEventsEnabled() && isMouseEvent(theEvent)) {
|
||||
+ // Fix restore after minimize or close by window buttons.
|
||||
+ if (pw && pw->frameStrutEventsEnabled() && pw->m_synchedWindowState != Qt::WindowMinimized && pw->m_isExposed && isMouseEvent(theEvent)) {
|
||||
@ -11438,7 +11455,7 @@ index 00cb43c..4530862 100644
|
||||
@@ -931,6 +932,15 @@ void QCocoaWindow::setWindowFilePath(const QString &filePath)
|
||||
[m_nsWindow setRepresentedFilename: fi.exists() ? QCFString::toNSString(filePath) : @""];
|
||||
}
|
||||
|
||||
|
||||
+// Create a good os x window icon (pixel-perfect).
|
||||
+qreal _win_devicePixelRatio() {
|
||||
+ qreal result = 1.0;
|
||||
@ -11478,7 +11495,7 @@ index 0d80333..729d4d0 100644
|
||||
}
|
||||
@@ -1451,14 +1452,14 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
|
||||
quint32 nativeVirtualKey = [nsevent keyCode];
|
||||
|
||||
|
||||
QChar ch = QChar::ReplacementCharacter;
|
||||
- int keyCode = Qt::Key_unknown;
|
||||
- if ([characters length] != 0) {
|
||||
@ -11496,13 +11513,13 @@ index 0d80333..729d4d0 100644
|
||||
+ ch = QChar([charactersIgnoringModifiers characterAtIndex:0]);
|
||||
+
|
||||
+ int keyCode = [self convertKeyCode:ch];
|
||||
|
||||
|
||||
// we will send a key event unless the input method sets m_sendKeyEvent to false
|
||||
m_sendKeyEvent = true;
|
||||
@@ -1524,6 +1525,23 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
|
||||
[self handleKeyEvent:nsevent eventType:int(QEvent::KeyRelease)];
|
||||
}
|
||||
|
||||
|
||||
+// Enable Ctrl+Tab and Ctrl+Shift+Tab / Ctrl+Backtab handle in-app.
|
||||
+- (BOOL)performKeyEquivalent:(NSEvent *)nsevent
|
||||
+{
|
||||
@ -11530,7 +11547,7 @@ index 9211fd1..283aabd 100644
|
||||
@@ -716,12 +716,20 @@ public:
|
||||
void setSelectedFiles(const QList<QUrl> &);
|
||||
QString selectedFile() const;
|
||||
|
||||
|
||||
+ // Adding select-by-url for Windows file dialog.
|
||||
+ void setSelectedRemoteContent(const QByteArray &);
|
||||
+ QByteArray selectedRemoteContent() const;
|
||||
@ -11551,7 +11568,7 @@ index 9211fd1..283aabd 100644
|
||||
@@ -775,6 +783,21 @@ inline void QWindowsFileDialogSharedData::setSelectedFiles(const QList<QUrl> &ur
|
||||
m_data->selectedFiles = urls;
|
||||
}
|
||||
|
||||
|
||||
+// Adding select-by-url for Windows file dialog.
|
||||
+inline QByteArray QWindowsFileDialogSharedData::selectedRemoteContent() const
|
||||
+{
|
||||
@ -11573,7 +11590,7 @@ index 9211fd1..283aabd 100644
|
||||
@@ -899,6 +922,9 @@ public:
|
||||
// example by appended default suffixes, etc.
|
||||
virtual QList<QUrl> dialogResult() const = 0;
|
||||
|
||||
|
||||
+ // Adding select-by-url for Windows file dialog.
|
||||
+ virtual QByteArray dialogRemoteContent() const { return QByteArray(); }
|
||||
+
|
||||
@ -11595,7 +11612,7 @@ index 9211fd1..283aabd 100644
|
||||
+ m_fileDialog->SetFileName((wchar_t*)file.utf16());;
|
||||
+ }
|
||||
}
|
||||
|
||||
|
||||
// Return the index of the selected filter, accounting for QFileDialog
|
||||
@@ -1405,7 +1438,11 @@ bool QWindowsNativeFileDialogBase::onFileOk()
|
||||
{
|
||||
@ -11608,12 +11625,12 @@ index 9211fd1..283aabd 100644
|
||||
+
|
||||
+ return true;
|
||||
}
|
||||
|
||||
|
||||
void QWindowsNativeFileDialogBase::close()
|
||||
@@ -1534,6 +1571,9 @@ public:
|
||||
QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
|
||||
QList<QUrl> dialogResult() const Q_DECL_OVERRIDE;
|
||||
|
||||
|
||||
+ // Adding select-by-url for Windows file dialog.
|
||||
+ QByteArray dialogRemoteContent() const Q_DECL_OVERRIDE;
|
||||
+
|
||||
@ -11623,7 +11640,7 @@ index 9211fd1..283aabd 100644
|
||||
@@ -1548,6 +1588,62 @@ QList<QUrl> QWindowsNativeOpenFileDialog::dialogResult() const
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+// Adding select-by-url for Windows file dialog.
|
||||
+QByteArray QWindowsNativeOpenFileDialog::dialogRemoteContent() const
|
||||
+{
|
||||
@ -11697,7 +11714,7 @@ index 9211fd1..283aabd 100644
|
||||
@@ -1704,6 +1804,12 @@ QList<QUrl> QWindowsFileDialogHelper::selectedFiles() const
|
||||
return m_data.selectedFiles();
|
||||
}
|
||||
|
||||
|
||||
+// Adding select-by-url for Windows file dialog.
|
||||
+QByteArray QWindowsFileDialogHelper::selectedRemoteContent() const
|
||||
+{
|
||||
@ -11721,7 +11738,7 @@ index 9211fd1..283aabd 100644
|
||||
@@ -2036,6 +2146,12 @@ QList<QUrl> QWindowsXpFileDialogHelper::selectedFiles() const
|
||||
return m_data.selectedFiles();
|
||||
}
|
||||
|
||||
|
||||
+// Adding select-by-url for Windows file dialog.
|
||||
+QByteArray QWindowsXpFileDialogHelper::selectedRemoteContent() const
|
||||
+{
|
||||
@ -11747,7 +11764,7 @@ index cc697ba..c72234f 100644
|
||||
// but that cannot handle a Windows command line [yet].
|
||||
command.replace(QStringLiteral("%1"), url.toString(QUrl::FullyEncoded));
|
||||
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
|
||||
index 7f45b48..4ace49c 100644
|
||||
index 7f45b48..9d5c339 100644
|
||||
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
|
||||
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
|
||||
@@ -1025,7 +1025,8 @@ void QWindowsWindow::destroyWindow()
|
||||
@ -11782,6 +11799,24 @@ index 7f45b48..4ace49c 100644
|
||||
if (newTransientParent != oldTransientParent)
|
||||
SetWindowLongPtr(m_data.hwnd, GWL_HWNDPARENT, (LONG_PTR)newTransientParent);
|
||||
#endif // !Q_OS_WINCE
|
||||
@@ -1453,10 +1469,14 @@ void QWindowsWindow::handleResized(int wParam)
|
||||
handleGeometryChange();
|
||||
break;
|
||||
case SIZE_RESTORED:
|
||||
- if (isFullScreen_sys())
|
||||
- handleWindowStateChange(Qt::WindowFullScreen);
|
||||
- else if (m_windowState != Qt::WindowNoState && !testFlag(MaximizeToFullScreen))
|
||||
+ if (isFullScreen_sys()) {
|
||||
+ if (m_windowState != Qt::WindowFullScreen)
|
||||
+ // When resolution is changed for a frameless fullscreen widget
|
||||
+ // this call prevents correct geometry get in handleGeometryChange().
|
||||
+ handleWindowStateChange(Qt::WindowFullScreen);
|
||||
+ } else if (m_windowState != Qt::WindowNoState && !testFlag(MaximizeToFullScreen)) {
|
||||
handleWindowStateChange(Qt::WindowNoState);
|
||||
+ }
|
||||
handleGeometryChange();
|
||||
break;
|
||||
}
|
||||
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
|
||||
index 6fffa1e..288df03 100644
|
||||
--- a/src/plugins/platforms/windows/qwindowswindow.h
|
||||
@ -11804,7 +11839,7 @@ index 3f3a6e7..f1cf176 100644
|
||||
@@ -1200,6 +1200,15 @@ QList<QUrl> QFileDialogPrivate::userSelectedFiles() const
|
||||
return files;
|
||||
}
|
||||
|
||||
|
||||
+// Adding select-by-url for Windows file dialog.
|
||||
+QByteArray QFileDialogPrivate::userSelectedRemoteContent() const
|
||||
+{
|
||||
@ -11820,7 +11855,7 @@ index 3f3a6e7..f1cf176 100644
|
||||
@@ -1267,6 +1276,14 @@ QStringList QFileDialog::selectedFiles() const
|
||||
return files;
|
||||
}
|
||||
|
||||
|
||||
+// Adding select-by-url for Windows file dialog.
|
||||
+QByteArray QFileDialog::selectedRemoteContent() const
|
||||
+{
|
||||
@ -11839,13 +11874,13 @@ index ffe49a2..4213206 100644
|
||||
@@ -108,6 +108,9 @@ public:
|
||||
void selectFile(const QString &filename);
|
||||
QStringList selectedFiles() const;
|
||||
|
||||
|
||||
+ // Adding select-by-url for Windows file dialog.
|
||||
+ QByteArray selectedRemoteContent() const;
|
||||
+
|
||||
void selectUrl(const QUrl &url);
|
||||
QList<QUrl> selectedUrls() const;
|
||||
|
||||
|
||||
diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h
|
||||
index f610e46..ca71d55 100644
|
||||
--- a/src/widgets/dialogs/qfiledialog_p.h
|
||||
@ -11875,7 +11910,7 @@ index f610e46..ca71d55 100644
|
||||
@@ -393,6 +401,14 @@ inline QList<QUrl> QFileDialogPrivate::selectedFiles_sys() const
|
||||
return QList<QUrl>();
|
||||
}
|
||||
|
||||
|
||||
+// Adding select-by-url for Windows file dialog.
|
||||
+inline QByteArray QFileDialogPrivate::selectedRemoteContent_sys() const
|
||||
+{
|
||||
@ -11914,7 +11949,35 @@ index ebb2921..8119bad 100644
|
||||
+ qpa_sys->updateMenu(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp
|
||||
index 65d06ea..920f529 100644
|
||||
--- a/src/widgets/widgets/qabstractscrollarea.cpp
|
||||
+++ b/src/widgets/widgets/qabstractscrollarea.cpp
|
||||
@@ -640,15 +640,19 @@ scrolling range.
|
||||
QSize QAbstractScrollArea::maximumViewportSize() const
|
||||
{
|
||||
Q_D(const QAbstractScrollArea);
|
||||
- int hsbExt = d->hbar->sizeHint().height();
|
||||
- int vsbExt = d->vbar->sizeHint().width();
|
||||
|
||||
int f = 2 * d->frameWidth;
|
||||
QSize max = size() - QSize(f + d->left + d->right, f + d->top + d->bottom);
|
||||
- if (d->vbarpolicy == Qt::ScrollBarAlwaysOn)
|
||||
+ if (d->vbarpolicy == Qt::ScrollBarAlwaysOn) {
|
||||
+ // Count the sizeHint of the bar only if it is displayed.
|
||||
+ int vsbExt = d->vbar->sizeHint().width();
|
||||
max.rwidth() -= vsbExt;
|
||||
- if (d->hbarpolicy == Qt::ScrollBarAlwaysOn)
|
||||
+ }
|
||||
+ if (d->hbarpolicy == Qt::ScrollBarAlwaysOn) {
|
||||
+ // Count the sizeHint of the bar only if it is displayed.
|
||||
+ int hsbExt = d->hbar->sizeHint().height();
|
||||
max.rheight() -= hsbExt;
|
||||
+ }
|
||||
return max;
|
||||
}
|
||||
|
||||
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
|
||||
index 436937b..fc7a843 100644
|
||||
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
|
||||
@ -11933,7 +11996,7 @@ index 436937b..fc7a843 100644
|
||||
#endif
|
||||
@@ -1881,11 +1886,21 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event)
|
||||
}
|
||||
|
||||
|
||||
// QTBUG-35734: ignore Ctrl/Ctrl+Shift; accept only AltGr (Alt+Ctrl) on German keyboards
|
||||
- if (unknown && !isReadOnly()
|
||||
- && event->modifiers() != Qt::ControlModifier
|
||||
|
@ -2157,17 +2157,6 @@ btnContext: iconedButton(btnDefIconed) {
|
||||
downTextPos: point(16px, 8px);
|
||||
}
|
||||
|
||||
photoLoader: size(52px, 22px);
|
||||
photoLoaderBg: #00000054;
|
||||
photoLoaderCnt: 3;
|
||||
photoLoaderPoint: size(6px, 6px);
|
||||
photoLoaderSkip: 6px;
|
||||
photoLoaderPeriod: 600; // ms full period
|
||||
photoLoaderDelta: 150; // ms between points
|
||||
photoLoaderDuration1: 150; // ms fade in
|
||||
photoLoaderDuration2: 150; // ms fade out
|
||||
photoLoaderAlphaMin: 0.1; // not less than that
|
||||
|
||||
radialSize: size(50px, 50px);
|
||||
radialLine: 3px;
|
||||
radialDuration: 350;
|
||||
@ -2178,10 +2167,6 @@ radialDownloadOpacity: 0.8;
|
||||
radialCancel: sprite(378px, 50px, 18px, 18px);
|
||||
radialCancelOpacity: 1.0;
|
||||
|
||||
mediaviewLoader: size(78px, 33px);
|
||||
mediaviewLoaderPoint: size(9px, 9px);
|
||||
mediaviewLoaderSkip: 9px;
|
||||
|
||||
downloadPathSkip: 10px;
|
||||
|
||||
usernamePadding: margins(23px, 22px, 21px, 12px);
|
||||
|
@ -697,7 +697,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
"lng_in_dlg_audio" = "Voice message";
|
||||
"lng_in_dlg_file" = "File";
|
||||
"lng_in_dlg_sticker" = "Sticker";
|
||||
"lng_in_dlg_sticker_emoji" = "{emoji} (sticker)";
|
||||
"lng_in_dlg_sticker_emoji" = "{emoji} Sticker";
|
||||
|
||||
"lng_ban_user" = "Ban User";
|
||||
"lng_delete_all_from" = "Delete all from this user";
|
||||
@ -726,7 +726,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
"lng_wont_be_notified" = "Members will not be notified when you post";
|
||||
"lng_empty_history" = "";
|
||||
"lng_willbe_history" = "Please select a chat to start messaging";
|
||||
"lng_message_with_from" = "[c]{from}:[/c] {message}";
|
||||
"lng_from_you" = "You";
|
||||
"lng_from_draft" = "Draft";
|
||||
"lng_bot_description" = "What can this bot do?";
|
||||
@ -735,6 +734,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
"lng_channel_mute" = "Mute";
|
||||
"lng_channel_unmute" = "Unmute";
|
||||
|
||||
"lng_dialogs_text_with_from" = "{from_part} {message}";
|
||||
"lng_dialogs_text_from_wrapped" = "{from}:";
|
||||
"lng_dialogs_text_media" = "{media_part} {caption}";
|
||||
"lng_dialogs_text_media_wrapped" = "{media},";
|
||||
|
||||
"lng_open_this_link" = "Open this link?";
|
||||
"lng_open_link" = "Open";
|
||||
|
||||
@ -880,7 +884,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
"lng_selected_upload_stop" = "Stop";
|
||||
"lng_selected_delete_sure_this" = "Do you want to delete this message?";
|
||||
"lng_selected_delete_sure" = "Do you want to delete {count:_not_used_|# message|# messages}?";
|
||||
//"lng_delete_photo_sure" = "Do you want to delete this photo?";
|
||||
"lng_delete_photo_sure" = "Do you want to delete this photo?";
|
||||
"lng_box_delete" = "Delete";
|
||||
"lng_box_leave" = "Leave";
|
||||
|
||||
|
@ -88,10 +88,9 @@ void paintRow(Painter &p, History *history, HistoryItem *item, Data::Draft *draf
|
||||
p.setPen(active ? st::dialogsTextFgActive : st::dialogsTextFgService);
|
||||
if (history->typing.isEmpty() && history->sendActions.isEmpty()) {
|
||||
if (history->cloudDraftTextCache.isEmpty()) {
|
||||
TextCustomTagsMap custom;
|
||||
custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink()));
|
||||
QString msg = lng_message_with_from(lt_from, textRichPrepare(lang(lng_from_draft)), lt_message, textRichPrepare(draft->textWithTags.text));
|
||||
history->cloudDraftTextCache.setRichText(st::dialogsTextFont, msg, _textDlgOptions, custom);
|
||||
auto draftWrapped = textcmdLink(1, lng_dialogs_text_from_wrapped(lt_from, lang(lng_from_draft)));
|
||||
auto draftText = lng_dialogs_text_with_from(lt_from_part, draftWrapped, lt_message, textClean(draft->textWithTags.text));
|
||||
history->cloudDraftTextCache.setText(st::dialogsTextFont, draftText, _textDlgOptions);
|
||||
}
|
||||
textstyleSet(&(active ? st::dialogsTextStyleActive : st::dialogsTextStyleDraft));
|
||||
p.setFont(st::dialogsTextFont);
|
||||
|
@ -2959,6 +2959,49 @@ void HistoryItem::recountDisplayDate() {
|
||||
}
|
||||
}
|
||||
|
||||
QString HistoryItem::notificationText() const {
|
||||
auto getText = [this]() {
|
||||
if (emptyText()) {
|
||||
return _media ? _media->notificationText() : QString();
|
||||
}
|
||||
return _text.originalText();
|
||||
};
|
||||
|
||||
auto result = getText();
|
||||
if (result.size() > 0xFF) result = result.mid(0, 0xFF) + qsl("...");
|
||||
return result;
|
||||
}
|
||||
|
||||
QString HistoryItem::inDialogsText() const {
|
||||
auto getText = [this]() {
|
||||
if (emptyText()) {
|
||||
return _media ? _media->inDialogsText() : QString();
|
||||
}
|
||||
return textClean(_text.originalText());
|
||||
};
|
||||
auto plainText = getText();
|
||||
if ((!_history->peer->isUser() || out()) && !isPost() && !isEmpty()) {
|
||||
auto fromText = author()->isSelf() ? lang(lng_from_you) : author()->shortName();
|
||||
auto fromWrapped = textcmdLink(1, lng_dialogs_text_from_wrapped(lt_from, textClean(fromText)));
|
||||
return lng_dialogs_text_with_from(lt_from_part, fromWrapped, lt_message, plainText);
|
||||
}
|
||||
return plainText;
|
||||
}
|
||||
|
||||
void HistoryItem::drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const {
|
||||
if (cacheFor != this) {
|
||||
cacheFor = this;
|
||||
cache.setText(st::dialogsTextFont, inDialogsText(), _textDlgOptions);
|
||||
}
|
||||
if (r.width()) {
|
||||
textstyleSet(&(act ? st::dialogsTextStyleActive : st::dialogsTextStyle));
|
||||
p.setFont(st::dialogsTextFont);
|
||||
p.setPen(act ? st::dialogsTextFgActive : st::dialogsTextFg);
|
||||
cache.drawElided(p, r.left(), r.top(), r.width(), r.height() / st::dialogsTextFont->height);
|
||||
textstyleRestore();
|
||||
}
|
||||
}
|
||||
|
||||
HistoryItem::~HistoryItem() {
|
||||
App::historyUnregItem(this);
|
||||
if (id < 0 && App::uploader()) {
|
||||
@ -3041,6 +3084,11 @@ void RadialAnimation::draw(Painter &p, const QRect &inner, int32 thickness, cons
|
||||
p.setOpacity(o);
|
||||
}
|
||||
|
||||
QString HistoryMedia::inDialogsText() const {
|
||||
auto result = notificationText();
|
||||
return result.isEmpty() ? QString() : textcmdLink(1, textClean(result));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
int32 documentMaxStatusWidth(DocumentData *document) {
|
||||
@ -3083,6 +3131,26 @@ TextWithEntities captionedSelectedText(const QString &attachType, const Text &ca
|
||||
return result;
|
||||
}
|
||||
|
||||
QString captionedNotificationText(const QString &attachType, const Text &caption) {
|
||||
if (caption.isEmpty()) {
|
||||
return attachType;
|
||||
}
|
||||
|
||||
auto captionText = caption.originalText();
|
||||
auto attachTypeWrapped = lng_dialogs_text_media_wrapped(lt_media, attachType);
|
||||
return lng_dialogs_text_media(lt_media_part, attachTypeWrapped, lt_caption, captionText);
|
||||
}
|
||||
|
||||
QString captionedInDialogsText(const QString &attachType, const Text &caption) {
|
||||
if (caption.isEmpty()) {
|
||||
return textcmdLink(1, textClean(attachType));
|
||||
}
|
||||
|
||||
auto captionText = textClean(caption.originalText());
|
||||
auto attachTypeWrapped = textcmdLink(1, lng_dialogs_text_media_wrapped(lt_media, textClean(attachType)));
|
||||
return lng_dialogs_text_media(lt_media_part, attachTypeWrapped, lt_caption, captionText);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void HistoryFileMedia::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) {
|
||||
@ -3501,8 +3569,12 @@ void HistoryPhoto::detachFromParent() {
|
||||
App::unregPhotoItem(_data, _parent);
|
||||
}
|
||||
|
||||
QString HistoryPhoto::notificationText() const {
|
||||
return captionedNotificationText(lang(lng_in_dlg_photo), _caption);
|
||||
}
|
||||
|
||||
QString HistoryPhoto::inDialogsText() const {
|
||||
return _caption.isEmpty() ? lang(lng_in_dlg_photo) : _caption.originalText(AllTextSelection, ExpandLinksNone);
|
||||
return captionedInDialogsText(lang(lng_in_dlg_photo), _caption);
|
||||
}
|
||||
|
||||
TextWithEntities HistoryPhoto::selectedText(TextSelection selection) const {
|
||||
@ -3747,8 +3819,12 @@ void HistoryVideo::setStatusSize(int32 newSize) const {
|
||||
HistoryFileMedia::setStatusSize(newSize, _data->size, _data->duration(), 0);
|
||||
}
|
||||
|
||||
QString HistoryVideo::notificationText() const {
|
||||
return captionedNotificationText(lang(lng_in_dlg_video), _caption);
|
||||
}
|
||||
|
||||
QString HistoryVideo::inDialogsText() const {
|
||||
return _caption.isEmpty() ? lang(lng_in_dlg_video) : _caption.originalText(AllTextSelection, ExpandLinksNone);
|
||||
return captionedInDialogsText(lang(lng_in_dlg_video), _caption);
|
||||
}
|
||||
|
||||
TextWithEntities HistoryVideo::selectedText(TextSelection selection) const {
|
||||
@ -4224,28 +4300,36 @@ HistoryTextState HistoryDocument::getState(int x, int y, HistoryStateRequest req
|
||||
return result;
|
||||
}
|
||||
|
||||
QString HistoryDocument::notificationText() const {
|
||||
QString result;
|
||||
buildStringRepresentation([&result](const QString &type, const QString &fileName, const Text &caption) {
|
||||
result = captionedNotificationText(fileName.isEmpty() ? type : fileName, caption);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
QString HistoryDocument::inDialogsText() const {
|
||||
QString result;
|
||||
if (Has<HistoryDocumentVoice>()) {
|
||||
result = lang(lng_in_dlg_audio);
|
||||
} else if (auto song = _data->song()) {
|
||||
result = documentName(_data);
|
||||
if (result.isEmpty()) {
|
||||
result = lang(lng_in_dlg_audio_file);
|
||||
}
|
||||
} else {
|
||||
auto named = Get<HistoryDocumentNamed>();
|
||||
result = (!named || named->_name.isEmpty()) ? lang(lng_in_dlg_file) : named->_name;
|
||||
}
|
||||
if (auto captioned = Get<HistoryDocumentCaptioned>()) {
|
||||
if (!captioned->_caption.isEmpty()) {
|
||||
result.append(' ').append(captioned->_caption.originalText(AllTextSelection, ExpandLinksNone));
|
||||
}
|
||||
}
|
||||
buildStringRepresentation([&result](const QString &type, const QString &fileName, const Text &caption) {
|
||||
result = captionedInDialogsText(fileName.isEmpty() ? type : fileName, caption);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
TextWithEntities HistoryDocument::selectedText(TextSelection selection) const {
|
||||
TextWithEntities result;
|
||||
buildStringRepresentation([&result, selection](const QString &type, const QString &fileName, const Text &caption) {
|
||||
auto fullType = type;
|
||||
if (!fileName.isEmpty()) {
|
||||
fullType.append(qstr(" : ")).append(fileName);
|
||||
}
|
||||
result = captionedSelectedText(fullType, caption, selection);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Callback>
|
||||
void HistoryDocument::buildStringRepresentation(Callback callback) const {
|
||||
const Text emptyCaption;
|
||||
const Text *caption = &emptyCaption;
|
||||
if (auto captioned = Get<HistoryDocumentCaptioned>()) {
|
||||
@ -4257,12 +4341,14 @@ TextWithEntities HistoryDocument::selectedText(TextSelection selection) const {
|
||||
} else if (_data->song()) {
|
||||
attachType = lang(lng_in_dlg_audio_file);
|
||||
}
|
||||
|
||||
QString attachFileName;
|
||||
if (auto named = Get<HistoryDocumentNamed>()) {
|
||||
if (!named->_name.isEmpty()) {
|
||||
attachType.append(qstr(" : ")).append(named->_name);
|
||||
attachFileName = named->_name;
|
||||
}
|
||||
}
|
||||
return captionedSelectedText(attachType, *caption, selection);
|
||||
return callback(attachType, attachFileName, *caption);
|
||||
}
|
||||
|
||||
void HistoryDocument::setStatusSize(int32 newSize, qint64 realDuration) const {
|
||||
@ -4696,8 +4782,12 @@ HistoryTextState HistoryGif::getState(int x, int y, HistoryStateRequest request)
|
||||
return result;
|
||||
}
|
||||
|
||||
QString HistoryGif::notificationText() const {
|
||||
return captionedNotificationText(qsl("GIF"), _caption);
|
||||
}
|
||||
|
||||
QString HistoryGif::inDialogsText() const {
|
||||
return qsl("GIF") + (_caption.isEmpty() ? QString() : (' ' + _caption.originalText(AllTextSelection, ExpandLinksNone)));
|
||||
return captionedInDialogsText(qsl("GIF"), _caption);
|
||||
}
|
||||
|
||||
TextWithEntities HistoryGif::selectedText(TextSelection selection) const {
|
||||
@ -5014,15 +5104,19 @@ HistoryTextState HistorySticker::getState(int x, int y, HistoryStateRequest requ
|
||||
return result;
|
||||
}
|
||||
|
||||
QString HistorySticker::inDialogsText() const {
|
||||
QString HistorySticker::toString() const {
|
||||
return _emoji.isEmpty() ? lang(lng_in_dlg_sticker) : lng_in_dlg_sticker_emoji(lt_emoji, _emoji);
|
||||
}
|
||||
|
||||
QString HistorySticker::notificationText() const {
|
||||
return toString();
|
||||
}
|
||||
|
||||
TextWithEntities HistorySticker::selectedText(TextSelection selection) const {
|
||||
if (selection != FullSelection) {
|
||||
return TextWithEntities();
|
||||
}
|
||||
return { qsl("[ ") + inDialogsText() + qsl(" ]"), EntitiesInText() };
|
||||
return { qsl("[ ") + toString() + qsl(" ]"), EntitiesInText() };
|
||||
}
|
||||
|
||||
void HistorySticker::attachToParent() {
|
||||
@ -5202,7 +5296,7 @@ HistoryTextState HistoryContact::getState(int x, int y, HistoryStateRequest requ
|
||||
return result;
|
||||
}
|
||||
|
||||
QString HistoryContact::inDialogsText() const {
|
||||
QString HistoryContact::notificationText() const {
|
||||
return lang(lng_in_dlg_contact);
|
||||
}
|
||||
|
||||
@ -5723,10 +5817,6 @@ void HistoryWebPage::detachFromParent() {
|
||||
if (_attach) _attach->detachFromParent();
|
||||
}
|
||||
|
||||
QString HistoryWebPage::inDialogsText() const {
|
||||
return QString();
|
||||
}
|
||||
|
||||
TextWithEntities HistoryWebPage::selectedText(TextSelection selection) const {
|
||||
if (selection == FullSelection) {
|
||||
return TextWithEntities();
|
||||
@ -6172,8 +6262,12 @@ TextSelection HistoryLocation::adjustSelection(TextSelection selection, TextSele
|
||||
return { titleSelection.from, fromDescriptionSelection(descriptionSelection).to };
|
||||
}
|
||||
|
||||
QString HistoryLocation::notificationText() const {
|
||||
return captionedNotificationText(lang(lng_maps_point), _title);
|
||||
}
|
||||
|
||||
QString HistoryLocation::inDialogsText() const {
|
||||
return _title.isEmpty() ? lang(lng_maps_point) : _title.originalText(AllTextSelection);
|
||||
return captionedInDialogsText(lang(lng_maps_point), _title);
|
||||
}
|
||||
|
||||
TextWithEntities HistoryLocation::selectedText(TextSelection selection) const {
|
||||
@ -6301,7 +6395,7 @@ bool HistoryMessageReply::updateData(HistoryMessage *holder, bool force) {
|
||||
}
|
||||
|
||||
if (replyToMsg) {
|
||||
replyToText.setText(st::msgFont, replyToMsg->inReplyText(), _textDlgOptions);
|
||||
replyToText.setText(st::msgFont, textClean(replyToMsg->inReplyText()), _textDlgOptions);
|
||||
|
||||
updateName();
|
||||
|
||||
@ -7032,10 +7126,6 @@ TextWithEntities HistoryMessage::selectedText(TextSelection selection) const {
|
||||
return result;
|
||||
}
|
||||
|
||||
QString HistoryMessage::inDialogsText() const {
|
||||
return emptyText() ? (_media ? _media->inDialogsText() : QString()) : _text.originalText(AllTextSelection, ExpandLinksNone);
|
||||
}
|
||||
|
||||
void HistoryMessage::setMedia(const MTPMessageMedia *media) {
|
||||
if (!_media && (!media || media->type() == mtpc_messageMediaEmpty)) return;
|
||||
|
||||
@ -7698,38 +7788,10 @@ TextSelection HistoryMessage::adjustSelection(TextSelection selection, TextSelec
|
||||
return { textSelection.from, fromMediaSelection(mediaSelection).to };
|
||||
}
|
||||
|
||||
void HistoryMessage::drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const {
|
||||
if (cacheFor != this) {
|
||||
cacheFor = this;
|
||||
QString msg(inDialogsText());
|
||||
if ((!_history->peer->isUser() || out()) && !isPost() && !isEmpty()) {
|
||||
TextCustomTagsMap custom;
|
||||
custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink()));
|
||||
msg = lng_message_with_from(lt_from, textRichPrepare((author() == App::self()) ? lang(lng_from_you) : author()->shortName()), lt_message, textRichPrepare(msg));
|
||||
cache.setRichText(st::dialogsTextFont, msg, _textDlgOptions, custom);
|
||||
} else {
|
||||
cache.setText(st::dialogsTextFont, msg, _textDlgOptions);
|
||||
}
|
||||
}
|
||||
if (r.width()) {
|
||||
textstyleSet(&(act ? st::dialogsTextStyleActive : st::dialogsTextStyle));
|
||||
p.setFont(st::dialogsTextFont);
|
||||
p.setPen(act ? st::dialogsTextFgActive : (emptyText() ? st::dialogsTextFgService : st::dialogsTextFg));
|
||||
cache.drawElided(p, r.left(), r.top(), r.width(), r.height() / st::dialogsTextFont->height);
|
||||
textstyleRestore();
|
||||
}
|
||||
}
|
||||
|
||||
QString HistoryMessage::notificationHeader() const {
|
||||
return (!_history->peer->isUser() && !isPost()) ? from()->name : QString();
|
||||
}
|
||||
|
||||
QString HistoryMessage::notificationText() const {
|
||||
QString msg(inDialogsText());
|
||||
if (msg.size() > 0xFF) msg = msg.mid(0, 0xFF) + qsl("...");
|
||||
return msg;
|
||||
}
|
||||
|
||||
bool HistoryMessage::displayFromPhoto() const {
|
||||
return hasFromPhoto() && !isAttachedToPrevious();
|
||||
}
|
||||
@ -8043,11 +8105,11 @@ TextWithEntities HistoryService::selectedText(TextSelection selection) const {
|
||||
}
|
||||
|
||||
QString HistoryService::inDialogsText() const {
|
||||
return _text.originalText(AllTextSelection, ExpandLinksNone);
|
||||
return textcmdLink(1, textClean(notificationText()));
|
||||
}
|
||||
|
||||
QString HistoryService::inReplyText() const {
|
||||
QString result = HistoryService::inDialogsText();
|
||||
QString result = HistoryService::notificationText();
|
||||
return result.trimmed().startsWith(author()->name) ? result.trimmed().mid(author()->name.size()).trimmed() : result;
|
||||
}
|
||||
|
||||
@ -8184,22 +8246,6 @@ HistoryTextState HistoryService::getState(int x, int y, HistoryStateRequest requ
|
||||
return result;
|
||||
}
|
||||
|
||||
void HistoryService::drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const {
|
||||
if (cacheFor != this) {
|
||||
cacheFor = this;
|
||||
cache.setText(st::dialogsTextFont, inDialogsText(), _textDlgOptions);
|
||||
}
|
||||
QRect tr(r);
|
||||
p.setPen(act ? st::dialogsTextFgActive : st::dialogsTextFgService);
|
||||
cache.drawElided(p, tr.left(), tr.top(), tr.width(), tr.height() / st::dialogsTextFont->height);
|
||||
}
|
||||
|
||||
QString HistoryService::notificationText() const {
|
||||
QString msg = _text.originalText();
|
||||
if (msg.size() > 0xFF) msg = msg.mid(0, 0xFF) + qsl("...");
|
||||
return msg;
|
||||
}
|
||||
|
||||
void HistoryService::applyEditionToEmpty() {
|
||||
TextWithEntities textWithEntities = { QString(), EntitiesInText() };
|
||||
setServiceText(QString());
|
||||
|
@ -1212,11 +1212,17 @@ public:
|
||||
virtual TextWithEntities selectedText(TextSelection selection) const {
|
||||
return { qsl("[-]"), EntitiesInText() };
|
||||
}
|
||||
virtual QString inDialogsText() const {
|
||||
return qsl("-");
|
||||
|
||||
virtual QString notificationHeader() const {
|
||||
return QString();
|
||||
}
|
||||
virtual QString notificationText() const;
|
||||
|
||||
// Returns text with link-start and link-end commands for service-color highlighting.
|
||||
// Example: "[link1-start]You:[link1-end] [link1-start]Photo,[link1-end] caption text"
|
||||
virtual QString inDialogsText() const;
|
||||
virtual QString inReplyText() const {
|
||||
return inDialogsText();
|
||||
return notificationText();
|
||||
}
|
||||
virtual TextWithEntities originalText() const {
|
||||
return { QString(), EntitiesInText() };
|
||||
@ -1227,11 +1233,11 @@ public:
|
||||
virtual void setViewsCount(int32 count) {
|
||||
}
|
||||
virtual void setId(MsgId newId);
|
||||
virtual void drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const = 0;
|
||||
virtual QString notificationHeader() const {
|
||||
return QString();
|
||||
}
|
||||
virtual QString notificationText() const = 0;
|
||||
void drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const;
|
||||
|
||||
bool emptyText() const {
|
||||
return _text.isEmpty();
|
||||
}
|
||||
|
||||
bool canDelete() const {
|
||||
ChannelData *channel = _history->peer->asChannel();
|
||||
@ -1593,7 +1599,14 @@ public:
|
||||
HistoryMedia &operator=(const HistoryMedia &other) = delete;
|
||||
|
||||
virtual HistoryMediaType type() const = 0;
|
||||
virtual QString inDialogsText() const = 0;
|
||||
|
||||
virtual QString notificationText() const {
|
||||
return QString();
|
||||
}
|
||||
|
||||
// Returns text with link-start and link-end commands for service-color highlighting.
|
||||
// Example: "[link1-start]You:[link1-end] [link1-start]Photo,[link1-end] caption text"
|
||||
virtual QString inDialogsText() const;
|
||||
virtual TextWithEntities selectedText(TextSelection selection) const = 0;
|
||||
|
||||
bool hasPoint(int x, int y) const {
|
||||
@ -1817,6 +1830,7 @@ public:
|
||||
return !_caption.isEmpty();
|
||||
}
|
||||
|
||||
QString notificationText() const override;
|
||||
QString inDialogsText() const override;
|
||||
TextWithEntities selectedText(TextSelection selection) const override;
|
||||
|
||||
@ -1897,6 +1911,7 @@ public:
|
||||
return !_caption.isEmpty();
|
||||
}
|
||||
|
||||
QString notificationText() const override;
|
||||
QString inDialogsText() const override;
|
||||
TextWithEntities selectedText(TextSelection selection) const override;
|
||||
|
||||
@ -2020,6 +2035,7 @@ public:
|
||||
return Has<HistoryDocumentCaptioned>();
|
||||
}
|
||||
|
||||
QString notificationText() const override;
|
||||
QString inDialogsText() const override;
|
||||
TextWithEntities selectedText(TextSelection selection) const override;
|
||||
|
||||
@ -2076,11 +2092,17 @@ protected:
|
||||
|
||||
private:
|
||||
void createComponents(bool caption);
|
||||
DocumentData *_data;
|
||||
|
||||
void setStatusSize(int32 newSize, qint64 realDuration = 0) const;
|
||||
bool updateStatusText() const; // returns showPause
|
||||
|
||||
// Callback is a void(const QString &, const QString &, const Text &) functor.
|
||||
// It will be called as callback(attachType, attachFileName, attachCaption).
|
||||
template <typename Callback>
|
||||
void buildStringRepresentation(Callback callback) const;
|
||||
|
||||
DocumentData *_data;
|
||||
|
||||
};
|
||||
|
||||
class HistoryGif : public HistoryFileMedia {
|
||||
@ -2107,6 +2129,7 @@ public:
|
||||
return !_caption.isEmpty();
|
||||
}
|
||||
|
||||
QString notificationText() const override;
|
||||
QString inDialogsText() const override;
|
||||
TextWithEntities selectedText(TextSelection selection) const override;
|
||||
|
||||
@ -2205,7 +2228,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
QString inDialogsText() const override;
|
||||
QString notificationText() const override;
|
||||
TextWithEntities selectedText(TextSelection selection) const override;
|
||||
|
||||
DocumentData *getDocument() override {
|
||||
@ -2230,6 +2253,7 @@ private:
|
||||
int additionalWidth() const {
|
||||
return additionalWidth(_parent->Get<HistoryMessageVia>(), _parent->Get<HistoryMessageReply>());
|
||||
}
|
||||
QString toString() const;
|
||||
|
||||
int16 _pixw, _pixh;
|
||||
ClickHandlerPtr _packLink;
|
||||
@ -2274,7 +2298,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
QString inDialogsText() const override;
|
||||
QString notificationText() const override;
|
||||
TextWithEntities selectedText(TextSelection selection) const override;
|
||||
|
||||
void attachToParent() override;
|
||||
@ -2342,7 +2366,6 @@ public:
|
||||
return _attach && _attach->dragItemByHandler(p);
|
||||
}
|
||||
|
||||
QString inDialogsText() const override;
|
||||
TextWithEntities selectedText(TextSelection selection) const override;
|
||||
|
||||
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
|
||||
@ -2476,6 +2499,7 @@ public:
|
||||
return p == _link;
|
||||
}
|
||||
|
||||
QString notificationText() const override;
|
||||
QString inDialogsText() const override;
|
||||
TextWithEntities selectedText(TextSelection selection) const override;
|
||||
|
||||
@ -2549,9 +2573,6 @@ public:
|
||||
int32 plainMaxWidth() const;
|
||||
void countPositionAndSize(int32 &left, int32 &width) const;
|
||||
|
||||
bool emptyText() const {
|
||||
return _text.isEmpty();
|
||||
}
|
||||
bool drawBubble() const {
|
||||
return _media ? (!emptyText() || _media->needsBubble()) : !isEmpty();
|
||||
}
|
||||
@ -2593,9 +2614,7 @@ public:
|
||||
HistoryItem::clickHandlerPressedChanged(p, pressed);
|
||||
}
|
||||
|
||||
void drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const override;
|
||||
QString notificationHeader() const override;
|
||||
QString notificationText() const override;
|
||||
|
||||
void applyEdition(const MTPDmessage &message) override;
|
||||
void applyEditionToEmpty() override;
|
||||
@ -2604,7 +2623,6 @@ public:
|
||||
void eraseFromOverview() override;
|
||||
|
||||
TextWithEntities selectedText(TextSelection selection) const override;
|
||||
QString inDialogsText() const override;
|
||||
void setText(const TextWithEntities &textWithEntities) override;
|
||||
TextWithEntities originalText() const override;
|
||||
bool textHasLinks() const override;
|
||||
@ -2795,9 +2813,6 @@ public:
|
||||
HistoryItem::clickHandlerPressedChanged(p, pressed);
|
||||
}
|
||||
|
||||
void drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const override;
|
||||
QString notificationText() const override;
|
||||
|
||||
void applyEditionToEmpty() override;
|
||||
|
||||
int32 addToOverview(AddToOverviewMethod method) override;
|
||||
|
@ -5908,7 +5908,7 @@ void HistoryWidget::onKbToggle(bool manual) {
|
||||
_kbReplyTo = (_peer->isChat() || _peer->isChannel() || _keyboard.forceReply()) ? App::histItemById(_keyboard.forMsgId()) : 0;
|
||||
if (_kbReplyTo && !_editMsgId && !_replyToId && fieldEnabled) {
|
||||
updateReplyToName();
|
||||
_replyEditMsgText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions);
|
||||
_replyEditMsgText.setText(st::msgFont, textClean(_kbReplyTo->inReplyText()), _textDlgOptions);
|
||||
_fieldBarCancel.show();
|
||||
updateMouseTracking();
|
||||
}
|
||||
@ -5927,7 +5927,7 @@ void HistoryWidget::onKbToggle(bool manual) {
|
||||
_kbReplyTo = (_peer->isChat() || _peer->isChannel() || _keyboard.forceReply()) ? App::histItemById(_keyboard.forMsgId()) : 0;
|
||||
if (_kbReplyTo && !_editMsgId && !_replyToId) {
|
||||
updateReplyToName();
|
||||
_replyEditMsgText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions);
|
||||
_replyEditMsgText.setText(st::msgFont, textClean(_kbReplyTo->inReplyText()), _textDlgOptions);
|
||||
_fieldBarCancel.show();
|
||||
updateMouseTracking();
|
||||
}
|
||||
@ -7048,7 +7048,7 @@ void HistoryWidget::updateBotKeyboard(History *h, bool force) {
|
||||
_kbReplyTo = (_peer->isChat() || _peer->isChannel() || _keyboard.forceReply()) ? App::histItemById(_keyboard.forMsgId()) : 0;
|
||||
if (_kbReplyTo && !_replyToId) {
|
||||
updateReplyToName();
|
||||
_replyEditMsgText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions);
|
||||
_replyEditMsgText.setText(st::msgFont, textClean(_kbReplyTo->inReplyText()), _textDlgOptions);
|
||||
_fieldBarCancel.show();
|
||||
updateMouseTracking();
|
||||
}
|
||||
@ -7285,7 +7285,7 @@ void HistoryWidget::updatePinnedBar(bool force) {
|
||||
_pinnedBar->msg = App::histItemById(_history->channelId(), _pinnedBar->msgId);
|
||||
}
|
||||
if (_pinnedBar->msg) {
|
||||
_pinnedBar->text.setText(st::msgFont, _pinnedBar->msg->inDialogsText(), _textDlgOptions);
|
||||
_pinnedBar->text.setText(st::msgFont, textClean(_pinnedBar->msg->notificationText()), _textDlgOptions);
|
||||
update();
|
||||
} else if (force) {
|
||||
if (_peer && _peer->isMegagroup()) {
|
||||
@ -7523,7 +7523,7 @@ void HistoryWidget::onReplyToMessage() {
|
||||
} else {
|
||||
_replyEditMsg = to;
|
||||
_replyToId = to->id;
|
||||
_replyEditMsgText.setText(st::msgFont, _replyEditMsg->inDialogsText(), _textDlgOptions);
|
||||
_replyEditMsgText.setText(st::msgFont, textClean(_replyEditMsg->inReplyText()), _textDlgOptions);
|
||||
|
||||
updateBotKeyboard();
|
||||
|
||||
@ -7869,7 +7869,7 @@ void HistoryWidget::updatePreview() {
|
||||
updateMouseTracking();
|
||||
if (_previewData->pendingTill) {
|
||||
_previewTitle.setText(st::msgServiceNameFont, lang(lng_preview_loading), _textNameOptions);
|
||||
_previewDescription.setText(st::msgFont, _previewLinks.splitRef(' ').at(0).toString(), _textDlgOptions);
|
||||
_previewDescription.setText(st::msgFont, textClean(_previewLinks.splitRef(' ').at(0).toString()), _textDlgOptions);
|
||||
|
||||
int32 t = (_previewData->pendingTill - unixtime()) * 1000;
|
||||
if (t <= 0) t = 1;
|
||||
@ -7901,7 +7901,7 @@ void HistoryWidget::updatePreview() {
|
||||
}
|
||||
}
|
||||
_previewTitle.setText(st::msgServiceNameFont, title, _textNameOptions);
|
||||
_previewDescription.setText(st::msgFont, desc, _textDlgOptions);
|
||||
_previewDescription.setText(st::msgFont, textClean(desc), _textDlgOptions);
|
||||
}
|
||||
} else if (!readyToForward() && !replyToId() && !_editMsgId) {
|
||||
_fieldBarCancel.hide();
|
||||
@ -8163,7 +8163,7 @@ void HistoryWidget::updateReplyEditTexts(bool force) {
|
||||
_replyEditMsg = App::histItemById(_channel, _editMsgId ? _editMsgId : _replyToId);
|
||||
}
|
||||
if (_replyEditMsg) {
|
||||
_replyEditMsgText.setText(st::msgFont, _replyEditMsg->inDialogsText(), _textDlgOptions);
|
||||
_replyEditMsgText.setText(st::msgFont, textClean(_replyEditMsg->inReplyText()), _textDlgOptions);
|
||||
|
||||
updateBotKeyboard();
|
||||
|
||||
|
@ -40,7 +40,7 @@ TextParseOptions _textNameOptions = {
|
||||
Qt::LayoutDirectionAuto, // lang-dependent
|
||||
};
|
||||
TextParseOptions _textDlgOptions = {
|
||||
0, // flags
|
||||
TextParseRichText, // flags
|
||||
0, // maxw is style-dependent
|
||||
1, // maxh
|
||||
Qt::LayoutDirectionAuto, // lang-dependent
|
||||
|
@ -256,7 +256,7 @@ void MainWidget::updateForwardingTexts() {
|
||||
}
|
||||
}
|
||||
_toForwardFrom.setText(st::msgServiceNameFont, from, _textNameOptions);
|
||||
_toForwardText.setText(st::msgFont, text, _textDlgOptions);
|
||||
_toForwardText.setText(st::msgFont, textClean(text), _textDlgOptions);
|
||||
_toForwardNameVersion = version;
|
||||
}
|
||||
|
||||
@ -632,10 +632,9 @@ void MainWidget::deleteLayer(int32 selectedCount) {
|
||||
|
||||
void MainWidget::deletePhotoLayer(PhotoData *photo) {
|
||||
_deletingPhoto = photo;
|
||||
onDeletePhotoSure(); // langs are not ready yet
|
||||
//auto box = new ConfirmBox(lang(lng_delete_photo_sure), lang(lng_box_delete));
|
||||
//connect(box, SIGNAL(confirmed()), this, SLOT(onDeletePhotoSure()));
|
||||
//Ui::showLayer(box);
|
||||
auto box = new ConfirmBox(lang(lng_delete_photo_sure), lang(lng_box_delete));
|
||||
connect(box, SIGNAL(confirmed()), this, SLOT(onDeletePhotoSure()));
|
||||
Ui::showLayer(box);
|
||||
}
|
||||
|
||||
void MainWidget::onDeletePhotoSure() {
|
||||
@ -1843,7 +1842,14 @@ void MainWidget::setChatBackground(const App::WallPaper &wp) {
|
||||
}
|
||||
|
||||
bool MainWidget::chatBackgroundLoading() {
|
||||
return !!_background;
|
||||
return (_background != nullptr);
|
||||
}
|
||||
|
||||
float64 MainWidget::chatBackgroundProgress() const {
|
||||
if (_background) {
|
||||
return _background->full->progress();
|
||||
}
|
||||
return 1.;
|
||||
}
|
||||
|
||||
void MainWidget::checkChatBackground() {
|
||||
|
@ -345,6 +345,7 @@ public:
|
||||
|
||||
void setChatBackground(const App::WallPaper &wp);
|
||||
bool chatBackgroundLoading();
|
||||
float64 chatBackgroundProgress() const;
|
||||
void checkChatBackground();
|
||||
ImagePtr newBackgroundThumb();
|
||||
|
||||
|
@ -88,6 +88,8 @@ MediaView::MediaView() : TWidget(App::wnd())
|
||||
_saveMsg = QRect(0, 0, _saveMsgText.maxWidth() + st::medviewSaveMsgPadding.left() + st::medviewSaveMsgPadding.right(), st::medviewSaveMsgFont->height + st::medviewSaveMsgPadding.top() + st::medviewSaveMsgPadding.bottom());
|
||||
_saveMsgText.setLink(1, MakeShared<SaveMsgClickHandler>(this));
|
||||
|
||||
connect(QApplication::desktop(), SIGNAL(resized(int)), this, SLOT(onScreenResized(int)));
|
||||
|
||||
_transparentBrush = QBrush(App::sprite().copy(st::mvTransparentBrush.rect()));
|
||||
|
||||
setWindowFlags(Qt::FramelessWindowHint | Qt::BypassWindowManagerHint | Qt::Tool | Qt::NoDropShadowWindowHint);
|
||||
@ -98,6 +100,7 @@ MediaView::MediaView() : TWidget(App::wnd())
|
||||
|
||||
hide();
|
||||
createWinId();
|
||||
setWindowState(Qt::WindowFullScreen);
|
||||
|
||||
_saveMsgUpdater.setSingleShot(true);
|
||||
connect(&_saveMsgUpdater, SIGNAL(timeout()), this, SLOT(updateImage()));
|
||||
@ -163,7 +166,10 @@ void MediaView::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) {
|
||||
if (_photo && _overview == OverviewChatPhotos && _history && !_history->peer->isUser()) {
|
||||
auto lastChatPhoto = computeLastOverviewChatPhoto();
|
||||
if (_index < 0 && _photo == lastChatPhoto.photo && _photo == _additionalChatPhoto) {
|
||||
return showPhoto(_photo, lastChatPhoto.item);
|
||||
auto firstOpened = _firstOpenedPeerPhoto;
|
||||
showPhoto(_photo, lastChatPhoto.item);
|
||||
_firstOpenedPeerPhoto = firstOpened;
|
||||
return;
|
||||
}
|
||||
computeAdditionalChatPhoto(_history->peer, lastChatPhoto.photo);
|
||||
}
|
||||
@ -484,7 +490,6 @@ void MediaView::step_radial(uint64 ms, bool timer) {
|
||||
location.accessDisable();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -543,6 +548,29 @@ void MediaView::onDropdownHiding() {
|
||||
}
|
||||
}
|
||||
|
||||
void MediaView::onScreenResized(int screen) {
|
||||
if (isHidden()) return;
|
||||
|
||||
bool ignore = false;
|
||||
auto screens = QApplication::screens();
|
||||
if (screen >= 0 && screen < screens.size()) {
|
||||
if (auto screenHandle = windowHandle()->screen()) {
|
||||
if (screens.at(screen) != screenHandle) {
|
||||
ignore = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ignore) {
|
||||
moveToScreen();
|
||||
auto item = (_msgid ? App::histItemById(_msgmigrated ? 0 : _channel, _msgid) : nullptr);
|
||||
if (_photo) {
|
||||
displayPhoto(_photo, item);
|
||||
} else if (_doc) {
|
||||
displayDocument(_doc, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MediaView::onToMessage() {
|
||||
if (HistoryItem *item = _msgid ? App::histItemById(_msgmigrated ? 0 : _channel, _msgid) : 0) {
|
||||
if (App::wnd()) {
|
||||
@ -735,7 +763,18 @@ void MediaView::onForward() {
|
||||
|
||||
void MediaView::onDelete() {
|
||||
close();
|
||||
if (!_msgid) {
|
||||
auto deletingPeerPhoto = [this]() {
|
||||
if (!_msgid) return true;
|
||||
if (_photo && _history) {
|
||||
auto lastPhoto = computeLastOverviewChatPhoto();
|
||||
if (lastPhoto.photo == _photo && _history->peer->photoId == _photo->id) {
|
||||
return _firstOpenedPeerPhoto;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
if (deletingPeerPhoto()) {
|
||||
App::main()->deletePhotoLayer(_photo);
|
||||
} else if (auto item = App::histItemById(_msgmigrated ? 0 : _channel, _msgid)) {
|
||||
App::contextItem(item);
|
||||
@ -784,6 +823,7 @@ void MediaView::showPhoto(PhotoData *photo, HistoryItem *context) {
|
||||
_migrated = nullptr;
|
||||
}
|
||||
_additionalChatPhoto = nullptr;
|
||||
_firstOpenedPeerPhoto = false;
|
||||
_peer = 0;
|
||||
_user = 0;
|
||||
_saveMsgStarted = 0;
|
||||
@ -825,6 +865,7 @@ void MediaView::showPhoto(PhotoData *photo, HistoryItem *context) {
|
||||
void MediaView::showPhoto(PhotoData *photo, PeerData *context) {
|
||||
_history = _migrated = nullptr;
|
||||
_additionalChatPhoto = nullptr;
|
||||
_firstOpenedPeerPhoto = true;
|
||||
_peer = context;
|
||||
_user = context->asUser();
|
||||
_saveMsgStarted = 0;
|
||||
@ -868,7 +909,9 @@ void MediaView::showPhoto(PhotoData *photo, PeerData *context) {
|
||||
|
||||
auto lastChatPhoto = computeLastOverviewChatPhoto();
|
||||
if (_photo == lastChatPhoto.photo) {
|
||||
return showPhoto(_photo, lastChatPhoto.item);
|
||||
showPhoto(_photo, lastChatPhoto.item);
|
||||
_firstOpenedPeerPhoto = true;
|
||||
return;
|
||||
}
|
||||
|
||||
computeAdditionalChatPhoto(_history->peer, lastChatPhoto.photo);
|
||||
|
@ -85,6 +85,8 @@ public slots:
|
||||
void onHideControls(bool force = false);
|
||||
void onDropdownHiding();
|
||||
|
||||
void onScreenResized(int screen);
|
||||
|
||||
void onToMessage();
|
||||
void onSaveAs();
|
||||
void onDownload();
|
||||
@ -194,6 +196,12 @@ private:
|
||||
// in the _history->overview[OverviewChatPhotos] (if the item was deleted).
|
||||
PhotoData *_additionalChatPhoto = nullptr;
|
||||
|
||||
// We save the information about the reason of the current mediaview show:
|
||||
// did we open a peer profile photo or a photo from some message.
|
||||
// We use it when trying to delete a photo: if we've opened a peer photo,
|
||||
// then we'll delete group photo instead of the corresponding message.
|
||||
bool _firstOpenedPeerPhoto = false;
|
||||
|
||||
PeerData *_from = nullptr;
|
||||
Text _fromName;
|
||||
|
||||
|
@ -188,6 +188,7 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : TWidget(parent)
|
||||
, _tileBackground(this, lang(lng_settings_bg_tile), cTileBackground())
|
||||
, _adaptiveForWide(this, lang(lng_settings_adaptive_wide), Global::AdaptiveForWide())
|
||||
, _needBackgroundUpdate(false)
|
||||
, _radial(animation(this, &SettingsInner::step_radial))
|
||||
|
||||
// advanced
|
||||
, _passcodeEdit(this, lang(cHasPasscode() ? lng_passcode_change : lng_passcode_turn_on))
|
||||
@ -318,6 +319,10 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : TWidget(parent)
|
||||
connect(&_tileBackground, SIGNAL(changed()), this, SLOT(onTileBackground()));
|
||||
connect(&_adaptiveForWide, SIGNAL(changed()), this, SLOT(onAdaptiveForWide()));
|
||||
|
||||
if (radialLoading()) {
|
||||
radialStart();
|
||||
}
|
||||
|
||||
// advanced
|
||||
connect(&_passcodeEdit, SIGNAL(clicked()), this, SLOT(onPasscode()));
|
||||
connect(&_passcodeTurnOff, SIGNAL(clicked()), this, SLOT(onPasscodeOff()));
|
||||
@ -385,18 +390,6 @@ void SettingsInner::peerUpdated(PeerData *data) {
|
||||
}
|
||||
|
||||
void SettingsInner::paintEvent(QPaintEvent *e) {
|
||||
bool animateBackground = false;
|
||||
if (App::main() && App::main()->chatBackgroundLoading()) {
|
||||
App::main()->checkChatBackground();
|
||||
if (App::main()->chatBackgroundLoading()) {
|
||||
animateBackground = true;
|
||||
} else {
|
||||
updateChatBackground();
|
||||
}
|
||||
} else if (_needBackgroundUpdate) {
|
||||
updateChatBackground();
|
||||
}
|
||||
|
||||
Painter p(this);
|
||||
|
||||
p.setClipRect(e->rect());
|
||||
@ -620,32 +613,35 @@ void SettingsInner::paintEvent(QPaintEvent *e) {
|
||||
p.drawText(_left + st::setHeaderLeft, top + st::setHeaderTop + st::setHeaderFont->ascent, lang(lng_settings_section_background));
|
||||
top += st::setHeaderSkip;
|
||||
|
||||
if (animateBackground) {
|
||||
const QPixmap &pix = App::main()->newBackgroundThumb()->pixBlurred(st::setBackgroundSize);
|
||||
|
||||
p.drawPixmap(_left, top, st::setBackgroundSize, st::setBackgroundSize, pix, 0, (pix.height() - st::setBackgroundSize) / 2, st::setBackgroundSize, st::setBackgroundSize);
|
||||
|
||||
uint64 dt = getms();
|
||||
int32 cnt = int32(st::photoLoaderCnt), period = int32(st::photoLoaderPeriod), t = dt % period, delta = int32(st::photoLoaderDelta);
|
||||
|
||||
int32 x = _left + (st::setBackgroundSize - st::mediaviewLoader.width()) / 2;
|
||||
int32 y = top + (st::setBackgroundSize - st::mediaviewLoader.height()) / 2;
|
||||
p.fillRect(x, y, st::mediaviewLoader.width(), st::mediaviewLoader.height(), st::photoLoaderBg->b);
|
||||
|
||||
x += (st::mediaviewLoader.width() - cnt * st::mediaviewLoaderPoint.width() - (cnt - 1) * st::mediaviewLoaderSkip) / 2;
|
||||
y += (st::mediaviewLoader.height() - st::mediaviewLoaderPoint.height()) / 2;
|
||||
QColor c(st::white->c);
|
||||
QBrush b(c);
|
||||
for (int32 i = 0; i < cnt; ++i) {
|
||||
t -= delta;
|
||||
while (t < 0) t += period;
|
||||
|
||||
float64 alpha = (t >= st::photoLoaderDuration1 + st::photoLoaderDuration2) ? 0 : ((t > st::photoLoaderDuration1 ? ((st::photoLoaderDuration1 + st::photoLoaderDuration2 - t) / st::photoLoaderDuration2) : (t / st::photoLoaderDuration1)));
|
||||
c.setAlphaF(st::photoLoaderAlphaMin + alpha * (1 - st::photoLoaderAlphaMin));
|
||||
b.setColor(c);
|
||||
p.fillRect(x + i * (st::mediaviewLoaderPoint.width() + st::mediaviewLoaderSkip), y, st::mediaviewLoaderPoint.width(), st::mediaviewLoaderPoint.height(), b);
|
||||
bool radial = false;
|
||||
float64 radialOpacity = 0;
|
||||
if (_radial.animating()) {
|
||||
_radial.step(getms());
|
||||
radial = _radial.animating();
|
||||
radialOpacity = _radial.opacity();
|
||||
}
|
||||
if (radial) {
|
||||
auto backThumb = App::main() ? App::main()->newBackgroundThumb() : ImagePtr();
|
||||
if (backThumb->isNull()) {
|
||||
p.drawPixmap(_left, top, _background);
|
||||
} else {
|
||||
const QPixmap &pix = App::main()->newBackgroundThumb()->pixBlurred(st::setBackgroundSize);
|
||||
p.drawPixmap(_left, top, st::setBackgroundSize, st::setBackgroundSize, pix, 0, (pix.height() - st::setBackgroundSize) / 2, st::setBackgroundSize, st::setBackgroundSize);
|
||||
}
|
||||
QTimer::singleShot(AnimationTimerDelta, this, SLOT(updateBackgroundRect()));
|
||||
|
||||
auto outer = radialRect();
|
||||
QRect inner(QPoint(outer.x() + (outer.width() - st::radialSize.width()) / 2, outer.y() + (outer.height() - st::radialSize.height()) / 2), st::radialSize);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(st::black);
|
||||
p.setOpacity(radialOpacity * st::radialBgOpacity);
|
||||
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||
p.drawEllipse(inner);
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
||||
|
||||
p.setOpacity(1);
|
||||
QRect arc(inner.marginsRemoved(QMargins(st::radialLine, st::radialLine, st::radialLine, st::radialLine)));
|
||||
_radial.draw(p, arc, st::radialLine, st::white);
|
||||
} else {
|
||||
p.drawPixmap(_left, top, _background);
|
||||
}
|
||||
@ -953,7 +949,7 @@ void SettingsInner::passcodeChanged() {
|
||||
}
|
||||
|
||||
void SettingsInner::updateBackgroundRect() {
|
||||
update(_left, _tileBackground.y() - st::setLittleSkip - st::setBackgroundSize, st::setBackgroundSize, st::setBackgroundSize);
|
||||
update(radialRect());
|
||||
}
|
||||
|
||||
void SettingsInner::onFullPeerUpdated(PeerData *peer) {
|
||||
@ -1657,6 +1653,53 @@ void SettingsInner::onBackFromFile() {
|
||||
updateChatBackground();
|
||||
}
|
||||
|
||||
float64 SettingsInner::radialProgress() const {
|
||||
if (auto m = App::main()) {
|
||||
return m->chatBackgroundProgress();
|
||||
}
|
||||
return 1.;
|
||||
}
|
||||
|
||||
bool SettingsInner::radialLoading() const {
|
||||
if (auto m = App::main()) {
|
||||
if (m->chatBackgroundLoading()) {
|
||||
m->checkChatBackground();
|
||||
if (m->chatBackgroundLoading()) {
|
||||
return true;
|
||||
} else {
|
||||
const_cast<SettingsInner*>(this)->updateChatBackground();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QRect SettingsInner::radialRect() const {
|
||||
auto left = _left;
|
||||
auto top = _tileBackground.y() - st::setLittleSkip - st::setBackgroundSize;
|
||||
return QRect(left, top, st::setBackgroundSize, st::setBackgroundSize);
|
||||
}
|
||||
|
||||
void SettingsInner::radialStart() {
|
||||
if (radialLoading() && !_radial.animating()) {
|
||||
_radial.start(radialProgress());
|
||||
if (auto shift = radialTimeShift()) {
|
||||
_radial.update(radialProgress(), !radialLoading(), getms() + shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64 SettingsInner::radialTimeShift() const {
|
||||
return st::radialDuration;
|
||||
}
|
||||
|
||||
void SettingsInner::step_radial(uint64 ms, bool timer) {
|
||||
_radial.update(radialProgress(), !radialLoading(), ms + radialTimeShift());
|
||||
if (timer && _radial.animating()) {
|
||||
updateBackgroundRect();
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsInner::updateChatBackground() {
|
||||
int32 size = st::setBackgroundSize * cIntRetinaFactor();
|
||||
QImage back(size, size, QImage::Format_ARGB32_Premultiplied);
|
||||
@ -1673,6 +1716,7 @@ void SettingsInner::updateChatBackground() {
|
||||
_background = QPixmap::fromImage(back);
|
||||
_background.setDevicePixelRatio(cRetinaFactor());
|
||||
_needBackgroundUpdate = false;
|
||||
|
||||
updateBackgroundRect();
|
||||
}
|
||||
|
||||
@ -1680,6 +1724,9 @@ void SettingsInner::needBackgroundUpdate(bool tile) {
|
||||
_needBackgroundUpdate = true;
|
||||
_tileBackground.setChecked(tile);
|
||||
updateChatBackground();
|
||||
if (radialLoading()) {
|
||||
radialStart();
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsInner::onTileBackground() {
|
||||
|
@ -285,6 +285,15 @@ private:
|
||||
FlatCheckbox _tileBackground, _adaptiveForWide;
|
||||
bool _needBackgroundUpdate;
|
||||
|
||||
// Radial animation interface.
|
||||
RadialAnimation _radial;
|
||||
float64 radialProgress() const;
|
||||
bool radialLoading() const;
|
||||
QRect radialRect() const;
|
||||
void radialStart();
|
||||
uint64 radialTimeShift() const;
|
||||
void step_radial(uint64 ms, bool timer);
|
||||
|
||||
// advanced
|
||||
LinkButton _passcodeEdit, _passcodeTurnOff, _autoLock;
|
||||
QString _autoLockText;
|
||||
|
Loading…
Reference in New Issue
Block a user