diff --git a/Telegram/Resources/style.txt b/Telegram/Resources/style.txt index 69abf56f4..f95169460 100644 --- a/Telegram/Resources/style.txt +++ b/Telegram/Resources/style.txt @@ -30,6 +30,8 @@ counterBG: #b42f35; counterMuteBG: #777; counterColor: #fff; +lineWidth: 1px; + transparent: rgba(255, 255, 255, 0); white: rgba(255, 255, 255, 255); black: rgba(0, 0, 0, 255); @@ -1000,6 +1002,7 @@ btnCancelSearch: iconedButton(btnNewGroup) { notifyBG: white; notifyBorder: #f1f1f1; +notifyBorderWidth: 1px; notifySlowHide: 4000; notifyPhotoSize: 62px; notifyPhotoPos: point(9px, 9px); diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index a600950d7..517a53bf1 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -113,7 +113,7 @@ namespace App { Window *w(wnd()); if (w) { w->tempDirDelete(); - w->psClearNotifyFast(); + w->notifyClearFast(); w->setupIntro(true); } MainWidget *m(main()); @@ -1828,7 +1828,7 @@ namespace App { setQuiting(); if (wnd()) { - wnd()->psClearNotifyFast(); + wnd()->notifyClearFast(); } if (app()) { app()->quit(); diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index 395b23c56..7be317a70 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -85,6 +85,16 @@ Application::Application(int &argc, char **argv) : PsApplication(argc, argv), QFontDatabase::addApplicationFont(qsl(":/gui/art/OpenSans-Bold.ttf")); QFontDatabase::addApplicationFont(qsl(":/gui/art/OpenSans-Semibold.ttf")); + { + QImage img(800, 600, QImage::Format_ARGB32_Premultiplied); + QPainter p(&img); + QFont f; + f.setPixelSize(24); + f.setFamily("Open Sans Semibold"); + p.setFont(f); + p.drawText(0, 0, "t"); + } + float64 dpi = primaryScreen()->logicalDotsPerInch(); if (dpi <= 108) { // 0-96-108 cSetScreenScale(dbisOne); diff --git a/Telegram/SourceFiles/boxes/addcontactbox.cpp b/Telegram/SourceFiles/boxes/addcontactbox.cpp index 2ac12c875..5638554b2 100644 --- a/Telegram/SourceFiles/boxes/addcontactbox.cpp +++ b/Telegram/SourceFiles/boxes/addcontactbox.cpp @@ -179,8 +179,7 @@ void AddContactBox::paintEvent(QPaintEvent *e) { p.fillRect(0, size().height() - st::btnSelectCancel.height - st::scrollDef.bottomsh, _width, st::scrollDef.bottomsh, st::scrollDef.shColor->b); // paint button sep - p.setPen(st::btnSelectSep->p); - p.drawLine(st::btnSelectCancel.width, size().height() - st::btnSelectCancel.height, st::btnSelectCancel.width, size().height() - 1); + p.fillRect(st::btnSelectCancel.width, size().height() - st::btnSelectCancel.height, st::lineWidth, st::btnSelectCancel.height, st::btnSelectSep->b); // draw box title / text p.setPen(st::black->p); diff --git a/Telegram/SourceFiles/boxes/addparticipantbox.cpp b/Telegram/SourceFiles/boxes/addparticipantbox.cpp index 3253f76f0..5659c657c 100644 --- a/Telegram/SourceFiles/boxes/addparticipantbox.cpp +++ b/Telegram/SourceFiles/boxes/addparticipantbox.cpp @@ -587,8 +587,7 @@ void AddParticipantBox::paintEvent(QPaintEvent *e) { p.fillRect(0, st::participantFilter.height, _width, st::scrollDef.topsh, st::scrollDef.shColor->b); // paint button sep - p.setPen(st::btnSelectSep->p); - p.drawLine(st::btnSelectCancel.width, size().height() - st::btnSelectCancel.height, st::btnSelectCancel.width, size().height() - 1); + p.fillRect(st::btnSelectCancel.width, size().height() - st::btnSelectCancel.height, st::lineWidth, st::btnSelectCancel.height, st::btnSelectSep->b); // draw box title / text p.setPen(st::black->p); diff --git a/Telegram/SourceFiles/boxes/confirmbox.cpp b/Telegram/SourceFiles/boxes/confirmbox.cpp index e1dfdf6ef..3e0f91f90 100644 --- a/Telegram/SourceFiles/boxes/confirmbox.cpp +++ b/Telegram/SourceFiles/boxes/confirmbox.cpp @@ -82,8 +82,7 @@ void ConfirmBox::paintEvent(QPaintEvent *e) { p.fillRect(0, _height - st::btnSelectCancel.height - st::scrollDef.bottomsh, _width, st::scrollDef.bottomsh, st::scrollDef.shColor->b); // paint button sep - p.setPen(st::btnSelectSep->p); - p.drawLine(st::btnSelectCancel.width, _height - st::btnSelectCancel.height, st::btnSelectCancel.width, _height - 1); + p.fillRect(st::btnSelectCancel.width, _height - st::btnSelectCancel.height, st::lineWidth, st::btnSelectCancel.height, st::btnSelectSep->b); // draw box title / text p.setFont(st::boxFont->f); diff --git a/Telegram/SourceFiles/boxes/connectionbox.cpp b/Telegram/SourceFiles/boxes/connectionbox.cpp index 047270462..f34d8c63a 100644 --- a/Telegram/SourceFiles/boxes/connectionbox.cpp +++ b/Telegram/SourceFiles/boxes/connectionbox.cpp @@ -136,8 +136,7 @@ void ConnectionBox::paintEvent(QPaintEvent *e) { p.fillRect(0, _height - st::btnSelectCancel.height - st::scrollDef.bottomsh, _width, st::scrollDef.bottomsh, st::scrollDef.shColor->b); // paint button sep - p.setPen(st::btnSelectSep->p); - p.drawLine(st::btnSelectCancel.width, _height - st::btnSelectCancel.height, st::btnSelectCancel.width, _height - 1); + p.fillRect(st::btnSelectCancel.width, _height - st::btnSelectCancel.height, st::lineWidth, st::btnSelectCancel.height, st::btnSelectSep->b); // draw box title / text p.setFont(st::addContactTitleFont->f); diff --git a/Telegram/SourceFiles/boxes/contactsbox.cpp b/Telegram/SourceFiles/boxes/contactsbox.cpp index 94cb2b509..242903f11 100644 --- a/Telegram/SourceFiles/boxes/contactsbox.cpp +++ b/Telegram/SourceFiles/boxes/contactsbox.cpp @@ -479,8 +479,7 @@ void ContactsBox::paintEvent(QPaintEvent *e) { p.fillRect(0, _addContact.height(), _width, st::scrollDef.topsh, st::scrollDef.shColor->b); // paint button sep - p.setPen(st::btnSelectSep->p); - p.drawLine(st::btnSelectCancel.width, size().height() - st::btnSelectCancel.height, st::btnSelectCancel.width, size().height() - 1); + p.fillRect(st::btnSelectCancel.width, size().height() - st::btnSelectCancel.height, st::lineWidth, st::btnSelectCancel.height, st::btnSelectSep->b); // draw box title / text p.setPen(st::black->p); diff --git a/Telegram/SourceFiles/boxes/downloadpathbox.cpp b/Telegram/SourceFiles/boxes/downloadpathbox.cpp index 0b5d76c19..018261873 100644 --- a/Telegram/SourceFiles/boxes/downloadpathbox.cpp +++ b/Telegram/SourceFiles/boxes/downloadpathbox.cpp @@ -109,8 +109,7 @@ void DownloadPathBox::paintEvent(QPaintEvent *e) { p.fillRect(0, _height - st::btnSelectCancel.height - st::scrollDef.bottomsh, _width, st::scrollDef.bottomsh, st::scrollDef.shColor->b); // paint button sep - p.setPen(st::btnSelectSep->p); - p.drawLine(st::btnSelectCancel.width, _height - st::btnSelectCancel.height, st::btnSelectCancel.width, _height - 1); + p.fillRect(st::btnSelectCancel.width, _height - st::btnSelectCancel.height, st::lineWidth, st::btnSelectCancel.height, st::btnSelectSep->b); // draw box title / text p.setFont(st::addContactTitleFont->f); diff --git a/Telegram/SourceFiles/boxes/newgroupbox.cpp b/Telegram/SourceFiles/boxes/newgroupbox.cpp index 4f994aeb0..a2822e94a 100644 --- a/Telegram/SourceFiles/boxes/newgroupbox.cpp +++ b/Telegram/SourceFiles/boxes/newgroupbox.cpp @@ -530,8 +530,7 @@ void NewGroupBox::paintEvent(QPaintEvent *e) { p.fillRect(0, st::participantFilter.height, _width, st::scrollDef.topsh, st::scrollDef.shColor->b); // paint button sep - p.setPen(st::btnSelectSep->p); - p.drawLine(st::btnSelectCancel.width, size().height() - st::btnSelectCancel.height, st::btnSelectCancel.width, size().height() - 1); + p.fillRect(st::btnSelectCancel.width, size().height() - st::btnSelectCancel.height, st::lineWidth, st::btnSelectCancel.height, st::btnSelectSep->b); // draw box title / text p.setPen(st::black->p); @@ -677,8 +676,7 @@ void CreateGroupBox::paintEvent(QPaintEvent *e) { p.fillRect(0, _height - st::btnSelectCancel.height - st::scrollDef.bottomsh, _width, st::scrollDef.bottomsh, st::scrollDef.shColor->b); // paint button sep - p.setPen(st::btnSelectSep->p); - p.drawLine(st::btnSelectCancel.width, _height - st::btnSelectCancel.height, st::btnSelectCancel.width, size().height() - 1); + p.fillRect(st::btnSelectCancel.width, _height - st::btnSelectCancel.height, st::lineWidth, st::btnSelectCancel.height, st::btnSelectSep->b); // draw box title / text p.setPen(st::black->p); diff --git a/Telegram/SourceFiles/boxes/photocropbox.cpp b/Telegram/SourceFiles/boxes/photocropbox.cpp index 8729aabd6..90bf787c1 100644 --- a/Telegram/SourceFiles/boxes/photocropbox.cpp +++ b/Telegram/SourceFiles/boxes/photocropbox.cpp @@ -218,8 +218,7 @@ void PhotoCropBox::paintEvent(QPaintEvent *e) { p.fillRect(0, _height - st::btnSelectCancel.height - st::scrollDef.bottomsh, _width, st::scrollDef.bottomsh, st::scrollDef.shColor->b); // paint button sep - p.setPen(st::btnSelectSep->p); - p.drawLine(st::btnSelectCancel.width, _height - st::btnSelectCancel.height, st::btnSelectCancel.width, _height - 1); + p.fillRect(st::btnSelectCancel.width, _height - st::btnSelectCancel.height, st::lineWidth, st::btnSelectCancel.height, st::btnSelectSep->b); p.setFont(st::boxFont->f); p.setPen(st::boxGrayTitle->p); diff --git a/Telegram/SourceFiles/boxes/photosendbox.cpp b/Telegram/SourceFiles/boxes/photosendbox.cpp index c31670d89..405e28068 100644 --- a/Telegram/SourceFiles/boxes/photosendbox.cpp +++ b/Telegram/SourceFiles/boxes/photosendbox.cpp @@ -91,8 +91,7 @@ void PhotoSendBox::paintEvent(QPaintEvent *e) { p.fillRect(0, _height - st::btnSelectCancel.height - st::scrollDef.bottomsh, _width, st::scrollDef.bottomsh, st::scrollDef.shColor->b); // paint button sep - p.setPen(st::btnSelectSep->p); - p.drawLine(st::btnSelectCancel.width, _height - st::btnSelectCancel.height, st::btnSelectCancel.width, _height - 1); + p.fillRect(st::btnSelectCancel.width, _height - st::btnSelectCancel.height, st::lineWidth, st::btnSelectCancel.height, st::btnSelectSep->b); p.setFont(st::boxFont->f); p.setPen(st::boxGrayTitle->p); diff --git a/Telegram/SourceFiles/config.h b/Telegram/SourceFiles/config.h index 92168928a..52ebb0aae 100644 --- a/Telegram/SourceFiles/config.h +++ b/Telegram/SourceFiles/config.h @@ -171,7 +171,7 @@ enum { NoUpdatesTimeout = 180 * 1000, // if nothing is received in 3 min we reconnect MemoryForImageCache = 64 * 1024 * 1024, // after 64mb of unpacked images we try to clear some memory - NotifyWindows = 3, // 3 desktop notifies at the same time + NotifyWindowsCount = 3, // 3 desktop notifies at the same time NotifyWaitTimeout = 1200, // 1.2 seconds timeout before notification NotifySettingSaveTimeout = 1000, // wait 1 second before saving notify setting to server UpdateChunk = 100 * 1024, // 100kb parts when downloading the update diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index 655fc2d47..13802c6c6 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -1169,7 +1169,7 @@ void DialogsWidget::onFilterUpdate() { list.onFilterUpdate(filterText); DialogsListWidget::State s = list.state(); bool switcherVisible = (s != DialogsListWidget::DefaultState); - if (switcherVisible && _stateSwitcher.isHidden() || !switcherVisible && !_stateSwitcher.isHidden()) { + if ((switcherVisible && _stateSwitcher.isHidden()) || (!switcherVisible && !_stateSwitcher.isHidden())) { if (switcherVisible) { _stateSwitcher.show(); } else { @@ -1232,10 +1232,7 @@ void DialogsWidget::keyPressEvent(QKeyEvent *e) { void DialogsWidget::paintEvent(QPaintEvent *e) { QPainter p(this); if (_drawShadow) { - p.setPen(st::dlgShadowColor->p); - for (int i = 0, w = width() - st::dlgShadow; i < st::dlgShadow; ++i) { - p.drawLine(w + i, 0, w + i, height()); - } + p.fillRect(width() - st::dlgShadow, 0, st::dlgShadow, height(), st::dlgShadowColor->b); } } diff --git a/Telegram/SourceFiles/dropdown.cpp b/Telegram/SourceFiles/dropdown.cpp index 51c81c16a..a1b50545a 100644 --- a/Telegram/SourceFiles/dropdown.cpp +++ b/Telegram/SourceFiles/dropdown.cpp @@ -71,10 +71,8 @@ void Dropdown::paintEvent(QPaintEvent *e) { int32 top = st::dropdownPadding.top() + _buttons.front()->height(); p.setPen(st::dropdownBorderColor->p); for (int32 i = 1, s = _buttons.size(); i < s; ++i) { - for (int32 e = top + st::dropdownBorder; top < e; ++top) { - p.drawLine(st::dropdownPadding.left(), top, _width - st::dropdownPadding.right() - 1, top); - } - top += _buttons[i]->height(); + p.fillRect(st::dropdownPadding.left(), top, _width - st::dropdownPadding.left() - st::dropdownPadding.right(), st::dropdownBorder, st::dropdownBorderColor->b); + top += st::dropdownBorder + _buttons[i]->height(); } } } diff --git a/Telegram/SourceFiles/gui/boxshadow.cpp b/Telegram/SourceFiles/gui/boxshadow.cpp index 245c8e514..f90e06413 100644 --- a/Telegram/SourceFiles/gui/boxshadow.cpp +++ b/Telegram/SourceFiles/gui/boxshadow.cpp @@ -66,9 +66,9 @@ void BoxShadow::paint(QPainter &p, const QRect &box, const QPoint &shift, int32 if (left && bottom) p.drawPixmap(box.left() - _size + minus + shift.x(), box.bottom() - minus + 1 + shift.y(), _corners, 0, _size, _size, _size); for (int32 i = 1; i <= count; ++i) { p.setPen(_colors[i - 1]->p); - if (top) p.drawLine(box.left() + (left ? minus : 0) + shift.x(), box.top() - count + i + shift.y(), box.right() - (right ? minus : 0) + shift.x(), box.top() - count + i + shift.y()); - if (right) p.drawLine(box.right() + count - i + shift.x(), box.top() + (top ? minus : 0) + shift.y(), box.right() + count - i + shift.x(), box.bottom() - (bottom ? minus : 0) + shift.y()); - if (bottom) p.drawLine(box.right() - (right ? minus : 0) + shift.x(), box.bottom() + count - i + shift.y(), box.left() + (left ? minus : 0) + shift.x(), box.bottom() + count - i + shift.y()); - if (left) p.drawLine(box.left() - count + i + shift.x(), box.bottom() - (bottom ? minus : 0) + shift.y(), box.left() - count + i + shift.x(), box.top() + (top ? minus : 0) + shift.y()); + if (top) p.fillRect(box.left() + (left ? minus : 0) + shift.x(), box.top() - count + i + shift.y(), box.width() - (right ? minus : 0) - (left ? minus : 0), st::lineWidth, _colors[i - 1]->b); + if (right) p.fillRect(box.right() + count - i + shift.x(), box.top() + (top ? minus : 0) + shift.y(), st::lineWidth, box.height() - (bottom ? minus : 0) - (top ? minus : 0), _colors[i - 1]->b); + if (bottom) p.fillRect(box.left() + (left ? minus : 0) + shift.x(), box.bottom() + count - i + shift.y(), box.width() - (right ? minus : 0) - (left ? minus : 0), st::lineWidth, _colors[i - 1]->b); + if (left) p.fillRect(box.left() - count + i + shift.x(), box.top() + (top ? minus : 0) + shift.y(), st::lineWidth, box.height() - (bottom ? minus : 0) - (top ? minus : 0), _colors[i - 1]->b); } } diff --git a/Telegram/SourceFiles/gui/countryinput.cpp b/Telegram/SourceFiles/gui/countryinput.cpp index 45ad9de78..55870cc4a 100644 --- a/Telegram/SourceFiles/gui/countryinput.cpp +++ b/Telegram/SourceFiles/gui/countryinput.cpp @@ -492,8 +492,7 @@ void CountrySelect::paintEvent(QPaintEvent *e) { p.fillRect(_innerLeft, _innerTop + st::participantFilter.height, _innerWidth, st::scrollDef.topsh, st::scrollDef.shColor->b); // paint button sep - p.setPen(st::btnSelectSep->p); - p.drawLine(_innerLeft + st::btnSelectCancel.width, _innerTop + _innerHeight - st::btnSelectCancel.height, _innerLeft + st::btnSelectCancel.width, _innerTop + _innerHeight - 1); + p.fillRect(_innerLeft + st::btnSelectCancel.width, _innerTop + _innerHeight - st::btnSelectCancel.height, st::lineWidth, st::btnSelectCancel.height, st::btnSelectSep->b); // draw box title / text p.setPen(st::black->p); diff --git a/Telegram/SourceFiles/gui/flatbutton.cpp b/Telegram/SourceFiles/gui/flatbutton.cpp index 152cabf72..fb4c31281 100644 --- a/Telegram/SourceFiles/gui/flatbutton.cpp +++ b/Telegram/SourceFiles/gui/flatbutton.cpp @@ -101,8 +101,7 @@ BottomButton::BottomButton(QWidget *w, const QString &t, const style::flatButton void BottomButton::paintEvent(QPaintEvent *e) { QPainter p(this); - p.setPen(st::scrollDef.shColor->p); - p.drawLine(0, 0, width(), 0); + p.fillRect(0, 0, width(), st::lineWidth, st::scrollDef.shColor->b); FlatButton::paintEvent(e); } diff --git a/Telegram/SourceFiles/gui/flatinput.cpp b/Telegram/SourceFiles/gui/flatinput.cpp index f032001f4..90fbe6067 100644 --- a/Telegram/SourceFiles/gui/flatinput.cpp +++ b/Telegram/SourceFiles/gui/flatinput.cpp @@ -133,10 +133,11 @@ void FlatInput::paintEvent(QPaintEvent *e) { QPainter p(this); p.fillRect(rect(), a_bgColor.current()); if (_st.borderWidth) { - p.setPen(a_borderColor.current()); - for (uint32 i = 0; i < _st.borderWidth; ++i) { - p.drawRect(i, i, width() - 2 * i - 1, height() - 2 * i - 1); - } + QBrush b(a_borderColor.current()); + p.fillRect(0, 0, width() - _st.borderWidth, _st.borderWidth, b); + p.fillRect(width() - _st.borderWidth, 0, _st.borderWidth, height() - _st.borderWidth, b); + p.fillRect(_st.borderWidth, height() - _st.borderWidth, width() - _st.borderWidth, _st.borderWidth, b); + p.fillRect(0, _st.borderWidth, _st.borderWidth, height() - _st.borderWidth, b); } if (_st.imgRect.pxWidth()) { p.drawPixmap(_st.imgPos, App::sprite(), _st.imgRect); diff --git a/Telegram/SourceFiles/gui/switcher.cpp b/Telegram/SourceFiles/gui/switcher.cpp index bcb9605ea..006969526 100644 --- a/Telegram/SourceFiles/gui/switcher.cpp +++ b/Telegram/SourceFiles/gui/switcher.cpp @@ -115,10 +115,10 @@ void Switcher::paintEvent(QPaintEvent *e) { } } if (_st.border) { - p.setPen(_st.borderColor->p); - for (uint32 i = 0; i < _st.border; ++i) { - p.drawRect(i, i, width() - 2 * i - 1, height() - 2 * i - 1); - } + p.fillRect(0, 0, width() - _st.border, _st.border, _st.borderColor->b); + p.fillRect(width() - _st.border, 0, _st.border, height() - _st.border, _st.borderColor->b); + p.fillRect(_st.border, height() - _st.border, width() - _st.border, _st.border, _st.borderColor->b); + p.fillRect(0, _st.border, _st.border, height() - _st.border, _st.borderColor->b); } } diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index 22a760467..c33747f83 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -1253,7 +1253,7 @@ void History::inboxRead(bool byThisInstance) { if (!dialogs.isEmpty()) { if (App::main()) App::main()->dlgUpdated(dialogs[0]); } - App::wnd()->psClearNotify(this); + App::wnd()->notifyClear(this); clearNotifications(); } @@ -1392,7 +1392,7 @@ void History::loadAround(MsgId msgId) { if (!loadedAtBottom()) { clear(true); } - newLoaded = isEmpty() || last && !last->detached(); + newLoaded = isEmpty() || (last && !last->detached()); } } } @@ -3462,8 +3462,7 @@ void HistoryUnreadBar::setCount(int32 count) { void HistoryUnreadBar::draw(QPainter &p, uint32 selection) const { p.fillRect(0, 1, _history->width, st::unreadBarHeight - 2, st::unreadBarBG->b); - p.setPen(st::unreadBarBorder->p); - p.drawLine(0, st::unreadBarHeight - 1, _history->width, st::unreadBarHeight - 1); + p.fillRect(0, st::unreadBarHeight - st::lineWidth, _history->width, st::lineWidth, st::unreadBarBorder->b); p.setFont(st::unreadBarFont->f); p.setPen(st::unreadBarColor->p); p.drawText(QRect(0, 0, _history->width, st::unreadBarHeight - 1), text, style::al_center); diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 673b446ee..ebc311ec0 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -554,7 +554,7 @@ void HistoryList::mouseReleaseEvent(QMouseEvent *e) { } void HistoryList::mouseDoubleClickEvent(QMouseEvent *e) { - if ((_dragAction == Selecting && !_selected.isEmpty() && _selected.cbegin().value() != FullItemSel || _dragAction == NoDrag && (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel)) && _dragSelType == TextSelectLetters && _dragItem) { + if (((_dragAction == Selecting && !_selected.isEmpty() && _selected.cbegin().value() != FullItemSel) || (_dragAction == NoDrag && (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel))) && _dragSelType == TextSelectLetters && _dragItem) { bool afterDragSymbol, uponSelected; uint16 symbol; _dragItem->getSymbol(symbol, afterDragSymbol, uponSelected, _dragStartPos.x(), _dragStartPos.y()); @@ -1334,8 +1334,7 @@ void HistoryHider::paintEvent(QPaintEvent *e) { p.fillRect(box.x(), box.y() + box.height() - st::btnSelectCancel.height - st::scrollDef.bottomsh, box.width(), st::scrollDef.bottomsh, st::scrollDef.shColor->b); // paint button sep - p.setPen(st::btnSelectSep->p); - p.drawLine(box.x() + st::btnSelectCancel.width, box.y() + box.height() - st::btnSelectCancel.height, box.x() + st::btnSelectCancel.width, box.y() + box.height() - 1); + p.fillRect(box.x() + st::btnSelectCancel.width, box.y() + box.height() - st::btnSelectCancel.height, st::lineWidth, st::btnSelectCancel.height, st::btnSelectSep->b); p.setPen(st::black->p); toText.drawElided(p, box.left() + (box.width() - toTextWidth) / 2, box.top() + st::boxPadding.top(), toTextWidth + 1); @@ -1820,7 +1819,7 @@ void HistoryWidget::newUnreadMsg(History *history, MsgId msgId) { } } else { if (hist != history) { - App::wnd()->psNotify(history, msgId); + App::wnd()->notifySchedule(history, msgId); } history->setUnreadCount(history->unreadCount + 1); } @@ -1830,7 +1829,7 @@ void HistoryWidget::newUnreadMsg(History *history, MsgId msgId) { if (history->unreadBar) history->unreadBar->destroy(); } } - App::wnd()->psNotify(history, msgId); + App::wnd()->notifySchedule(history, msgId); history->setUnreadCount(history->unreadCount + 1); history->lastWidth = 0; } @@ -1956,7 +1955,7 @@ void HistoryWidget::messagesReceived(const MTPmessages_Messages &messages, mtpRe addMessagesToFront(histPreload); histPreload.clear(); loadMessages(); - } else if (down && histPreloadDown.size() || !down && histPreload.size()) { + } else if ((down && histPreloadDown.size()) || (!down && histPreload.size())) { onListScroll(); } else if (down) { loadMessagesDown(); @@ -2779,7 +2778,7 @@ void HistoryWidget::updateListSize(int32 addToY, bool initial, bool loadedDown) } if (!hist->readyForWork()) return; - if (!initial && !wasAtBottom || loadedDown) { + if ((!initial && !wasAtBottom) || loadedDown) { _scroll.scrollToY(newSt + addToY); return; } diff --git a/Telegram/SourceFiles/logs.cpp b/Telegram/SourceFiles/logs.cpp index 8b6c30e41..e55b3f888 100644 --- a/Telegram/SourceFiles/logs.cpp +++ b/Telegram/SourceFiles/logs.cpp @@ -116,7 +116,7 @@ void logsInit() { static _StreamCreator streamCreator; if (mainLogStream) return; -#ifdef Q_OS_MAC +#if defined Q_OS_MAC && !defined _DEBUG cForceWorkingDir(psAppDataPath()); #endif diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 84789d3d3..ce9b11f2e 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -155,10 +155,7 @@ void TopBarWidget::paintEvent(QPaintEvent *e) { int a = 0; // optimize shadow-only drawing } if (_drawShadow) { - p.setPen(st::titleShadowColor->p); - for (int32 i = 0; i < st::titleShadow; ++i) { - p.drawLine(st::titleShadow, st::topBarHeight + i, width(), st::topBarHeight + i); - } + p.fillRect(st::titleShadow, st::topBarHeight, width() - st::titleShadow, st::titleShadow, st::titleShadowColor->b); } } @@ -1314,7 +1311,7 @@ void MainWidget::applyNotifySetting(const MTPNotifyPeer &peer, const MTPPeerNoti if (peerId) { if (!history) history = App::history(peerId); if (isNotifyMuted(setTo)) { - App::wnd()->psClearNotify(history); + App::wnd()->notifyClear(history); history->setMute(true); } else { history->setMute(false); @@ -1344,7 +1341,7 @@ void MainWidget::gotNotifySetting(MTPInputNotifyPeer peer, const MTPPeerNotifySe } break; } - App::wnd()->psNotifySettingGot(); + App::wnd()->notifySettingGot(); } bool MainWidget::failNotifySetting(MTPInputNotifyPeer peer) { diff --git a/Telegram/SourceFiles/mtproto/mtpFileLoader.cpp b/Telegram/SourceFiles/mtproto/mtpFileLoader.cpp index f441bbd03..6406dcd56 100644 --- a/Telegram/SourceFiles/mtproto/mtpFileLoader.cpp +++ b/Telegram/SourceFiles/mtproto/mtpFileLoader.cpp @@ -167,7 +167,7 @@ void mtpFileLoader::partLoaded(int32 offset, const MTPupload_File &result) { } removeFromQueue(); App::wnd()->update(); - App::wnd()->psUpdateNotifies(); + App::wnd()->notifyUpdateAll(); } emit progress(this); } diff --git a/Telegram/SourceFiles/mtproto/mtpRPC.h b/Telegram/SourceFiles/mtproto/mtpRPC.h index 8fa3a8886..f27438b30 100644 --- a/Telegram/SourceFiles/mtproto/mtpRPC.h +++ b/Telegram/SourceFiles/mtproto/mtpRPC.h @@ -474,7 +474,7 @@ class RPCBindedDoneHandlerOwnedReq : public RPCOwnedDoneHandler { // done(b, res typedef TReturn (TReceiver::*CallbackType)(T, const TResponse &, mtpRequestId); public: - RPCBindedDoneHandlerOwnedReq(T b, TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _b(b), _onDone(onDone) { + RPCBindedDoneHandlerOwnedReq(T b, TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _onDone(onDone), _b(b) { } virtual void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const { if (_owner) (static_cast(_owner)->*_onDone)(_b, TResponse(from, end), requestId); diff --git a/Telegram/SourceFiles/pspecific_mac.cpp b/Telegram/SourceFiles/pspecific_mac.cpp index 27045ad52..c80536ef5 100644 --- a/Telegram/SourceFiles/pspecific_mac.cpp +++ b/Telegram/SourceFiles/pspecific_mac.cpp @@ -44,7 +44,7 @@ namespace { void MacPrivate::activeSpaceChanged() { if (App::wnd()) { - App::wnd()->psActivateNotifies(); + App::wnd()->notifyActivateAll(); } } @@ -54,7 +54,7 @@ void MacPrivate::notifyClicked(unsigned long long peer) { App::wnd()->showFromTray(); App::wnd()->hideSettings(); App::main()->showPeer(history->peer->id, false, true); - App::wnd()->psClearNotify(history); + App::wnd()->notifyClear(history); } void MacPrivate::notifyReplied(unsigned long long peer, const char *str) { @@ -67,8 +67,6 @@ PsMainWindow::PsMainWindow(QWidget *parent) : QMainWindow(parent), posInited(false), trayIcon(0), trayIconMenu(0), icon256(qsl(":/gui/art/iconround256.png")) { connect(&psIdleTimer, SIGNAL(timeout()), this, SLOT(psIdleTimeout())); psIdleTimer.setSingleShot(false); - connect(¬ifyWaitTimer, SIGNAL(timeout()), this, SLOT(psNotifyFire())); - notifyWaitTimer.setSingleShot(true); } void PsMainWindow::psNotIdle() const { @@ -287,497 +285,39 @@ void PsMainWindow::psFlash() { PsMainWindow::~PsMainWindow() { finished = true; - psClearNotifyFast(); } -void PsMainWindow::psNotify(History *history, MsgId msgId) { - if (App::quiting() || !history->notifyFrom) return; - - bool haveSetting = (history->peer->notify != UnknownNotifySettings); - if (haveSetting) { - if (history->peer->notify != EmptyNotifySettings && history->peer->notify->mute > unixtime()) { - history->clearNotifyFrom(); - return; - } - } else { - App::wnd()->getNotifySetting(MTP_inputNotifyPeer(history->peer->input)); - } - - uint64 ms = getms() + NotifyWaitTimeout; - notifyWhenAlerts[history].insert(ms); - if (cDesktopNotify()) { - NotifyWhenMaps::iterator i = notifyWhenMaps.find(history); - if (i == notifyWhenMaps.end()) { - i = notifyWhenMaps.insert(history, NotifyWhenMap()); - } - if (i.value().constFind(msgId) == i.value().cend()) { - i.value().insert(msgId, ms); - } - NotifyWaiters *addTo = haveSetting ? ¬ifyWaiters : ¬ifySettingWaiters; - if (addTo->constFind(history) == addTo->cend()) { - addTo->insert(history, NotifyWaiter(msgId, ms)); - } - } - if (haveSetting) { - if (!notifyWaitTimer.isActive()) { - notifyWaitTimer.start(NotifyWaitTimeout); - } - } +void PsMainWindow::psClearNotifies(PeerId peerId) { + _private.clearNotifies(peerId); } -void PsMainWindow::psNotifyFire() { - psShowNextNotify(); -} - -void PsMainWindow::psNotifySettingGot() { - int32 t = unixtime(); - for (NotifyWaiters::iterator i = notifySettingWaiters.begin(); i != notifySettingWaiters.end();) { - History *history = i.key(); - if (history->peer->notify == UnknownNotifySettings) { - ++i; - } else { - if (history->peer->notify == EmptyNotifySettings || history->peer->notify->mute <= t) { - notifyWaiters.insert(i.key(), i.value()); - } - i = notifySettingWaiters.erase(i); - } - } - notifyWaitTimer.stop(); - psShowNextNotify(); -} - -void PsMainWindow::psClearNotify(History *history) { - if (!history) { - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->unlinkHistory(); - } - _private.clearNotifies(); - for (NotifyWhenMaps::const_iterator i = notifyWhenMaps.cbegin(), e = notifyWhenMaps.cend(); i != e; ++i) { - i.key()->clearNotifyFrom(); - } - notifyWaiters.clear(); - notifySettingWaiters.clear(); - notifyWhenMaps.clear(); - return; - } - notifyWaiters.remove(history); - notifySettingWaiters.remove(history); - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->unlinkHistory(history); - } - _private.clearNotifies(history->peer->id); - notifyWhenMaps.remove(history); - notifyWhenAlerts.remove(history); -} - -void PsMainWindow::psClearNotifyFast() { - notifyWaiters.clear(); - notifySettingWaiters.clear(); - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->deleteLater(); - } - _private.clearNotifies(); - notifyWindows.clear(); - notifyWhenMaps.clear(); - notifyWhenAlerts.clear(); -} - -void PsMainWindow::psActivateNotifies() { - if (cCustomNotifies()) { - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - _private.activateWnd((*i)->winId()); - } - } +void PsMainWindow::psActivateNotify(NotifyWindow *w) { + _private.activateWnd(w->winId()); } namespace { QRect _monitorRect; uint64 _monitorLastGot = 0; - QRect _desktopRect() { - uint64 tnow = getms(); - if (tnow > _monitorLastGot + 1000 || tnow < _monitorLastGot) { - _monitorLastGot = tnow; - _monitorRect = QApplication::desktop()->availableGeometry(App::wnd()); - } - return _monitorRect; +} + +QRect psDesktopRect() { + uint64 tnow = getms(); + if (tnow > _monitorLastGot + 1000 || tnow < _monitorLastGot) { + _monitorLastGot = tnow; + _monitorRect = QApplication::desktop()->availableGeometry(App::wnd()); } + return _monitorRect; } -void PsMainWindow::psShowNextNotify(PsNotifyWindow *remove) { - if (App::quiting()) return; - - int32 count = NotifyWindows; - if (remove) { - for (PsNotifyWindows::iterator i = notifyWindows.begin(), e = notifyWindows.end(); i != e; ++i) { - if ((*i) == remove) { - notifyWindows.erase(i); - break; - } - } - } - - uint64 ms = getms(), nextAlert = 0; - bool alert = false; - for (NotifyWhenAlerts::iterator i = notifyWhenAlerts.begin(); i != notifyWhenAlerts.end();) { - while (!i.value().isEmpty() && *i.value().begin() <= ms) { - i.value().erase(i.value().begin()); - NotifySettingsPtr n = i.key()->peer->notify; - if (n == EmptyNotifySettings || (n != UnknownNotifySettings && n->mute <= unixtime())) { - alert = true; - } - } - if (i.value().isEmpty()) { - i = notifyWhenAlerts.erase(i); - } else { - if (!nextAlert || nextAlert > *i.value().begin()) { - nextAlert = *i.value().begin(); - } - ++i; - } - } - if (alert) { - psFlash(); - App::playSound(); - } - - if (cCustomNotifies()) { - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - int32 ind = (*i)->index(); - if (ind < 0) continue; - --count; - } - } - if (count <= 0 || !cDesktopNotify()) { - if (nextAlert) { - notifyWaitTimer.start(nextAlert - ms); - } - return; - } - - QRect r = _desktopRect(); - int32 x = r.x() + r.width() - st::notifyWidth - st::notifyDeltaX, y = r.y() + r.height() - st::notifyHeight - st::notifyDeltaY; - while (count > 0) { - uint64 next = 0; - HistoryItem *notifyItem = 0; - NotifyWaiters::iterator notifyWaiter; - for (NotifyWaiters::iterator i = notifyWaiters.begin(); i != notifyWaiters.end(); ++i) { - History *history = i.key(); - if (history->notifyFrom && history->notifyFrom->id != i.value().msg) { - NotifyWhenMaps::iterator j = notifyWhenMaps.find(history); - if (j == notifyWhenMaps.end()) { - history->clearNotifyFrom(); - i = notifyWaiters.erase(i); - continue; - } - do { - NotifyWhenMap::const_iterator k = j.value().constFind(history->notifyFrom->id); - if (k != j.value().cend()) { - i.value().msg = k.key(); - i.value().when = k.value(); - break; - } - history->getNextNotifyFrom(); - } while (history->notifyFrom); - } - if (!history->notifyFrom) { - notifyWhenMaps.remove(history); - i = notifyWaiters.erase(i); - continue; - } - uint64 when = i.value().when; - if (!notifyItem || next > when) { - next = when; - notifyItem = history->notifyFrom; - notifyWaiter = i; - } - } - if (notifyItem) { - if (next > ms) { - if (nextAlert && nextAlert < next) { - next = nextAlert; - nextAlert = 0; - } - notifyWaitTimer.start(next - ms); - break; - } else { - if (cCustomNotifies()) { - PsNotifyWindow *notify = new PsNotifyWindow(notifyItem, x, y); - notifyWindows.push_back(notify); - notify->hide(); - _private.holdOnTop(notify->winId()); - notify->show(); - _private.showOverAll(notify->winId()); - --count; - } else { - _private.showNotify(notifyItem->history()->peer->id, notifyItem->history()->peer->name, notifyItem->notificationHeader(), notifyItem->notificationText()); - } - - uint64 ms = getms(); - History *history = notifyItem->history(); - history->getNextNotifyFrom(); - NotifyWhenMaps::iterator j = notifyWhenMaps.find(history); - if (j == notifyWhenMaps.end() || !history->notifyFrom) { - history->clearNotifyFrom(); - notifyWaiters.erase(notifyWaiter); - if (j != notifyWhenMaps.end()) notifyWhenMaps.erase(j); - continue; - } - j.value().remove(notifyItem->id); - do { - NotifyWhenMap::const_iterator k = j.value().constFind(history->notifyFrom->id); - if (k != j.value().cend()) { - notifyWaiter.value().msg = k.key(); - notifyWaiter.value().when = k.value(); - break; - } - history->getNextNotifyFrom(); - } while (history->notifyFrom); - if (!history->notifyFrom) { - notifyWaiters.erase(notifyWaiter); - notifyWhenMaps.erase(j); - continue; - } - } - } else { - break; - } - } - if (nextAlert) { - notifyWaitTimer.start(nextAlert - ms); - } - - count = NotifyWindows - count; - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - int32 ind = (*i)->index(); - if (ind < 0) continue; - --count; - (*i)->moveTo(x, y - count * (st::notifyHeight + st::notifyDeltaY)); - } +void PsMainWindow::psNotifyShown(NotifyWindow *w) { + w->hide(); + _private.holdOnTop(w->winId()); + w->show(); + _private.showOverAll(w->winId()); } -void PsMainWindow::psStopHiding() { - if (cCustomNotifies()) { - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->stopHiding(); - } - } -} - -void PsMainWindow::psStartHiding() { - if (cCustomNotifies()) { - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->startHiding(); - } - } -} - -void PsMainWindow::psUpdateNotifies() { - if (cCustomNotifies()) { - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->updatePeerPhoto(); - } - } -} - -PsNotifyWindow::PsNotifyWindow(HistoryItem *item, int32 x, int32 y) : history(item->history()),// started(GetTickCount()), -close(this, st::notifyClose), alphaDuration(st::notifyFastAnim), posDuration(st::notifyFastAnim), hiding(false), _index(0), aOpacity(0), aOpacityFunc(st::notifyFastAnimFunc), aY(y + st::notifyHeight + st::notifyDeltaY) { - - int32 w = st::notifyWidth, h = st::notifyHeight; - QImage img(w * cIntRetinaFactor(), h * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); - if (cRetina()) img.setDevicePixelRatio(cRetinaFactor()); - img.fill(st::notifyBG->c); - - { - QPainter p(&img); - p.setPen(st::notifyBorder->p); - p.setBrush(Qt::NoBrush); - p.drawRect(0, 0, w - 1, h - 1); - - if (history->peer->photo->loaded()) { - p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), history->peer->photo->pix(st::notifyPhotoSize)); - } else { - MTP::clearLoaderPriorities(); - peerPhoto = history->peer->photo; - peerPhoto->load(true, true); - } - - int32 itemWidth = w - st::notifyPhotoPos.x() - st::notifyPhotoSize - st::notifyTextLeft - st::notifyClosePos.x() - st::notifyClose.width; - - QRect rectForName(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyTextTop, itemWidth, st::msgNameFont->height); - if (history->peer->chat) { - p.drawPixmap(QPoint(rectForName.left() + st::dlgChatImgLeft, rectForName.top() + st::dlgChatImgTop), App::sprite(), st::dlgChatImg); - rectForName.setLeft(rectForName.left() + st::dlgChatImgSkip); - } - - QDateTime now(QDateTime::currentDateTime()), lastTime(item->date); - QDate nowDate(now.date()), lastDate(lastTime.date()); - QString dt = lastTime.toString(qsl("hh:mm")); - int32 dtWidth = st::dlgHistFont->m.width(dt); - rectForName.setWidth(rectForName.width() - dtWidth - st::dlgDateSkip); - p.setFont(st::dlgDateFont->f); - p.setPen(st::dlgDateColor->p); - p.drawText(rectForName.left() + rectForName.width() + st::dlgDateSkip, rectForName.top() + st::dlgHistFont->ascent, dt); - - const HistoryItem *textCachedFor = 0; - Text itemTextCache(itemWidth); - bool active = false; - item->drawInDialog(p, QRect(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height, itemWidth, 2 * st::dlgFont->height), active, textCachedFor, itemTextCache); - - p.setPen(st::dlgNameColor->p); - history->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); - } - pm = QPixmap::fromImage(img); - - hideTimer.setSingleShot(true); - connect(&hideTimer, SIGNAL(timeout()), this, SLOT(hideByTimer())); - - inputTimer.setSingleShot(true); - connect(&inputTimer, SIGNAL(timeout()), this, SLOT(checkLastInput())); - - connect(&close, SIGNAL(clicked()), this, SLOT(unlinkHistory())); - close.setAcceptBoth(true); - close.move(w - st::notifyClose.width - st::notifyClosePos.x(), st::notifyClosePos.y()); - close.show(); - - aY.start(y); - setGeometry(x, aY.current(), st::notifyWidth, st::notifyHeight); - - aOpacity.start(1); - setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint); - setAttribute(Qt::WA_MacAlwaysShowToolWindow); - - show(); - - setWindowOpacity(aOpacity.current()); - - alphaDuration = posDuration = st::notifyFastAnim; - anim::start(this); - - checkLastInput(); -} - -void PsNotifyWindow::checkLastInput() { - // TODO - if (true) { - hideTimer.start(st::notifyWaitLongHide); - } else { - inputTimer.start(300); - } -} - -void PsNotifyWindow::moveTo(int32 x, int32 y, int32 index) { - if (index >= 0) { - _index = index; - } - move(x, aY.current()); - aY.start(y); - aOpacity.restart(); - posDuration = st::notifyFastAnim; - anim::start(this); -} - -void PsNotifyWindow::updatePeerPhoto() { - if (!peerPhoto->isNull() && peerPhoto->loaded()) { - QImage img(pm.toImage()); - { - QPainter p(&img); - p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), peerPhoto->pix(st::notifyPhotoSize)); - } - peerPhoto = ImagePtr(); - pm = QPixmap::fromImage(img); - update(); - } -} - -void PsNotifyWindow::unlinkHistory(History *hist) { - if (!hist || hist == history) { - animHide(st::notifyFastAnim, st::notifyFastAnimFunc); - history = 0; - App::wnd()->psShowNextNotify(); - } -} - -void PsNotifyWindow::enterEvent(QEvent */*e*/) { - if (!history) return; - if (App::wnd()) App::wnd()->psStopHiding(); -} - -void PsNotifyWindow::leaveEvent(QEvent */*e*/) { - if (!history) return; - App::wnd()->psStartHiding(); -} - -void PsNotifyWindow::startHiding() { - hideTimer.start(st::notifyWaitShortHide); -} - -void PsNotifyWindow::mousePressEvent(QMouseEvent *e) { - if (!history) return; - if (e->button() == Qt::RightButton) { - unlinkHistory(); - } else if (history) { - App::wnd()->showFromTray(); - App::wnd()->hideSettings(); - App::main()->showPeer(history->peer->id, false, true); - unlinkHistory(); - e->ignore(); - } -} - -void PsNotifyWindow::paintEvent(QPaintEvent *e) { - QPainter p(this); - p.drawPixmap(0, 0, pm); -} - -void PsNotifyWindow::animHide(float64 duration, anim::transition func) { - if (!history) return; - alphaDuration = duration; - aOpacityFunc = func; - aOpacity.start(0); - aY.restart(); - hiding = true; - anim::start(this); -} - -void PsNotifyWindow::stopHiding() { - if (!history) return; - alphaDuration = st::notifyFastAnim; - aOpacityFunc = st::notifyFastAnimFunc; - aOpacity.start(1); - aY.restart(); - hiding = false; - hideTimer.stop(); - anim::start(this); -} - -void PsNotifyWindow::hideByTimer() { - if (!history) return; - animHide(st::notifySlowHide, st::notifySlowHideFunc); -} - -bool PsNotifyWindow::animStep(float64 ms) { - float64 dtAlpha = ms / alphaDuration, dtPos = ms / posDuration; - if (dtAlpha >= 1) { - aOpacity.finish(); - if (hiding) { - deleteLater(); - } - } else { - aOpacity.update(dtAlpha, aOpacityFunc); - } - setWindowOpacity(aOpacity.current()); - if (dtPos >= 1) { - aY.finish(); - } else { - aY.update(dtPos, anim::linear); - } - move(x(), aY.current()); - update(); - return (dtAlpha < 1 || (!hiding && dtPos < 1)); -} - -PsNotifyWindow::~PsNotifyWindow() { - if (App::wnd()) App::wnd()->psShowNextNotify(this); +void PsMainWindow::psPlatformNotify(HistoryItem *item) { + _private.showNotify(item->history()->peer->id, item->history()->peer->name, item->notificationHeader(), item->notificationText()); } PsApplication::PsApplication(int &argc, char **argv) : QApplication(argc, argv) { diff --git a/Telegram/SourceFiles/pspecific_mac.h b/Telegram/SourceFiles/pspecific_mac.h index ff26e4909..3cfca22dc 100644 --- a/Telegram/SourceFiles/pspecific_mac.h +++ b/Telegram/SourceFiles/pspecific_mac.h @@ -29,60 +29,6 @@ inline void psCheckLocalSocket(const QString &serverName) { } } - -class PsNotifyWindow : public QWidget, public Animated { - Q_OBJECT - -public: - - PsNotifyWindow(HistoryItem *item, int32 x, int32 y); - - void enterEvent(QEvent *e); - void leaveEvent(QEvent *e); - void mousePressEvent(QMouseEvent *e); - void paintEvent(QPaintEvent *e); - - bool animStep(float64 ms); - void animHide(float64 duration, anim::transition func); - void startHiding(); - void stopHiding(); - void moveTo(int32 x, int32 y, int32 index = -1); - - void updatePeerPhoto(); - - int32 index() const { - return history ? _index : -1; - } - - ~PsNotifyWindow(); - - public slots: - - void hideByTimer(); - void checkLastInput(); - - void unlinkHistory(History *hist = 0); - -private: - -// DWORD started; - - History *history; - IconedButton close; - QPixmap pm; - float64 alphaDuration, posDuration; - QTimer hideTimer, inputTimer; - bool hiding; - int32 _index; - anim::fvalue aOpacity; - anim::transition aOpacityFunc; - anim::ivalue aY; - ImagePtr peerPhoto; - -}; - -typedef QList PsNotifyWindows; - class MacPrivate : public PsMacWindowPrivate { public: @@ -92,6 +38,8 @@ public: }; +class NotifyWindow; + class PsMainWindow : public QMainWindow { Q_OBJECT @@ -114,7 +62,6 @@ public: bool psHandleTitle(); void psFlash(); - void psNotifySettingGot(); bool psIsActive(int state = -1) const; bool psIsOnline(int state) const; @@ -126,19 +73,15 @@ public: return false; } - void psNotify(History *history, MsgId msgId); - void psClearNotify(History *history = 0); - void psClearNotifyFast(); - void psShowNextNotify(PsNotifyWindow *remove = 0); - void psActivateNotifies(); - void psStopHiding(); - void psStartHiding(); - void psUpdateNotifies(); - bool psPosInited() const { return posInited; } - + + void psActivateNotify(NotifyWindow *w); + void psClearNotifies(PeerId peerId = 0); + void psNotifyShown(NotifyWindow *w); + void psPlatformNotify(HistoryItem *item); + ~PsMainWindow(); public slots: @@ -147,7 +90,6 @@ public slots: void psUpdateCounter(); void psSavePosition(Qt::WindowState state = Qt::WindowActive); void psIdleTimeout(); - void psNotifyFire(); protected: @@ -159,26 +101,6 @@ protected: QImage icon256; virtual void setupTrayIcon() { } - - typedef QMap NotifyWhenMap; - typedef QMap NotifyWhenMaps; - NotifyWhenMaps notifyWhenMaps; - struct NotifyWaiter { - NotifyWaiter(MsgId msg, uint64 when) : msg(msg), when(when) { - } - MsgId msg; - uint64 when; - }; - typedef QMap NotifyWaiters; - NotifyWaiters notifyWaiters; - NotifyWaiters notifySettingWaiters; - QTimer notifyWaitTimer; - - typedef QSet NotifyWhenAlert; - typedef QMap NotifyWhenAlerts; - NotifyWhenAlerts notifyWhenAlerts; - - PsNotifyWindows notifyWindows; QTimer psUpdatedPositionTimer; @@ -257,6 +179,8 @@ QString psAppDataPath(); QString psCurrentExeDirectory(int argc, char *argv[]); void psAutoStart(bool start, bool silent = false); +QRect psDesktopRect(); + int psCleanup(); int psFixPrevious(); diff --git a/Telegram/SourceFiles/pspecific_mac.mm b/Telegram/SourceFiles/pspecific_mac.mm deleted file mode 100644 index e145ff29c..000000000 --- a/Telegram/SourceFiles/pspecific_mac.mm +++ /dev/null @@ -1,2466 +0,0 @@ -#include "stdafx.h" -#include "pspecific.h" - -#include "lang.h" -#include "application.h" -#include "mainwidget.h" - -#define min(a, b) ((a) < (b) ? (a) : (b)) -#define max(a, b) ((a) < (b) ? (b) : (a)) - -namespace { - bool frameless = true; - bool useDWM = false; - bool useTheme = false; - bool useOpenAs = false; - bool themeInited = false; - bool finished = true; - int menuShown = 0, menuHidden = 0; - int dleft = 0, dtop = 0; - QMargins simpleMargins, margins; - //HICON bigIcon = 0, smallIcon = 0, overlayIcon = 0; - - //UINT tbCreatedMsgId = 0; - //ITaskbarList3 *tbListInterface = 0; - - /*HWND createTaskbarHider() { - HINSTANCE appinst = (HINSTANCE)GetModuleHandle(0); - HWND hWnd = 0; - - QString cn = QString("TelegramTaskbarHider"); - LPCWSTR _cn = (LPCWSTR)cn.utf16(); - WNDCLASSEX wc; - - wc.cbSize = sizeof(wc); - wc.style = 0; - wc.lpfnWndProc = DefWindowProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = appinst; - wc.hIcon = 0; - wc.hCursor = 0; - wc.hbrBackground = 0; - wc.lpszMenuName = NULL; - wc.lpszClassName = _cn; - wc.hIconSm = 0; - if (!RegisterClassEx(&wc)) { - DEBUG_LOG(("Application Error: could not register taskbar hider window class, error: %1").arg(GetLastError())); - return hWnd; - } - - hWnd = CreateWindowEx(WS_EX_TOOLWINDOW, _cn, 0, WS_POPUP, 0, 0, 0, 0, 0, 0, appinst, 0); - if (!hWnd) { - DEBUG_LOG(("Application Error: could not create taskbar hider window class, error: %1").arg(GetLastError())); - return hWnd; - } - return hWnd; - } - - enum { - _PsShadowMoved = 0x01, - _PsShadowResized = 0x02, - _PsShadowShown = 0x04, - _PsShadowHidden = 0x08, - _PsShadowActivate = 0x10, - }; - - enum { - _PsInitHor = 0x01, - _PsInitVer = 0x02, - }; - - int32 _psSize = 0; - class _PsShadowWindows { - public: - - _PsShadowWindows() : screenDC(0), max_w(0), max_h(0), _x(0), _y(0), _w(0), _h(0), hidden(true), r(0), g(0), b(0), noKeyColor(RGB(255, 255, 255)) { - for (int i = 0; i < 4; ++i) { - dcs[i] = 0; - bitmaps[i] = 0; - hwnds[i] = 0; - } - } - - void setColor(QColor c) { - r = c.red(); - g = c.green(); - b = c.blue(); - - if (!hwnds[0]) return; - Gdiplus::SolidBrush brush(Gdiplus::Color(_alphas[0], r, g, b)); - for (int i = 0; i < 4; ++i) { - Gdiplus::Graphics graphics(dcs[i]); - graphics.SetCompositingMode(Gdiplus::CompositingModeSourceCopy); - if ((i % 2) && _h || !(i % 2) && _w) { - graphics.FillRectangle(&brush, 0, 0, (i % 2) ? _size : _w, (i % 2) ? _h : _size); - } - } - initCorners(); - - _x = _y = _w = _h = 0; - update(_PsShadowMoved | _PsShadowResized); - } - - bool init(QColor c) { - style::rect topLeft = st::wndShadow; - _fullsize = topLeft.width(); - _shift = st::wndShadowShift; - QImage cornersImage(_fullsize, _fullsize, QImage::Format_ARGB32_Premultiplied); - { - QPainter p(&cornersImage); - p.drawPixmap(QPoint(0, 0), App::sprite(), topLeft); - } - uchar *bits = cornersImage.bits(); - if (bits) { - for ( - quint32 *p = (quint32*)bits, *end = (quint32*)(bits + cornersImage.byteCount()); - p < end; - ++p - ) { - *p = (*p ^ 0x00ffffff) << 24; - } - } - - _metaSize = _fullsize + 2 * _shift; - _alphas.reserve(_metaSize); - _colors.reserve(_metaSize * _metaSize); - for (int32 j = 0; j < _metaSize; ++j) { - for (int32 i = 0; i < _metaSize; ++i) { - _colors.push_back((i < 2 * _shift || j < 2 * _shift) ? 1 : qMax(BYTE(1), BYTE(cornersImage.pixel(QPoint(i - 2 * _shift, j - 2 * _shift)) >> 24))); - } - } - uchar prev = 0; - for (int32 i = 0; i < _metaSize; ++i) { - uchar a = _colors[(_metaSize - 1) * _metaSize + i]; - if (a < prev) break; - - _alphas.push_back(a); - prev = a; - } - _psSize = _size = _alphas.size() - 2 * _shift; - - setColor(c); - - Gdiplus::GdiplusStartupInput gdiplusStartupInput; - ULONG_PTR gdiplusToken; - Gdiplus::Status gdiRes = Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); - - if (gdiRes != Gdiplus::Ok) { - DEBUG_LOG(("Application Error: could not init GDI+, error: %1").arg((int)gdiRes)); - return false; - } - blend.AlphaFormat = AC_SRC_ALPHA; - blend.SourceConstantAlpha = 255; - blend.BlendFlags = 0; - blend.BlendOp = AC_SRC_OVER; - - screenDC = GetDC(0); - if (!screenDC) return false; - - QRect avail(QDesktopWidget().availableGeometry()); - max_w = avail.width(); - if (max_w < st::wndMinWidth) max_w = st::wndMinWidth; - max_h = avail.height(); - if (max_h < st::wndMinHeight) max_h = st::wndMinHeight; - - HINSTANCE appinst = (HINSTANCE)GetModuleHandle(0); - - for (int i = 0; i < 4; ++i) { - QString cn = QString("TelegramShadow%1").arg(i); - LPCWSTR _cn = (LPCWSTR)cn.utf16(); - WNDCLASSEX wc; - - wc.cbSize = sizeof(wc); - wc.style = 0; - wc.lpfnWndProc = wndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = appinst; - wc.hIcon = 0; - wc.hCursor = 0; - wc.hbrBackground = 0; - wc.lpszMenuName = NULL; - wc.lpszClassName = _cn; - wc.hIconSm = 0; - if (!RegisterClassEx(&wc)) { - DEBUG_LOG(("Application Error: could not register shadow window class %1, error: %2").arg(i).arg(GetLastError())); - destroy(); - return false; - } - - hwnds[i] = CreateWindowEx(WS_EX_LAYERED | WS_EX_TOOLWINDOW, _cn, 0, WS_POPUP, 0, 0, 0, 0, 0, 0, appinst, 0); - if (!hwnds[i]) { - DEBUG_LOG(("Application Error: could not create shadow window class %1, error: %2").arg(i).arg(GetLastError())); - destroy(); - return false; - } - - dcs[i] = CreateCompatibleDC(screenDC); - if (!dcs[i]) { - DEBUG_LOG(("Application Error: could not create dc for shadow window class %1, error: %2").arg(i).arg(GetLastError())); - destroy(); - return false; - } - - bitmaps[i] = CreateCompatibleBitmap(screenDC, (i % 2) ? _size : max_w, (i % 2) ? max_h : _size); - if (!bitmaps[i]) { - DEBUG_LOG(("Application Error: could not create bitmap for shadow window class %1, error: %2").arg(i).arg(GetLastError())); - destroy(); - return false; - } - - SelectObject(dcs[i], bitmaps[i]); - } - - initCorners(); - return true; - } - - void initCorners(int directions = (_PsInitHor | _PsInitVer)) { - bool hor = (directions & _PsInitHor), ver = (directions & _PsInitVer); - Gdiplus::Graphics graphics0(dcs[0]), graphics1(dcs[1]), graphics2(dcs[2]), graphics3(dcs[3]); - graphics0.SetCompositingMode(Gdiplus::CompositingModeSourceCopy); - graphics1.SetCompositingMode(Gdiplus::CompositingModeSourceCopy); - graphics2.SetCompositingMode(Gdiplus::CompositingModeSourceCopy); - graphics3.SetCompositingMode(Gdiplus::CompositingModeSourceCopy); - - Gdiplus::SolidBrush brush(Gdiplus::Color(_alphas[0], r, g, b)); - if (hor) graphics0.FillRectangle(&brush, 0, 0, _fullsize - (_size - _shift), 2 * _shift); - - if (ver) { - graphics1.FillRectangle(&brush, 0, 0, _size, 2 * _shift); - graphics3.FillRectangle(&brush, 0, 0, _size, 2 * _shift); - graphics1.FillRectangle(&brush, _size - _shift, 2 * _shift, _shift, _fullsize); - graphics3.FillRectangle(&brush, 0, 2 * _shift, _shift, _fullsize); - } - - if (hor) { - for (int j = 2 * _shift; j < _size; ++j) { - for (int k = 0; k < _fullsize - (_size - _shift); ++k) { - brush.SetColor(Gdiplus::Color(_colors[j * _metaSize + k + (_size + _shift)], r, g, b)); - graphics0.FillRectangle(&brush, k, j, 1, 1); - graphics2.FillRectangle(&brush, k, _size - (j - 2 * _shift) - 1, 1, 1); - } - } - for (int j = _size; j < _size + 2 * _shift; ++j) { - for (int k = 0; k < _fullsize - (_size - _shift); ++k) { - brush.SetColor(Gdiplus::Color(_colors[j * _metaSize + k + (_size + _shift)], r, g, b)); - graphics2.FillRectangle(&brush, k, _size - (j - 2 * _shift) - 1, 1, 1); - } - } - } - if (ver) { - for (int j = 2 * _shift; j < _fullsize + 2 * _shift; ++j) { - for (int k = _shift; k < _size; ++k) { - brush.SetColor(Gdiplus::Color(_colors[j * _metaSize + (k + _shift)], r, g, b)); - graphics1.FillRectangle(&brush, _size - k - 1, j, 1, 1); - graphics3.FillRectangle(&brush, k, j, 1, 1); - } - } - } - } - void verCorners(int h, Gdiplus::Graphics *pgraphics1, Gdiplus::Graphics *pgraphics3) { - Gdiplus::SolidBrush brush(Gdiplus::Color(_alphas[0], r, g, b)); - pgraphics1->FillRectangle(&brush, _size - _shift, h - _fullsize, _shift, _fullsize); - pgraphics3->FillRectangle(&brush, 0, h - _fullsize, _shift, _fullsize); - for (int j = 0; j < _fullsize; ++j) { - for (int k = _shift; k < _size; ++k) { - brush.SetColor(Gdiplus::Color(_colors[(j + 2 * _shift) * _metaSize + k + _shift], r, g, b)); - pgraphics1->FillRectangle(&brush, _size - k - 1, h - j - 1, 1, 1); - pgraphics3->FillRectangle(&brush, k, h - j - 1, 1, 1); - } - } - } - void horCorners(int w, Gdiplus::Graphics *pgraphics0, Gdiplus::Graphics *pgraphics2) { - Gdiplus::SolidBrush brush(Gdiplus::Color(_alphas[0], r, g, b)); - pgraphics0->FillRectangle(&brush, w - 2 * _size - (_fullsize - (_size - _shift)), 0, _fullsize - (_size - _shift), 2 * _shift); - for (int j = 2 * _shift; j < _size; ++j) { - for (int k = 0; k < _fullsize - (_size - _shift); ++k) { - brush.SetColor(Gdiplus::Color(_colors[j * _metaSize + k + (_size + _shift)], r, g, b)); - pgraphics0->FillRectangle(&brush, w - 2 * _size - k - 1, j, 1, 1); - pgraphics2->FillRectangle(&brush, w - 2 * _size - k - 1, _size - (j - 2 * _shift) - 1, 1, 1); - } - } - for (int j = _size; j < _size + 2 * _shift; ++j) { - for (int k = 0; k < _fullsize - (_size - _shift); ++k) { - brush.SetColor(Gdiplus::Color(_colors[j * _metaSize + k + (_size + _shift)], r, g, b)); - pgraphics2->FillRectangle(&brush, w - 2 * _size - k - 1, _size - (j - 2 * _shift) - 1, 1, 1); - } - } - } - - void update(int changes, WINDOWPOS *pos = 0) { - HWND hwnd = Application::wnd() ? Application::wnd()->psHwnd() : 0; - if (!hwnd || !hwnds[0]) return; - - if (changes == _PsShadowActivate) { - for (int i = 0; i < 4; ++i) { - SetWindowPos(hwnds[i], hwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - } - return; - } - - if (changes & _PsShadowHidden) { - if (!hidden) { - for (int i = 0; i < 4; ++i) { - hidden = true; - ShowWindow(hwnds[i], SW_HIDE); - } - } - return; - } - if (!Application::wnd()->psPosInited()) return; - - int x = _x, y = _y, w = _w, h = _h; - if (pos && (!(pos->flags & SWP_NOMOVE) || !(pos->flags & SWP_NOSIZE) || !(pos->flags & SWP_NOREPOSITION))) { - if (!(pos->flags & SWP_NOMOVE)) { - x = pos->x - _size; - y = pos->y - _size; - } else if (pos->flags & SWP_NOSIZE) { - for (int i = 0; i < 4; ++i) { - SetWindowPos(hwnds[i], hwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - } - return; - } - if (!(pos->flags & SWP_NOSIZE)) { - w = pos->cx + 2 * _size; - h = pos->cy + 2 * _size; - } - } else { - RECT r; - GetWindowRect(hwnd, &r); - x = r.left - _size; - y = r.top - _size; - w = r.right + _size - x; - h = r.bottom + _size - y; - } - if (h < 2 * _fullsize + 2 * _shift) { - h = 2 * _fullsize + 2 * _shift; - } - if (w < 2 * (_fullsize + _shift)) { - w = 2 * (_fullsize + _shift); - } - - if (w != _w) { - int from = (_w > 2 * (_fullsize + _shift)) ? (_w - _size - _fullsize - _shift) : (_fullsize - (_size - _shift)); - int to = w - _size - _fullsize - _shift; - if (w > max_w) { - from = _fullsize - (_size - _shift); - max_w *= 2; - for (int i = 0; i < 4; i += 2) { - DeleteObject(bitmaps[i]); - bitmaps[i] = CreateCompatibleBitmap(screenDC, max_w, _size); - SelectObject(dcs[i], bitmaps[i]); - } - initCorners(_PsInitHor); - } - Gdiplus::Graphics graphics0(dcs[0]), graphics2(dcs[2]); - graphics0.SetCompositingMode(Gdiplus::CompositingModeSourceCopy); - graphics2.SetCompositingMode(Gdiplus::CompositingModeSourceCopy); - Gdiplus::SolidBrush brush(Gdiplus::Color(_alphas[0], r, g, b)); - if (to > from) { - graphics0.FillRectangle(&brush, from, 0, to - from, 2 * _shift); - for (int i = 2 * _shift; i < _size; ++i) { - Gdiplus::Pen pen(Gdiplus::Color(_alphas[i], r, g, b)); - graphics0.DrawLine(&pen, from, i, to, i); - graphics2.DrawLine(&pen, from, _size - (i - 2 * _shift) - 1, to, _size - (i - 2 * _shift) - 1); - } - for (int i = _size; i < _size + 2 * _shift; ++i) { - Gdiplus::Pen pen(Gdiplus::Color(_alphas[i], r, g, b)); - graphics2.DrawLine(&pen, from, _size - (i - 2 * _shift) - 1, to, _size - (i - 2 * _shift) - 1); - } - } - if (_w > w) { - graphics0.FillRectangle(&brush, w - _size - _fullsize - _shift, 0, _fullsize - (_size - _shift), _size); - graphics2.FillRectangle(&brush, w - _size - _fullsize - _shift, 0, _fullsize - (_size - _shift), _size); - } - horCorners(w, &graphics0, &graphics2); - POINT p0 = { x + _size, y }, p2 = { x + _size, y + h - _size }, f = { 0, 0 }; - SIZE s = { w - 2 * _size, _size }; - updateWindow(0, &p0, &s); - updateWindow(2, &p2, &s); - } else if (x != _x || y != _y) { - POINT p0 = { x + _size, y }, p2 = { x + _size, y + h - _size }; - updateWindow(0, &p0); - updateWindow(2, &p2); - } else if (h != _h) { - POINT p2 = { x + _size, y + h - _size }; - updateWindow(2, &p2); - } - - if (h != _h) { - int from = (_h > 2 * _fullsize + 2 * _shift) ? (_h - _fullsize) : (_fullsize + 2 * _shift); - int to = h - _fullsize; - if (h > max_h) { - from = (_fullsize + 2 * _shift); - max_h *= 2; - for (int i = 1; i < 4; i += 2) { - DeleteObject(bitmaps[i]); - bitmaps[i] = CreateCompatibleBitmap(dcs[i], _size, max_h); - SelectObject(dcs[i], bitmaps[i]); - } - initCorners(_PsInitVer); - } - Gdiplus::Graphics graphics1(dcs[1]), graphics3(dcs[3]); - graphics1.SetCompositingMode(Gdiplus::CompositingModeSourceCopy); - graphics3.SetCompositingMode(Gdiplus::CompositingModeSourceCopy); - - Gdiplus::SolidBrush brush(Gdiplus::Color(_alphas[0], r, g, b)); - if (to > from) { - graphics1.FillRectangle(&brush, _size - _shift, from, _shift, to - from); - graphics3.FillRectangle(&brush, 0, from, _shift, to - from); - for (int i = 2 * _shift; i < _size + _shift; ++i) { - Gdiplus::Pen pen(Gdiplus::Color(_alphas[i], r, g, b)); - graphics1.DrawLine(&pen, _size + _shift - i - 1, from, _size + _shift - i - 1, to); - graphics3.DrawLine(&pen, i - _shift, from, i - _shift, to); - } - } - if (_h > h) { - graphics1.FillRectangle(&brush, 0, h - _fullsize, _size, _fullsize); - graphics3.FillRectangle(&brush, 0, h - _fullsize, _size, _fullsize); - } - verCorners(h, &graphics1, &graphics3); - - POINT p1 = {x + w - _size, y}, p3 = {x, y}, f = {0, 0}; - SIZE s = { _size, h }; - updateWindow(1, &p1, &s); - updateWindow(3, &p3, &s); - } else if (x != _x || y != _y) { - POINT p1 = { x + w - _size, y }, p3 = { x, y }; - updateWindow(1, &p1); - updateWindow(3, &p3); - } else if (w != _w) { - POINT p1 = { x + w - _size, y }; - updateWindow(1, &p1); - } - _x = x; - _y = y; - _w = w; - _h = h; - - if (hidden && (changes & _PsShadowShown)) { - for (int i = 0; i < 4; ++i) { - SetWindowPos(hwnds[i], hwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE); - } - hidden = false; - } - } - - void updateWindow(int i, POINT *p, SIZE *s = 0) { - static POINT f = {0, 0}; - if (s) { - UpdateLayeredWindow(hwnds[i], (s ? screenDC : 0), p, s, (s ? dcs[i] : 0), (s ? (&f) : 0), noKeyColor, &blend, ULW_ALPHA); - } else { - SetWindowPos(hwnds[i], 0, p->x, p->y, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER); - } - } - - void destroy() { - for (int i = 0; i < 4; ++i) { - if (dcs[i]) DeleteDC(dcs[i]); - if (bitmaps[i]) DeleteObject(bitmaps[i]); - if (hwnds[i]) DestroyWindow(hwnds[i]); - dcs[i] = 0; - bitmaps[i] = 0; - hwnds[i] = 0; - } - if (screenDC) ReleaseDC(0, screenDC); - } - - private: - - int _x, _y, _w, _h; - int _metaSize, _fullsize, _size, _shift; - QVector _alphas, _colors; - - bool hidden; - - HWND hwnds[4]; - HDC dcs[4], screenDC; - HBITMAP bitmaps[4]; - int max_w, max_h; - BLENDFUNCTION blend; - - BYTE r, g, b; - COLORREF noKeyColor; - - static LRESULT CALLBACK _PsShadowWindows::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - - }; - _PsShadowWindows _psShadowWindows; - - LRESULT CALLBACK _PsShadowWindows::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (finished) return DefWindowProc(hwnd, msg, wParam, lParam); - - int i; - for (i = 0; i < 4; ++i) { - if (_psShadowWindows.hwnds[i] && hwnd == _psShadowWindows.hwnds[i]) { - break; - } - } - if (i == 4) return DefWindowProc(hwnd, msg, wParam, lParam); - - switch (msg) { - case WM_CLOSE: - Application::wnd()->close(); - break; - case WM_NCHITTEST: { - int32 xPos = GET_X_LPARAM(lParam), yPos = GET_Y_LPARAM(lParam); - switch (i) { - case 0: return HTTOP; - case 1: return (yPos < _psShadowWindows._y + _psSize) ? HTTOPRIGHT : ((yPos >= _psShadowWindows._y + _psShadowWindows._h - _psSize) ? HTBOTTOMRIGHT : HTRIGHT); - case 2: return HTBOTTOM; - case 3: return (yPos < _psShadowWindows._y + _psSize) ? HTTOPLEFT : ((yPos >= _psShadowWindows._y + _psShadowWindows._h - _psSize) ? HTBOTTOMLEFT : HTLEFT); - } - return HTTRANSPARENT; - } break; - - case WM_NCACTIVATE: return DefWindowProc(hwnd, msg, wParam, lParam); - case WM_NCLBUTTONDOWN: - case WM_NCLBUTTONUP: - case WM_NCLBUTTONDBLCLK: - case WM_NCMBUTTONDOWN: - case WM_NCMBUTTONUP: - case WM_NCMBUTTONDBLCLK: - case WM_NCRBUTTONDOWN: - case WM_NCRBUTTONUP: - case WM_NCRBUTTONDBLCLK: - case WM_NCXBUTTONDOWN: - case WM_NCXBUTTONUP: - case WM_NCXBUTTONDBLCLK: - case WM_NCMOUSEHOVER: - case WM_NCMOUSELEAVE: - case WM_NCMOUSEMOVE: - case WM_NCPOINTERUPDATE: - case WM_NCPOINTERDOWN: - case WM_NCPOINTERUP: - if (App::wnd() && App::wnd()->psHwnd()) { - if (msg == WM_NCLBUTTONDOWN) { - ::SetForegroundWindow(App::wnd()->psHwnd()); - } - LRESULT res = SendMessage(App::wnd()->psHwnd(), msg, wParam, lParam); - return res; - } - return 0; - break; - case WM_ACTIVATE: - if (App::wnd() && App::wnd()->psHwnd() && wParam == WA_ACTIVE) { - if ((HWND)lParam != App::wnd()->psHwnd()) { - ::SetForegroundWindow(hwnd); - ::SetWindowPos(App::wnd()->psHwnd(), hwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - } - } - return DefWindowProc(hwnd, msg, wParam, lParam); - break; - default: - return DefWindowProc(hwnd, msg, wParam, lParam); - } - return 0; - } - - QColor _shActive(0, 0, 0), _shInactive(0, 0, 0); - - typedef BOOL (FAR STDAPICALLTYPE *f_dwmDefWindowProc)(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, _Out_ LRESULT *plResult); - f_dwmDefWindowProc dwmDefWindowProc; - - typedef HRESULT (FAR STDAPICALLTYPE *f_dwmSetWindowAttribute)(HWND hWnd, DWORD dwAttribute, _In_ LPCVOID pvAttribute, DWORD cbAttribute); - f_dwmSetWindowAttribute dwmSetWindowAttribute; - - typedef HRESULT (FAR STDAPICALLTYPE *f_dwmExtendFrameIntoClientArea)(HWND hWnd, const MARGINS *pMarInset); - f_dwmExtendFrameIntoClientArea dwmExtendFrameIntoClientArea; - - typedef HRESULT (FAR STDAPICALLTYPE *f_setWindowTheme)(HWND hWnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList); - f_setWindowTheme setWindowTheme; - - typedef HRESULT (FAR STDAPICALLTYPE *f_openAs_RunDLL)(HWND hWnd, HINSTANCE hInstance, LPCWSTR lpszCmdLine, int nCmdShow); - f_openAs_RunDLL openAs_RunDLL; - - typedef HRESULT (FAR STDAPICALLTYPE *f_shOpenWithDialog)(HWND hwndParent, const OPENASINFO *poainfo); - f_shOpenWithDialog shOpenWithDialog; - - template - bool loadFunction(HINSTANCE dll, LPCSTR name, TFunction &func) { - if (!dll) return false; - - func = (TFunction)GetProcAddress(dll, name); - return !!func; - } - - class _PsInitializer { - public: - _PsInitializer() { - setupDWM(); - useDWM = true; - frameless = !useDWM; - - setupUx(); - setupOpenAs(); - } - void setupDWM() { - HINSTANCE procId = LoadLibrary(L"DWMAPI.DLL"); - - if (!loadFunction(procId, "DwmDefWindowProc", dwmDefWindowProc)) return; - if (!loadFunction(procId, "DwmSetWindowAttribute", dwmSetWindowAttribute)) return; - if (!loadFunction(procId, "DwmExtendFrameIntoClientArea", dwmExtendFrameIntoClientArea)) return; - useDWM = true; - } - void setupUx() { - HINSTANCE procId = LoadLibrary(L"UXTHEME.DLL"); - - if (!loadFunction(procId, "SetWindowTheme", setWindowTheme)) return; - useTheme = true; - } - void setupOpenAs() { - HINSTANCE procId = LoadLibrary(L"SHELL32.DLL"); - - if (!loadFunction(procId, "SHOpenWithDialog", shOpenWithDialog) && !loadFunction(procId, "OpenAs_RunDLLW", openAs_RunDLL)) return; - useOpenAs = true; - } - }; - _PsInitializer _psInitializer; - - class _PsEventFilter : public QAbstractNativeEventFilter { - public: - _PsEventFilter() { - } - - bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) { - Window *wnd = Application::wnd(); - if (!wnd) return false; - - MSG *msg = (MSG*)message; - if (msg->message == WM_ENDSESSION) { - App::quit(); - return false; - } - if (msg->hwnd == wnd->psHwnd() || msg->hwnd && !wnd->psHwnd()) { - return mainWindowEvent(msg->hwnd, msg->message, msg->wParam, msg->lParam, (LRESULT*)result); - } - return false; - } - - bool mainWindowEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *result) { - if (tbCreatedMsgId && msg == tbCreatedMsgId) { - if (CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_ALL, IID_ITaskbarList3, (void**)&tbListInterface) != S_OK) { - tbListInterface = 0; - } - } - switch (msg) { - - case WM_DESTROY: { - App::quit(); - } return false; - - case WM_ACTIVATE: { - if (LOWORD(wParam) == WA_CLICKACTIVE) { - App::wnd()->inactivePress(true); - } - Application::wnd()->psUpdateMargins(); - if (LOWORD(wParam) != WA_INACTIVE) { - _psShadowWindows.setColor(_shActive); - _psShadowWindows.update(_PsShadowActivate); - } else { - _psShadowWindows.setColor(_shInactive); - } - QTimer::singleShot(0, Application::wnd(), SLOT(psUpdateCounter())); - Application::wnd()->update(); - } return false; - - case WM_NCPAINT: if (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8) return false; *result = 0; return true; - - case WM_NCCALCSIZE: if (!useDWM) return false; { - if (wParam == TRUE) { - LPNCCALCSIZE_PARAMS params = (LPNCCALCSIZE_PARAMS)lParam; - params->rgrc[0].left += margins.left() - simpleMargins.left(); - params->rgrc[0].top += margins.top() - simpleMargins.top(); - params->rgrc[0].right -= margins.right() - simpleMargins.right(); - params->rgrc[0].bottom -= margins.bottom() - simpleMargins.bottom(); - } else if (wParam == FALSE) { - LPRECT rect = (LPRECT)lParam; - - rect->left += margins.left() - simpleMargins.left(); - rect->top += margins.top() - simpleMargins.top(); - rect->right += margins.right() - simpleMargins.right(); - rect->bottom += margins.bottom() - simpleMargins.bottom(); - } - *result = 0; - } return true; - - case WM_NCACTIVATE: { - Application::wnd()->psUpdateMargins(); - *result = LRESULT(TRUE); - Application::wnd()->repaint(); - } return true; - - case WM_WINDOWPOSCHANGING: - case WM_WINDOWPOSCHANGED: { - _psShadowWindows.update(_PsShadowMoved | _PsShadowResized, (WINDOWPOS*)lParam); - } return false; - - case WM_SIZE: { - if (App::wnd()) { - if (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED || wParam == SIZE_MINIMIZED) { - if (wParam != SIZE_RESTORED || App::wnd()->windowState() != Qt::WindowNoState) { - Qt::WindowState state = Qt::WindowNoState; - if (wParam == SIZE_MAXIMIZED) { - state = Qt::WindowMaximized; - } else if (wParam == SIZE_MINIMIZED) { - state = Qt::WindowMinimized; - } - emit App::wnd()->windowHandle()->windowStateChanged(state); - } else { - App::wnd()->psUpdatedPosition(); - } - int changes = (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXIMIZED) ? _PsShadowHidden : (_PsShadowResized | _PsShadowShown); - _psShadowWindows.update(changes); - } - } - } return false; - - case WM_SHOWWINDOW: { - LONG style = GetWindowLong(hWnd, GWL_STYLE); - int changes = _PsShadowResized | ((wParam && !(style & (WS_MAXIMIZE | WS_MINIMIZE))) ? _PsShadowShown : _PsShadowHidden); - _psShadowWindows.update(changes); - } return false; - - case WM_MOVE: { - _psShadowWindows.update(_PsShadowMoved); - App::wnd()->psUpdatedPosition(); - } return false; - - case WM_NCHITTEST: { - POINTS p = MAKEPOINTS(lParam); - RECT r; - GetWindowRect(hWnd, &r); - HitTestType res = Application::wnd()->hitTest(QPoint(p.x - r.left + dleft, p.y - r.top + dtop)); - switch (res) { - case HitTestClient: - case HitTestSysButton: *result = HTCLIENT; break; - case HitTestIcon: *result = HTCAPTION; break; - case HitTestCaption: *result = HTCAPTION; break; - case HitTestTop: *result = HTTOP; break; - case HitTestTopRight: *result = HTTOPRIGHT; break; - case HitTestRight: *result = HTRIGHT; break; - case HitTestBottomRight: *result = HTBOTTOMRIGHT; break; - case HitTestBottom: *result = HTBOTTOM; break; - case HitTestBottomLeft: *result = HTBOTTOMLEFT; break; - case HitTestLeft: *result = HTLEFT; break; - case HitTestTopLeft: *result = HTTOPLEFT; break; - case HitTestNone: - default: *result = HTTRANSPARENT; break; - }; - } return true; - - case WM_NCRBUTTONUP: { - SendMessage(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam); - } return true; - - case WM_NCLBUTTONDOWN: { - POINTS p = MAKEPOINTS(lParam); - RECT r; - GetWindowRect(hWnd, &r); - HitTestType res = Application::wnd()->hitTest(QPoint(p.x - r.left + dleft, p.y - r.top + dtop)); - switch (res) { - case HitTestIcon: - if (menuHidden && getms() < menuHidden + 10) { - menuHidden = 0; - if (getms() < menuShown + GetDoubleClickTime()) { - Application::wnd()->close(); - } - } else { - QRect icon = Application::wnd()->iconRect(); - p.x = r.left - dleft + icon.left(); - p.y = r.top - dtop + icon.top() + icon.height(); - Application::wnd()->psUpdateSysMenu(Application::wnd()->windowHandle()->windowState()); - menuShown = getms(); - menuHidden = 0; - TrackPopupMenu(Application::wnd()->psMenu(), TPM_LEFTALIGN | TPM_TOPALIGN | TPM_LEFTBUTTON, p.x, p.y, 0, hWnd, 0); - menuHidden = getms(); - } - return true; - }; - } return false; - - case WM_NCLBUTTONDBLCLK: { - POINTS p = MAKEPOINTS(lParam); - RECT r; - GetWindowRect(hWnd, &r); - HitTestType res = Application::wnd()->hitTest(QPoint(p.x - r.left + dleft, p.y - r.top + dtop)); - switch (res) { - case HitTestIcon: Application::wnd()->close(); return true; - }; - } return false; - - case WM_SYSCOMMAND: { - if (wParam == SC_MOUSEMENU) { - POINTS p = MAKEPOINTS(lParam); - Application::wnd()->psUpdateSysMenu(Application::wnd()->windowHandle()->windowState()); - TrackPopupMenu(Application::wnd()->psMenu(), TPM_LEFTALIGN | TPM_TOPALIGN | TPM_LEFTBUTTON, p.x, p.y, 0, hWnd, 0); - } - } return false; - - case WM_COMMAND: { - if (HIWORD(wParam)) return false; - int cmd = LOWORD(wParam); - switch (cmd) { - case SC_CLOSE: Application::wnd()->close(); return true; - case SC_MINIMIZE: Application::wnd()->setWindowState(Qt::WindowMinimized); return true; - case SC_MAXIMIZE: Application::wnd()->setWindowState(Qt::WindowMaximized); return true; - case SC_RESTORE: Application::wnd()->setWindowState(Qt::WindowNoState); return true; - } - } return true; - - } - return false; - } - }; - _PsEventFilter *_psEventFilter = 0;*/ - -}; - -PsMainWindow::PsMainWindow(QWidget *parent) : QMainWindow(parent), -posInited(false), trayIcon(0), trayIconMenu(0), icon256(qsl(":/gui/art/iconround256.png")) { - - //tbCreatedMsgId = RegisterWindowMessage(L"TaskbarButtonCreated"); - icon16 = icon256.scaledToWidth(16, Qt::SmoothTransformation); - icon32 = icon256.scaledToWidth(32, Qt::SmoothTransformation); - //connect(&psIdleTimer, SIGNAL(timeout()), this, SLOT(psIdleTimeout())); - //psIdleTimer.setSingleShot(false); -} - -void PsMainWindow::psIdleTimeout() { - /*LASTINPUTINFO lii; - lii.cbSize = sizeof(LASTINPUTINFO); - BOOL res = GetLastInputInfo(&lii); - if (res) { - uint64 ticks = GetTickCount(); - if (lii.dwTime >= ticks - IdleMsecs) { - psIdle = false; - psIdleTimer.stop(); - if (App::main()) App::main()->setOnline(); - } - }*/ -} - -bool PsMainWindow::psIsActive() const { - return isActiveWindow() && isVisible() && !(windowState() & Qt::WindowMinimized); -} - -bool PsMainWindow::psIsOnline(int windowState) const { - if (windowState < 0) windowState = this->windowState(); - if (windowState & Qt::WindowMinimized) { - return false; - } else if (!isVisible()) { - return false; - } - /*LASTINPUTINFO lii; - lii.cbSize = sizeof(LASTINPUTINFO); - BOOL res = GetLastInputInfo(&lii); - if (res) { - uint64 ticks = GetTickCount(); - if (lii.dwTime < ticks - IdleMsecs) { - if (!psIdle) { - psIdle = true; - psIdleTimer.start(900); - } - return false; - } else { - psIdle = false; - psIdleTimer.stop(); - } - }*/ - return true; -} - -void PsMainWindow::psRefreshTaskbarIcon() { - /*QWidget *w = new QWidget(this); - w->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint); - w->setGeometry(x() + 1, y() + 1, 1, 1); - QPalette p(w->palette()); - p.setColor(QPalette::Background, st::titleBG->c); - QWindow *wnd = w->windowHandle(); - w->setPalette(p); - w->show(); - w->activateWindow(); - delete w;*/ -} - -void PsMainWindow::psUpdateWorkmode() { - /*switch (cWorkMode()) { - case dbiwmWindowAndTray: { - setupTrayIcon(); - HWND psOwner = (HWND)GetWindowLong(ps_hWnd, GWL_HWNDPARENT); - if (psOwner) { - SetWindowLong(ps_hWnd, GWL_HWNDPARENT, 0); - psRefreshTaskbarIcon(); - } - } break; - - case dbiwmTrayOnly: { - setupTrayIcon(); - HWND psOwner = (HWND)GetWindowLong(ps_hWnd, GWL_HWNDPARENT); - if (!psOwner) { - SetWindowLong(ps_hWnd, GWL_HWNDPARENT, (LONG)ps_tbHider_hWnd); - } - } break; - - case dbiwmWindowOnly: { - if (trayIconMenu) trayIconMenu->deleteLater(); - trayIconMenu = 0; - if (trayIcon) trayIcon->deleteLater(); - trayIcon = 0; - - HWND psOwner = (HWND)GetWindowLong(ps_hWnd, GWL_HWNDPARENT); - if (psOwner) { - SetWindowLong(ps_hWnd, GWL_HWNDPARENT, 0); - psRefreshTaskbarIcon(); - } - } break; - }*/ -} - -/*HICON qt_pixmapToWinHICON(const QPixmap &); -static HICON _qt_createHIcon(const QIcon &icon, int xSize, int ySize) { - if (!icon.isNull()) { - const QPixmap pm = icon.pixmap(icon.actualSize(QSize(xSize, ySize))); - if (!pm.isNull()) - return qt_pixmapToWinHICON(pm); - } - return 0; -}*/ - -void PsMainWindow::psUpdateCounter() { - int32 counter = App::histories().unreadFull; - style::color bg = (App::histories().unreadMuted < counter) ? st::counterBG : st::counterMuteBG; - QIcon icon; - QImage cicon16(icon16), cicon32(icon32); - if (counter > 0) { - { - QString cnt = (counter < 1000) ? QString("%1").arg(counter) : QString("..%1").arg(counter % 100, 2, 10, QChar('0')); - QPainter p16(&cicon16); - p16.setBrush(bg->b); - p16.setPen(Qt::NoPen); - p16.setRenderHint(QPainter::Antialiasing); - int32 fontSize = 8; - style::font f(fontSize); - int32 w = f->m.width(cnt), d = 2, r = 3; - p16.drawRoundedRect(QRect(16 - w - d * 2, 16 - f->height, w + d * 2, f->height), r, r); - p16.setFont(f->f); - - p16.setPen(st::counterColor->p); - - p16.drawText(16 - w - d, 16 - f->height + f->ascent, cnt); - } - /*if (!tbListInterface) { - QString cnt = (counter < 10000) ? QString("%1").arg(counter) : ((counter < 1000000) ? QString("%1K").arg(counter / 1000) : QString("%1M").arg(counter / 1000000)); - QPainter p32(&cicon32); - style::font f(10); - int32 w = f->m.width(cnt), d = 3, r = 6; - p32.setBrush(bg->b); - p32.setPen(Qt::NoPen); - p32.setRenderHint(QPainter::Antialiasing); - p32.drawRoundedRect(QRect(32 - w - d * 2, 0, w + d * 2, f->height - 1), r, r); - p32.setPen(st::counterColor->p); - p32.setFont(f->f); - p32.drawText(32 - w - d, f->ascent - 1, cnt); - }*/ - } - icon.addPixmap(QPixmap::fromImage(cicon16)); - icon.addPixmap(QPixmap::fromImage(cicon32)); - if (trayIcon) { - QIcon ticon; - QImage ticon16(icon16); - if (counter > 0) { - QString cnt = (counter < 1000) ? QString("%1").arg(counter) : QString("..%1").arg(counter % 100, 2, 10, QChar('0')); - { - QPainter p16(&ticon16); - p16.setBrush(bg->b); - p16.setPen(Qt::NoPen); - p16.setRenderHint(QPainter::Antialiasing); - int32 fontSize = 8; - style::font f(fontSize); - int32 w = f->m.width(cnt), d = 2, r = 3; - p16.drawRoundedRect(QRect(16 - w - d * 2, 16 - f->height, w + d * 2, f->height), r, r); - p16.setFont(f->f); - - p16.setPen(st::counterColor->p); - - p16.drawText(16 - w - d, 16 - f->height + f->ascent, cnt); - } - } - ticon.addPixmap(QPixmap::fromImage(ticon16)); - ticon.addPixmap(QPixmap::fromImage(cicon32)); - trayIcon->setIcon(ticon); - } - - /*setWindowTitle((counter > 0) ? qsl("Telegram (%1)").arg(counter) : qsl("Telegram")); - psDestroyIcons(); - ps_iconSmall = _qt_createHIcon(icon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); - ps_iconBig = _qt_createHIcon(icon, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)); - SendMessage(ps_hWnd, WM_SETICON, 0, (LPARAM)ps_iconSmall); - SendMessage(ps_hWnd, WM_SETICON, 1, (LPARAM)(ps_iconBig ? ps_iconBig : ps_iconSmall)); - if (tbListInterface) { - if (counter > 0) { - QString cnt = (counter < 1000) ? QString("%1").arg(counter) : QString("..%1").arg(counter % 100, 2, 10, QChar('0')); - QImage oicon16(16, 16, QImage::Format_ARGB32); - int32 cntSize = cnt.size(); - oicon16.fill(st::transparent->c); - { - QPainter p16(&oicon16); - p16.setBrush(bg->b); - p16.setPen(Qt::NoPen); - p16.setRenderHint(QPainter::Antialiasing); - int32 fontSize = (cntSize < 2) ? 12 : ((cntSize < 3) ? 12 : 8); - style::font f(fontSize); - int32 w = f->m.width(cnt), d = (cntSize < 2) ? 5 : ((cntSize < 3) ? 2 : 2), r = (cntSize < 2) ? 8 : ((cntSize < 3) ? 7 : 3); - p16.drawRoundedRect(QRect(16 - w - d * 2, 16 - f->height, w + d * 2, f->height), r, r); - p16.setFont(f->f); - - p16.setPen(st::counterColor->p); - - p16.drawText(16 - w - d, 16 - f->height + f->ascent, cnt); - } - QIcon oicon(QPixmap::fromImage(oicon16)); - ps_iconOverlay = _qt_createHIcon(oicon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); - } - QString description = counter > 0 ? QString("%1 unread messages").arg(counter) : qsl("No unread messages"); - static WCHAR descriptionArr[1024]; - description.toWCharArray(descriptionArr); - tbListInterface->SetOverlayIcon(ps_hWnd, ps_iconOverlay, descriptionArr); - }*/ -} - -/*namespace { - HMONITOR enumMonitor = 0; - RECT enumMonitorWork; - - BOOL CALLBACK _monitorEnumProc( - _In_ HMONITOR hMonitor, - _In_ HDC hdcMonitor, - _In_ LPRECT lprcMonitor, - _In_ LPARAM dwData - ) { - MONITORINFOEX info; - info.cbSize = sizeof(info); - GetMonitorInfo(hMonitor, &info); - if (dwData == hashCrc32(info.szDevice, sizeof(info.szDevice))) { - enumMonitor = hMonitor; - enumMonitorWork = info.rcWork; - return FALSE; - } - return TRUE; - } -}*/ - -void PsMainWindow::psInitSize() { - setMinimumWidth(st::wndMinWidth); - setMinimumHeight(st::wndMinHeight); - - TWindowPos pos(cWindowPos()); - if (cDebug()) { // temp while design - pos.w = 800; - pos.h = 600; - } - QRect avail(QDesktopWidget().availableGeometry()); - bool maximized = false; - QRect geom(avail.x() + (avail.width() - st::wndDefWidth) / 2, avail.y() + (avail.height() - st::wndDefHeight) / 2, st::wndDefWidth, st::wndDefHeight); - if (pos.w && pos.h) { - if (pos.y < 0) pos.y = 0; - //enumMonitor = 0; - //EnumDisplayMonitors(0, 0, &_monitorEnumProc, pos.moncrc); - /*if (enumMonitor) { - int32 w = enumMonitorWork.right - enumMonitorWork.left, h = enumMonitorWork.bottom - enumMonitorWork.top; - if (w >= st::wndMinWidth && h >= st::wndMinHeight) { - if (pos.w > w) pos.w = w; - if (pos.h > h) pos.h = h; - pos.x += enumMonitorWork.left; - pos.y += enumMonitorWork.top; - if (pos.x < enumMonitorWork.right - 10 && pos.y < enumMonitorWork.bottom - 10) { - geom = QRect(pos.x, pos.y, pos.w, pos.h); - } - } - }*/ - maximized = pos.maximized; - } - setGeometry(geom); -} - -void PsMainWindow::psInitFrameless() { - psUpdatedPositionTimer.setSingleShot(true); - connect(&psUpdatedPositionTimer, SIGNAL(timeout()), this, SLOT(psSavePosition())); - - if (frameless) { -// setWindowFlags(Qt::FramelessWindowHint); - } - - connect(windowHandle(), SIGNAL(windowStateChanged(Qt::WindowState)), this, SLOT(psStateChanged(Qt::WindowState))); -} - -void PsMainWindow::psSavePosition(Qt::WindowState state) { - if (state == Qt::WindowActive) state = windowHandle()->windowState(); - if (state == Qt::WindowMinimized || !posInited) return; -/* - TWindowPos pos(cWindowPos()), curPos = pos; - - if (state == Qt::WindowMaximized) { - curPos.maximized = 1; - } else { - RECT w; - GetWindowRect(ps_hWnd, &w); - curPos.x = w.left; - curPos.y = w.top; - curPos.w = w.right - w.left; - curPos.h = w.bottom - w.top; - curPos.maximized = 0; - } - - HMONITOR hMonitor = MonitorFromWindow(ps_hWnd, MONITOR_DEFAULTTONEAREST); - if (hMonitor) { - MONITORINFOEX info; - info.cbSize = sizeof(info); - GetMonitorInfo(hMonitor, &info); - if (!curPos.maximized) { - curPos.x -= info.rcWork.left; - curPos.y -= info.rcWork.top; - } - curPos.moncrc = hashCrc32(info.szDevice, sizeof(info.szDevice)); - } - - if (curPos.w >= st::wndMinWidth && curPos.h >= st::wndMinHeight) { - if (curPos.x != pos.x || curPos.y != pos.y || curPos.w != pos.w || curPos.h != pos.h || curPos.moncrc != pos.moncrc || curPos.maximized != pos.maximized) { - cSetWindowPos(curPos); - App::writeConfig(); - } - }*/ -} - -void PsMainWindow::psUpdatedPosition() { - //psUpdatedPositionTimer.start(4000); -} - -void PsMainWindow::psStateChanged(Qt::WindowState state) { - psUpdateSysMenu(state); - psUpdateMargins(); - /*if (state == Qt::WindowMinimized && GetWindowLong(ps_hWnd, GWL_HWNDPARENT)) { - minimizeToTray(); - } - psSavePosition(state);*/ -} - -//Q_DECLARE_METATYPE(QMargins); -void PsMainWindow::psFirstShow() { - //_psShadowWindows.init(_shActive); - finished = false; - - //psUpdateMargins(); - - //_psShadowWindows.update(_PsShadowHidden); - bool showShadows = true; - - show(); - if (cWindowPos().maximized) { - setWindowState(Qt::WindowMaximized); - } - - if (cFromAutoStart()) { - if (cStartMinimized()) { - setWindowState(Qt::WindowMinimized); - if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) { - hide(); - } else { - show(); - } - showShadows = false; - } else { - show(); - } - } else { - show(); - } - posInited = true; - //if (showShadows) { - // _psShadowWindows.update(_PsShadowMoved | _PsShadowResized | _PsShadowShown); - //} -} - -bool PsMainWindow::psHandleTitle() { - //return useDWM; - return true; -} - -void PsMainWindow::psInitSysMenu() { - /*Qt::WindowStates states = windowState(); - ps_menu = GetSystemMenu(ps_hWnd, FALSE); - psUpdateSysMenu(windowHandle()->windowState());*/ -} - -void PsMainWindow::psUpdateSysMenu(Qt::WindowState state) { - /*if (!ps_menu) return; - - int menuToDisable = SC_RESTORE; - if (state == Qt::WindowMaximized) { - menuToDisable = SC_MAXIMIZE; - } else if (state == Qt::WindowMinimized) { - menuToDisable = SC_MINIMIZE; - } - int itemCount = GetMenuItemCount(ps_menu); - for (int i = 0; i < itemCount; ++i) { - MENUITEMINFO itemInfo = {0}; - itemInfo.cbSize = sizeof(itemInfo); - itemInfo.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID; - if (GetMenuItemInfo(ps_menu, i, TRUE, &itemInfo)) { - if (itemInfo.fType & MFT_SEPARATOR) { - continue; - } - if (itemInfo.wID && !(itemInfo.fState & MFS_DEFAULT)) { - UINT fOldState = itemInfo.fState, fState = itemInfo.fState & ~MFS_DISABLED; - if (itemInfo.wID == SC_CLOSE) { - fState |= MFS_DEFAULT; - } else if (itemInfo.wID == menuToDisable || (itemInfo.wID != SC_MINIMIZE && itemInfo.wID != SC_MAXIMIZE && itemInfo.wID != SC_RESTORE)) { - fState |= MFS_DISABLED; - } - itemInfo.fMask = MIIM_STATE; - itemInfo.fState = fState; - if (!SetMenuItemInfo(ps_menu, i, TRUE, &itemInfo)) { - DEBUG_LOG(("PS Error: could not set state %1 to menu item %2, old state %3, error %4").arg(fState).arg(itemInfo.wID).arg(fOldState).arg(GetLastError())); - DestroyMenu(ps_menu); - ps_menu = 0; - break; - } - } - } else { - DEBUG_LOG(("PS Error: could not get state, menu item %1 of %2, error %3").arg(i).arg(itemCount).arg(GetLastError())); - DestroyMenu(ps_menu); - ps_menu = 0; - break; - } - }*/ -} - -void PsMainWindow::psUpdateMargins() { - /*if (!useDWM) return; - - RECT r, a; - - GetClientRect(ps_hWnd, &r); - a = r; - - LONG style = GetWindowLong(ps_hWnd, GWL_STYLE), styleEx = GetWindowLong(ps_hWnd, GWL_EXSTYLE); - AdjustWindowRectEx(&a, style, false, styleEx); - simpleMargins = QMargins(a.left - r.left, a.top - r.top, r.right - a.right, r.bottom - a.bottom); - if (style & WS_MAXIMIZE) { - RECT w, m; - GetWindowRect(ps_hWnd, &w); - m = w; - - HMONITOR hMonitor = MonitorFromRect(&w, MONITOR_DEFAULTTONEAREST); - if (hMonitor) { - MONITORINFO mi; - mi.cbSize = sizeof(mi); - GetMonitorInfo(hMonitor, &mi); - m = mi.rcWork; - } - - dleft = w.left - m.left; - dtop = w.top - m.top; - - margins.setLeft(simpleMargins.left() - w.left + m.left); - margins.setRight(simpleMargins.right() - m.right + w.right); - margins.setBottom(simpleMargins.bottom() - m.bottom + w.bottom); - margins.setTop(simpleMargins.top() - w.top + m.top); - } else { - margins = simpleMargins; - dleft = dtop = 0; - } - - QPlatformNativeInterface *i = QGuiApplication::platformNativeInterface(); - i->setWindowProperty(windowHandle()->handle(), "WindowsCustomMargins", QVariant::fromValue(margins)); - if (!themeInited) { - themeInited = true; - if (useTheme) { - if (QSysInfo::WindowsVersion < QSysInfo::WV_WINDOWS8) { - setWindowTheme(ps_hWnd, L" ", L" "); - QApplication::setStyle(QStyleFactory::create("Windows")); - } - } - }*/ -} - -void PsMainWindow::psFlash() { - /*if (GetForegroundWindow() == ps_hWnd) return; - - FLASHWINFO info; - info.cbSize = sizeof(info); - info.hwnd = ps_hWnd; - info.dwFlags = FLASHW_ALL; - info.dwTimeout = 0; - info.uCount = 1; - FlashWindowEx(&info);*/ -} - -/*HWND PsMainWindow::psHwnd() const { - return ps_hWnd; -} - -HMENU PsMainWindow::psMenu() const { - return ps_menu; -}*/ - -/*void PsMainWindow::psDestroyIcons() { - if (ps_iconBig) { - DestroyIcon(ps_iconBig); - ps_iconBig = 0; - } - if (ps_iconSmall) { - DestroyIcon(ps_iconSmall); - ps_iconSmall = 0; - } - if (ps_iconOverlay) { - DestroyIcon(ps_iconOverlay); - ps_iconOverlay = 0; - } -}*/ - -PsMainWindow::~PsMainWindow() { - finished = true; - //if (ps_menu) DestroyMenu(ps_menu); - //psDestroyIcons(); - //_psShadowWindows.destroy(); - //psClearNotifyFast(); - //if (ps_tbHider_hWnd) DestroyWindow(ps_tbHider_hWnd); -} - -void PsMainWindow::psNotify(History *history, MsgId msgId) { - /*if (App::quiting()) return; - if (!cDesktopNotify()) { - history->clearNotifyFrom(); - } - if (notifyHistories.constFind(history) != notifyHistories.cend()) return; - notifyHistories.insert(history); - psShowNextNotify();*/ -} - -void PsMainWindow::psClearNotify(History *history) { - /*if (!history) { - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->unlinkHistory(); - } - for (NotifyHistories::const_iterator i = notifyHistories.cbegin(), e = notifyHistories.cend(); i != e; ++i) { - (*i)->clearNotifyFrom(); - } - notifyHistories.clear(); - return; - } - notifyHistories.remove(history); - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->unlinkHistory(history); - }*/ -} - -void PsMainWindow::psClearNotifyFast() { - /*notifyHistories.clear(); - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->deleteLater(); - } - notifyWindows.clear();*/ -} - -/*void PsMainWindow::psShowNextNotify(PsNotifyWindow *remove) { - if (App::quiting()) return; - - int32 count = NotifyWindows; - if (remove) { - for (PsNotifyWindows::iterator i = notifyWindows.begin(), e = notifyWindows.end(); i != e; ++i) { - if ((*i) == remove) { - notifyWindows.erase(i); - break; - } - } - } - QRect r = QApplication::desktop()->availableGeometry(App::wnd()); - int32 x = r.width() - st::notifyWidth - st::notifyDeltaX, y = r.bottom() - st::notifyHeight - st::notifyDeltaY; - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - int32 ind = (*i)->index(); - if (ind < 0) continue; - --count; - } - while (count > 0) { - HistoryItem *notify = 0; - for (NotifyHistories::iterator i = notifyHistories.begin(), e = notifyHistories.end(); i != e;) { - if ((*i)->notifyFrom) { - if (!notify || (*i)->notifyFrom->date < notify->date) { - notify = (*i)->notifyFrom; - } - ++i; - } else { - i = notifyHistories.erase(i); - } - } - if (notify) { - notifyWindows.push_back(new PsNotifyWindow(notify, x, y)); - notify->history()->getNextNotifyFrom(); - --count; - } else { - break; - } - } - count = NotifyWindows - count; - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - int32 ind = (*i)->index(); - if (ind < 0) continue; - --count; - (*i)->moveTo(x, y - count * (st::notifyHeight + st::notifyDeltaY)); - } -}*/ - -void PsMainWindow::psStopHiding() { - /*for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->stopHiding(); - }*/ -} - -void PsMainWindow::psStartHiding() { - /*for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->startHiding(); - }*/ -} - -void PsMainWindow::psUpdateNotifies() { - /*for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->updatePeerPhoto(); - }*/ -} - -void PsMainWindow::psNotifySettingGot() { -} - -/*PsNotifyWindow::PsNotifyWindow(HistoryItem *item, int32 x, int32 y) : history(item->history()), aOpacity(0), _index(0), hiding(false), started(GetTickCount()), - alphaDuration(st::notifyFastAnim), posDuration(st::notifyFastAnim), aY(y + st::notifyHeight + st::notifyDeltaY), close(this, st::notifyClose), aOpacityFunc(st::notifyFastAnimFunc) { - - int32 w = st::notifyWidth, h = st::notifyHeight; - QImage img(w, h, QImage::Format_ARGB32_Premultiplied); - img.fill(st::notifyBG->c); - - { - QPainter p(&img); - p.setPen(st::notifyBorder->p); - p.setBrush(Qt::NoBrush); - p.drawRect(0, 0, w - 1, h - 1); - - if (history->peer->photo->loaded()) { - p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), history->peer->photo->pix(st::notifyPhotoSize)); - } else { - MTP::clearLoaderPriorities(); - peerPhoto = history->peer->photo; - peerPhoto->load(true, true); - } - - int32 itemWidth = w - st::notifyPhotoPos.x() - st::notifyPhotoSize - st::notifyTextLeft - st::notifyClosePos.x() - st::notifyClose.width; - - QRect rectForName(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyTextTop, itemWidth, st::msgNameFont->height); - if (history->peer->chat) { - p.drawPixmap(QPoint(rectForName.left() + st::dlgChatImgLeft, rectForName.top() + st::dlgChatImgTop), App::sprite(), st::dlgChatImg); - rectForName.setLeft(rectForName.left() + st::dlgChatImgSkip); - } - - QDateTime now(QDateTime::currentDateTime()), lastTime(item->date); - QDate nowDate(now.date()), lastDate(lastTime.date()); - QString dt = lastTime.toString(qsl("hh:mm")); - int32 dtWidth = st::dlgHistFont->m.width(dt); - rectForName.setWidth(rectForName.width() - dtWidth - st::dlgDateSkip); - p.setFont(st::dlgDateFont->f); - p.setPen(st::dlgDateColor->p); - p.drawText(rectForName.left() + rectForName.width() + st::dlgDateSkip, rectForName.top() + st::dlgHistFont->ascent, dt); - - const HistoryItem *textCachedFor = 0; - Text itemTextCache(itemWidth); - bool active = false; - item->drawInDialog(p, QRect(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height, itemWidth, 2 * st::dlgFont->height), active, textCachedFor, itemTextCache); - - p.setPen(st::dlgNameColor->p); - history->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); - } - pm = QPixmap::fromImage(img); - - hideTimer.setSingleShot(true); - connect(&hideTimer, SIGNAL(timeout()), this, SLOT(hideByTimer())); - - inputTimer.setSingleShot(true); - connect(&inputTimer, SIGNAL(timeout()), this, SLOT(checkLastInput())); - - connect(&close, SIGNAL(clicked()), this, SLOT(unlinkHistory())); - close.setAcceptBoth(true); - close.move(w - st::notifyClose.width - st::notifyClosePos.x(), st::notifyClosePos.y()); - close.show(); - - aY.start(y); - setGeometry(x, aY.current(), st::notifyWidth, st::notifyHeight); - - aOpacity.start(1); - setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint); - - show(); - - setWindowOpacity(aOpacity.current()); - - alphaDuration = posDuration = st::notifyFastAnim; - anim::start(this); - - checkLastInput(); -} - -void PsNotifyWindow::checkLastInput() { - LASTINPUTINFO lii; - lii.cbSize = sizeof(LASTINPUTINFO); - BOOL res = GetLastInputInfo(&lii); - if (!res || lii.dwTime >= started) { - hideTimer.start(st::notifyWaitLongHide); - } else { - inputTimer.start(300); - } -} - -void PsNotifyWindow::moveTo(int32 x, int32 y, int32 index) { - if (index >= 0) { - _index = index; - } - move(x, aY.current()); - aY.start(y); - aOpacity.restart(); - posDuration = st::notifyFastAnim; - anim::start(this); -} - -void PsNotifyWindow::updatePeerPhoto() { - if (!peerPhoto->isNull() && peerPhoto->loaded()) { - QImage img(pm.toImage()); - { - QPainter p(&img); - p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), peerPhoto->pix(st::notifyPhotoSize)); - } - peerPhoto = ImagePtr(); - pm = QPixmap::fromImage(img); - update(); - } -} - -void PsNotifyWindow::unlinkHistory(History *hist) { - if (!hist || hist == history) { - animHide(st::notifyFastAnim, st::notifyFastAnimFunc); - history = 0; - App::wnd()->psShowNextNotify(); - } -} - -void PsNotifyWindow::enterEvent(QEvent *e) { - if (!history) return; - if (App::wnd()) App::wnd()->psStopHiding(); -} - -void PsNotifyWindow::leaveEvent(QEvent *e) { - if (!history) return; - App::wnd()->psStartHiding(); -} - -void PsNotifyWindow::startHiding() { - hideTimer.start(st::notifyWaitShortHide); -} - -void PsNotifyWindow::mousePressEvent(QMouseEvent *e) { - if (!history) return; - if (e->button() == Qt::RightButton) { - unlinkHistory(); - } else if (history) { - App::wnd()->showFromTray(); - App::wnd()->hideSettings(); - App::main()->showPeer(history->peer->id, false, true); - e->ignore(); - } -} - -void PsNotifyWindow::paintEvent(QPaintEvent *e) { - QPainter p(this); - p.drawPixmap(0, 0, pm); -} - -void PsNotifyWindow::animHide(float64 duration, anim::transition func) { - if (!history) return; - alphaDuration = duration; - aOpacityFunc = func; - aOpacity.start(0); - aY.restart(); - hiding = true; - anim::start(this); -} - -void PsNotifyWindow::stopHiding() { - if (!history) return; - alphaDuration = st::notifyFastAnim; - aOpacityFunc = st::notifyFastAnimFunc; - aOpacity.start(1); - aY.restart(); - hiding = false; - hideTimer.stop(); - anim::start(this); -} - -void PsNotifyWindow::hideByTimer() { - if (!history) return; - animHide(st::notifySlowHide, st::notifySlowHideFunc); -} - -bool PsNotifyWindow::animStep(float64 ms) { - float64 dtAlpha = ms / alphaDuration, dtPos = ms / posDuration; - if (dtAlpha >= 1) { - aOpacity.finish(); - if (hiding) { - deleteLater(); - } - } else { - aOpacity.update(dtAlpha, aOpacityFunc); - } - setWindowOpacity(aOpacity.current()); - if (dtPos >= 1) { - aY.finish(); - } else { - aY.update(dtPos, anim::linear); - } - move(x(), aY.current()); - update(); - return (dtAlpha < 1 || !hiding && dtPos < 1); -} - -PsNotifyWindow::~PsNotifyWindow() { - if (App::wnd()) App::wnd()->psShowNextNotify(this); -}*/ - -PsApplication::PsApplication(int argc, char *argv[]) : QApplication(argc, argv) { -} - -void PsApplication::psInstallEventFilter() { - /*delete _psEventFilter; - _psEventFilter = new _PsEventFilter(); - installNativeEventFilter(_psEventFilter);*/ -} - -PsApplication::~PsApplication() { - //delete _psEventFilter; - //_psEventFilter = 0; -} - -PsUpdateDownloader::PsUpdateDownloader(QThread *thread, const MTPDhelp_appUpdate &update) : already(0), reply(0), full(0) { - updateUrl = qs(update.vurl); - moveToThread(thread); - manager.moveToThread(thread); - App::setProxySettings(manager); - - connect(thread, SIGNAL(started()), this, SLOT(start())); - initOutput(); -} - -PsUpdateDownloader::PsUpdateDownloader(QThread *thread, const QString &url) : already(0), reply(0), full(0) { - updateUrl = url; - moveToThread(thread); - manager.moveToThread(thread); - App::setProxySettings(manager); - - connect(thread, SIGNAL(started()), this, SLOT(start())); - initOutput(); -} - -void PsUpdateDownloader::initOutput() { - QString fileName; - QRegularExpressionMatch m = QRegularExpression(qsl("/([^/\\?]+)(\\?|$)")).match(updateUrl); - if (m.hasMatch()) { - fileName = m.captured(1).replace(QRegularExpression(qsl("[^a-zA-Z0-9_\\-]")), QString()); - } - if (fileName.isEmpty()) { - fileName = qsl("tupdate-%1").arg(rand()); - } - QString dirStr = cWorkingDir() + qsl("tupdates/"); - fileName = dirStr + fileName; - QFileInfo file(fileName); - - QDir dir(dirStr); - if (dir.exists()) { - QFileInfoList all = dir.entryInfoList(QDir::Files); - for (QFileInfoList::iterator i = all.begin(), e = all.end(); i != e; ++i) { - if (i->absoluteFilePath() != file.absoluteFilePath()) { - QFile::remove(i->absoluteFilePath()); - } - } - } else { - dir.mkdir(dir.absolutePath()); - } - outputFile.setFileName(fileName); - if (file.exists()) { - uint64 fullSize = file.size(); - if (fullSize < INT_MAX) { - int32 goodSize = (int32)fullSize; - if (goodSize % UpdateChunk) { - goodSize = goodSize - (goodSize % UpdateChunk); - if (goodSize) { - if (outputFile.open(QIODevice::ReadOnly)) { - QByteArray goodData = outputFile.readAll().mid(0, goodSize); - outputFile.close(); - if (outputFile.open(QIODevice::WriteOnly)) { - outputFile.write(goodData); - outputFile.close(); - - QMutexLocker lock(&mutex); - already = goodSize; - } - } - } - } else { - QMutexLocker lock(&mutex); - already = goodSize; - } - } - if (!already) { - QFile::remove(fileName); - } - } -} - -void PsUpdateDownloader::start() { - sendRequest(); -} - -void PsUpdateDownloader::sendRequest() { - QNetworkRequest req(updateUrl); - QByteArray rangeHeaderValue = "bytes=" + QByteArray::number(already) + "-";// + QByteArray::number(already + cUpdateChunk() - 1); - req.setRawHeader("Range", rangeHeaderValue); - req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); - if (reply) reply->deleteLater(); - reply = manager.get(req); - connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(partFinished(qint64,qint64))); - connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(partFailed(QNetworkReply::NetworkError))); - connect(reply, SIGNAL(metaDataChanged()), this, SLOT(partMetaGot())); -} - -void PsUpdateDownloader::partMetaGot() { - typedef QList Pairs; - Pairs pairs = reply->rawHeaderPairs(); - for (Pairs::iterator i = pairs.begin(), e = pairs.end(); i != e; ++i) { - if (QString::fromUtf8(i->first).toLower() == "content-range") { - QRegularExpressionMatch m = QRegularExpression(qsl("/(\\d+)([^\\d]|$)")).match(QString::fromUtf8(i->second)); - if (m.hasMatch()) { - { - QMutexLocker lock(&mutex); - full = m.captured(1).toInt(); - } - emit App::app()->updateDownloading(already, full); - } - } - } -} - -int32 PsUpdateDownloader::ready() { - QMutexLocker lock(&mutex); - return already; -} - -int32 PsUpdateDownloader::size() { - QMutexLocker lock(&mutex); - return full; -} - -void PsUpdateDownloader::partFinished(qint64 got, qint64 total) { - if (!reply) return; - - QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); - if (statusCode.isValid()) { - int status = statusCode.toInt(); - if (status != 200 && status != 206 && status != 416) { - LOG(("Update Error: Bad HTTP status received in partFinished(): %1").arg(status)); - return fatalFail(); - } - } - - if (!already && !full) { - QMutexLocker lock(&mutex); - full = total; - } - DEBUG_LOG(("Update Info: part %1 of %2").arg(got).arg(total)); - - if (!outputFile.isOpen()) { - if (!outputFile.open(QIODevice::Append)) { - LOG(("Update Error: Could not open output file '%1' for appending").arg(outputFile.fileName())); - return fatalFail(); - } - } - QByteArray r = reply->readAll(); - if (!r.isEmpty()) { - outputFile.write(r); - - QMutexLocker lock(&mutex); - already += r.size(); - } - if (got >= total) { - reply->deleteLater(); - reply = 0; - outputFile.close(); - unpackUpdate(); - } else { - emit App::app()->updateDownloading(already, full); - } -} - -void PsUpdateDownloader::partFailed(QNetworkReply::NetworkError e) { - if (!reply) return; - - QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); - reply->deleteLater(); - reply = 0; - if (statusCode.isValid()) { - int status = statusCode.toInt(); - if (status == 416) { // Requested range not satisfiable - outputFile.close(); - unpackUpdate(); - return; - } - } - LOG(("Update Error: failed to download part starting from %1, error %2").arg(already).arg(e)); - emit App::app()->updateFailed(); -} - -void PsUpdateDownloader::deleteDir(const QString &dir) { - /*std::wstring wDir = QDir::toNativeSeparators(dir).toStdWString(); - WCHAR path[4096]; - memcpy(path, wDir.c_str(), (wDir.size() + 1) * sizeof(WCHAR)); - path[wDir.size() + 1] = 0; - SHFILEOPSTRUCT file_op = { - NULL, - FO_DELETE, - path, - L"", - FOF_NOCONFIRMATION | - FOF_NOERRORUI | - FOF_SILENT, - false, - 0, - L"" - }; - int res = SHFileOperation(&file_op);*/ -} - -void PsUpdateDownloader::fatalFail() { - clearAll(); - emit App::app()->updateFailed(); -} - -void PsUpdateDownloader::clearAll() { - deleteDir(cWorkingDir() + qsl("tupdates")); -} - -void PsUpdateDownloader::unpackUpdate() { - /*QByteArray packed; - if (!outputFile.open(QIODevice::ReadOnly)) { - LOG(("Update Error: cant read updates file!")); - return fatalFail(); - } - - const int32 hSigLen = 128, hShaLen = 20, hPropsLen = LZMA_PROPS_SIZE, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hPropsLen + hOriginalSizeLen; // header - - QByteArray compressed = outputFile.readAll(); - int32 compressedLen = compressed.size() - hSize; - if (compressedLen <= 0) { - LOG(("Update Error: bad compressed size: %1").arg(compressed.size())); - return fatalFail(); - } - outputFile.close(); - - QString tempDirPath = cWorkingDir() + qsl("tupdates/temp"), readyDirPath = cWorkingDir() + qsl("tupdates/ready"); - deleteDir(tempDirPath); - deleteDir(readyDirPath); - - QDir tempDir(tempDirPath), readyDir(readyDirPath); - if (tempDir.exists() || readyDir.exists()) { - LOG(("Update Error: cant clear tupdates/temp or tupdates/ready dir!")); - return fatalFail(); - } - - uchar sha1Buffer[20]; - bool goodSha1 = !memcmp(compressed.constData() + hSigLen, hashSha1(compressed.constData() + hSigLen + hShaLen, compressedLen + hPropsLen + hOriginalSizeLen, sha1Buffer), hShaLen); - if (!goodSha1) { - LOG(("Update Error: bad SHA1 hash of update file!")); - return fatalFail(); - } - - RSA *pbKey = PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast(UpdatesPublicKey), -1), 0, 0, 0); - if (!pbKey) { - LOG(("Update Error: cant read public rsa key!")); - return fatalFail(); - } - if (RSA_verify(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (const uchar*)(compressed.constData()), hSigLen, pbKey) != 1) { // verify signature - RSA_free(pbKey); - LOG(("Update Error: bad RSA signature of update file!")); - return fatalFail(); - } - RSA_free(pbKey); - - QByteArray uncompressed; - - int32 uncompressedLen; - memcpy(&uncompressedLen, compressed.constData() + hSigLen + hShaLen + hPropsLen, hOriginalSizeLen); - uncompressed.resize(uncompressedLen); - - size_t resultLen = uncompressed.size(); - SizeT srcLen = compressedLen; - int uncompressRes = LzmaUncompress((uchar*)uncompressed.data(), &resultLen, (const uchar*)(compressed.constData() + hSize), &srcLen, (const uchar*)(compressed.constData() + hSigLen + hShaLen), LZMA_PROPS_SIZE); - if (uncompressRes != SZ_OK) { - LOG(("Update Error: could not uncompress lzma, code: %1").arg(uncompressRes)); - return fatalFail(); - } - - tempDir.mkdir(tempDir.absolutePath()); - - quint32 version; - { - QBuffer buffer(&uncompressed); - buffer.open(QIODevice::ReadOnly); - QDataStream stream(&buffer); - stream.setVersion(QDataStream::Qt_5_1); - - stream >> version; - if (stream.status() != QDataStream::Ok) { - LOG(("Update Error: cant read version from downloaded stream, status: %1").arg(stream.status())); - return fatalFail(); - } - if (version <= AppVersion) { - LOG(("Update Error: downloaded version %1 is not greater, than mine %2").arg(version).arg(AppVersion)); - return fatalFail(); - } - - quint32 filesCount; - stream >> filesCount; - if (stream.status() != QDataStream::Ok) { - LOG(("Update Error: cant read files count from downloaded stream, status: %1").arg(stream.status())); - return fatalFail(); - } - if (!filesCount) { - LOG(("Update Error: update is empty!")); - return fatalFail(); - } - for (int32 i = 0; i < filesCount; ++i) { - QString relativeName; - quint32 fileSize; - QByteArray fileInnerData; - - stream >> relativeName >> fileSize >> fileInnerData; - if (stream.status() != QDataStream::Ok) { - LOG(("Update Error: cant read file from downloaded stream, status: %1").arg(stream.status())); - return fatalFail(); - } - if (fileSize != fileInnerData.size()) { - LOG(("Update Error: bad file size %1 not matching data size %2").arg(fileSize).arg(fileInnerData.size())); - return fatalFail(); - } - - QFile f(tempDirPath + '/' + relativeName); - if (!f.open(QIODevice::WriteOnly)) { - LOG(("Update Error: cant open file '%1' for writing").arg(tempDirPath + '/' + relativeName)); - return fatalFail(); - } - if (f.write(fileInnerData) != fileSize) { - f.close(); - LOG(("Update Error: cant write file '%1'").arg(tempDirPath + '/' + relativeName)); - return fatalFail(); - } - f.close(); - } - - // create tdata/version file - tempDir.mkdir(QDir(tempDirPath + qsl("/tdata")).absolutePath()); - std::wstring versionString = ((version % 1000) ? QString("%1.%2.%3").arg(int(version / 1000000)).arg(int((version % 1000000) / 1000)).arg(int(version % 1000)) : QString("%1.%2").arg(int(version / 1000000)).arg(int((version % 1000000) / 1000))).toStdWString(); - DWORD versionNum = DWORD(version), versionLen = DWORD(versionString.size() * sizeof(WCHAR)); - WCHAR versionStr[32]; - memcpy(versionStr, versionString.c_str(), versionLen); - - QFile fVersion(tempDirPath + qsl("/tdata/version")); - if (!fVersion.open(QIODevice::WriteOnly)) { - LOG(("Update Error: cant write version file '%1'").arg(tempDirPath + qsl("/version"))); - return fatalFail(); - } - fVersion.write((const char*)&versionNum, sizeof(DWORD)); - fVersion.write((const char*)&versionLen, sizeof(DWORD)); - fVersion.write((const char*)&versionStr[0], versionLen); - fVersion.close(); - } - - if (!tempDir.rename(tempDir.absolutePath(), readyDir.absolutePath())) { - LOG(("Update Error: cant rename temp dir '%1' to ready dir '%2'").arg(tempDir.absolutePath()).arg(readyDir.absolutePath())); - return fatalFail(); - } - deleteDir(tempDirPath); - outputFile.remove(); - - emit App::app()->updateReady();*/ -} - -PsUpdateDownloader::~PsUpdateDownloader() { - delete reply; - reply = 0; -} - -/*namespace { - BOOL CALLBACK _ActivateProcess(HWND hWnd, LPARAM lParam) { - uint64 &processId(*(uint64*)lParam); - - DWORD dwProcessId; - ::GetWindowThreadProcessId(hWnd, &dwProcessId); - - if ((uint64)dwProcessId == processId) { // found top-level window - static const int32 nameBufSize = 1024; - WCHAR nameBuf[nameBufSize]; - int32 len = GetWindowText(hWnd, nameBuf, nameBufSize); - if (len && len < nameBufSize) { - if (QRegularExpression(qsl("^Telegram(\\s*\\(\\d+\\))?$")).match(QString::fromStdWString(nameBuf)).hasMatch()) { - BOOL res = ::SetForegroundWindow(hWnd); - return FALSE; - } - } - } - return TRUE; - } -}*/ - -void psActivateProcess(uint64 pid) { - //::EnumWindows((WNDENUMPROC)_ActivateProcess, (LPARAM)&pid); -} - -QString psCurrentCountry() { - /*int chCount = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, 0, 0); - if (chCount && chCount < 128) { - WCHAR wstrCountry[128]; - int len = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, wstrCountry, chCount); - return len ? QString::fromStdWString(std::wstring(wstrCountry)) : QString::fromLatin1(DefaultCountry); - } - return QString::fromLatin1(DefaultCountry);*/ - return QString(""); - //TODO -} - -/*namespace { - QString langById(int lngId) { - int primary = lngId & 0xFF; - switch (primary) { - case 0x36: return qsl("af"); - case 0x1C: return qsl("sq"); - case 0x5E: return qsl("am"); - case 0x01: return qsl("ar"); - case 0x2B: return qsl("hy"); - case 0x4D: return qsl("as"); - case 0x2C: return qsl("az"); - case 0x45: return qsl("bn"); - case 0x6D: return qsl("ba"); - case 0x2D: return qsl("eu"); - case 0x23: return qsl("be"); - case 0x1A: - if (lngId == LANG_CROATIAN) { - return qsl("hr"); - } else if (lngId == LANG_BOSNIAN_NEUTRAL || lngId == LANG_BOSNIAN) { - return qsl("bs"); - } - return qsl("sr"); - break; - case 0x7E: return qsl("br"); - case 0x02: return qsl("bg"); - case 0x92: return qsl("ku"); - case 0x03: return qsl("ca"); - case 0x04: return qsl("zh"); - case 0x83: return qsl("co"); - case 0x05: return qsl("cs"); - case 0x06: return qsl("da"); - case 0x65: return qsl("dv"); - case 0x13: return qsl("nl"); - case 0x09: return qsl("en"); - case 0x25: return qsl("et"); - case 0x38: return qsl("fo"); - case 0x0B: return qsl("fi"); - case 0x0c: return qsl("fr"); - case 0x62: return qsl("fy"); - case 0x56: return qsl("gl"); - case 0x37: return qsl("ka"); - case 0x07: return qsl("de"); - case 0x08: return qsl("el"); - case 0x6F: return qsl("kl"); - case 0x47: return qsl("gu"); - case 0x68: return qsl("ha"); - case 0x0D: return qsl("he"); - case 0x39: return qsl("hi"); - case 0x0E: return qsl("hu"); - case 0x0F: return qsl("is"); - case 0x70: return qsl("ig"); - case 0x21: return qsl("id"); - case 0x5D: return qsl("iu"); - case 0x3C: return qsl("ga"); - case 0x34: return qsl("xh"); - case 0x35: return qsl("zu"); - case 0x10: return qsl("it"); - case 0x11: return qsl("ja"); - case 0x4B: return qsl("kn"); - case 0x3F: return qsl("kk"); - case 0x53: return qsl("kh"); - case 0x87: return qsl("rw"); - case 0x12: return qsl("ko"); - case 0x40: return qsl("ky"); - case 0x54: return qsl("lo"); - case 0x26: return qsl("lv"); - case 0x27: return qsl("lt"); - case 0x6E: return qsl("lb"); - case 0x2F: return qsl("mk"); - case 0x3E: return qsl("ms"); - case 0x4C: return qsl("ml"); - case 0x3A: return qsl("mt"); - case 0x81: return qsl("mi"); - case 0x4E: return qsl("mr"); - case 0x50: return qsl("mn"); - case 0x61: return qsl("ne"); - case 0x14: return qsl("no"); - case 0x82: return qsl("oc"); - case 0x48: return qsl("or"); - case 0x63: return qsl("ps"); - case 0x29: return qsl("fa"); - case 0x15: return qsl("pl"); - case 0x16: return qsl("pt"); - case 0x67: return qsl("ff"); - case 0x46: return qsl("pa"); - case 0x18: return qsl("ro"); - case 0x17: return qsl("rm"); - case 0x19: return qsl("ru"); - case 0x3B: return qsl("se"); - case 0x4F: return qsl("sa"); - case 0x32: return qsl("tn"); - case 0x59: return qsl("sd"); - case 0x5B: return qsl("si"); - case 0x1B: return qsl("sk"); - case 0x24: return qsl("sl"); - case 0x0A: return qsl("es"); - case 0x41: return qsl("sw"); - case 0x1D: return qsl("sv"); - case 0x28: return qsl("tg"); - case 0x49: return qsl("ta"); - case 0x44: return qsl("tt"); - case 0x4A: return qsl("te"); - case 0x1E: return qsl("th"); - case 0x51: return qsl("bo"); - case 0x73: return qsl("ti"); - case 0x1F: return qsl("tr"); - case 0x42: return qsl("tk"); - case 0x22: return qsl("uk"); - case 0x20: return qsl("ur"); - case 0x80: return qsl("ug"); - case 0x43: return qsl("uz"); - case 0x2A: return qsl("vi"); - case 0x52: return qsl("cy"); - case 0x88: return qsl("wo"); - case 0x78: return qsl("ii"); - case 0x6A: return qsl("yo"); - } - return QString::fromLatin1(DefaultLanguage); - } -}*/ - -QString psCurrentLanguage() { -/* int chCount = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SNAME, 0, 0); - if (chCount && chCount < 128) { - WCHAR wstrLocale[128]; - int len = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SNAME, wstrLocale, chCount); - if (!len) return QString::fromLatin1(DefaultLanguage); - QString locale = QString::fromStdWString(std::wstring(wstrLocale)); - QRegularExpressionMatch m = QRegularExpression("(^|[^a-z])([a-z]{2})-").match(locale); - if (m.hasMatch()) { - return m.captured(2); - } - } - chCount = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ILANGUAGE, 0, 0); - if (chCount && chCount < 128) { - WCHAR wstrLocale[128]; - int len = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ILANGUAGE, wstrLocale, chCount), lngId = 0; - if (len < 5) return QString::fromLatin1(DefaultLanguage); - - for (int i = 0; i < 4; ++i) { - WCHAR ch = wstrLocale[i]; - lngId *= 16; - if (ch >= WCHAR('0') && ch <= WCHAR('9')) { - lngId += (ch - WCHAR('0')); - } else if (ch >= WCHAR('A') && ch <= WCHAR('F')) { - lngId += (10 + ch - WCHAR('A')); - } else { - return QString::fromLatin1(DefaultLanguage); - } - } - return langById(lngId); - } - return QString::fromLatin1(DefaultLanguage);*/ - return QString("en"); -} - -QString psAppDataPath() { - /*static const int maxFileLen = MAX_PATH * 10; - WCHAR wstrPath[maxFileLen]; - if (GetEnvironmentVariable(L"APPDATA", wstrPath, maxFileLen)) { - QDir appData(QString::fromStdWString(std::wstring(wstrPath))); - return appData.absolutePath() + "/" + QString::fromWCharArray(AppName) + "/"; - }*/ - return QString(); -} - -QString psCurrentExeDirectory() { - /*LPWSTR *args; - int argsCount; - args = CommandLineToArgvW(GetCommandLine(), &argsCount); - if (args) { - QFileInfo info(QDir::fromNativeSeparators(QString::fromWCharArray(args[0]))); - if (info.isFile()) { - return info.absoluteDir().absolutePath() + '/'; - } - LocalFree(args); - }*/ - return QString(); -} - -void psDoCleanup() { - try { - psAutoStart(false, true); - } catch (...) { - } -} - -int psCleanup() { - /*__try - { - psDoCleanup(); - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - return 0; - }*/ - return 0; -} - -void psDoFixPrevious() { - /*try { - static const int bufSize = 4096; - DWORD checkType, checkSize = bufSize * 2; - WCHAR checkStr[bufSize]; - - QString appId = QString::fromStdWString(AppId); - QString newKeyStr1 = QString("Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%1_is1").arg(appId); - QString newKeyStr2 = QString("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%1_is1").arg(appId); - QString oldKeyStr1 = QString("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%1_is1").arg(appId); - QString oldKeyStr2 = QString("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%1_is1").arg(appId); - HKEY newKey1, newKey2, oldKey1, oldKey2; - LSTATUS newKeyRes1 = RegOpenKeyEx(HKEY_CURRENT_USER, newKeyStr1.toStdWString().c_str(), 0, KEY_READ, &newKey1); - LSTATUS newKeyRes2 = RegOpenKeyEx(HKEY_CURRENT_USER, newKeyStr2.toStdWString().c_str(), 0, KEY_READ, &newKey2); - LSTATUS oldKeyRes1 = RegOpenKeyEx(HKEY_LOCAL_MACHINE, oldKeyStr1.toStdWString().c_str(), 0, KEY_READ, &oldKey1); - LSTATUS oldKeyRes2 = RegOpenKeyEx(HKEY_LOCAL_MACHINE, oldKeyStr2.toStdWString().c_str(), 0, KEY_READ, &oldKey2); - - bool existNew1 = (newKeyRes1 == ERROR_SUCCESS) && (RegQueryValueEx(newKey1, L"InstallDate", 0, &checkType, (BYTE*)checkStr, &checkSize) == ERROR_SUCCESS); checkSize = bufSize * 2; - bool existNew2 = (newKeyRes2 == ERROR_SUCCESS) && (RegQueryValueEx(newKey2, L"InstallDate", 0, &checkType, (BYTE*)checkStr, &checkSize) == ERROR_SUCCESS); checkSize = bufSize * 2; - bool existOld1 = (oldKeyRes1 == ERROR_SUCCESS) && (RegQueryValueEx(oldKey1, L"InstallDate", 0, &checkType, (BYTE*)checkStr, &checkSize) == ERROR_SUCCESS); checkSize = bufSize * 2; - bool existOld2 = (oldKeyRes2 == ERROR_SUCCESS) && (RegQueryValueEx(oldKey2, L"InstallDate", 0, &checkType, (BYTE*)checkStr, &checkSize) == ERROR_SUCCESS); checkSize = bufSize * 2; - - if (newKeyRes1 == ERROR_SUCCESS) RegCloseKey(newKey1); - if (newKeyRes2 == ERROR_SUCCESS) RegCloseKey(newKey2); - if (oldKeyRes1 == ERROR_SUCCESS) RegCloseKey(oldKey1); - if (oldKeyRes2 == ERROR_SUCCESS) RegCloseKey(oldKey2); - - if (existNew1 || existNew2) { - oldKeyRes1 = existOld1 ? RegDeleteKey(HKEY_LOCAL_MACHINE, oldKeyStr1.toStdWString().c_str()) : ERROR_SUCCESS; - oldKeyRes2 = existOld2 ? RegDeleteKey(HKEY_LOCAL_MACHINE, oldKeyStr2.toStdWString().c_str()) : ERROR_SUCCESS; - } - - QString userDesktopLnk, commonDesktopLnk; - WCHAR userDesktopFolder[MAX_PATH], commonDesktopFolder[MAX_PATH]; - HRESULT userDesktopRes = SHGetFolderPath(0, CSIDL_DESKTOPDIRECTORY, 0, SHGFP_TYPE_CURRENT, userDesktopFolder); - HRESULT commonDesktopRes = SHGetFolderPath(0, CSIDL_COMMON_DESKTOPDIRECTORY, 0, SHGFP_TYPE_CURRENT, commonDesktopFolder); - if (SUCCEEDED(userDesktopRes)) { - userDesktopLnk = QString::fromWCharArray(userDesktopFolder) + "\\Telegram.lnk"; - } - if (SUCCEEDED(commonDesktopRes)) { - commonDesktopLnk = QString::fromWCharArray(commonDesktopFolder) + "\\Telegram.lnk"; - } - QFile userDesktopFile(userDesktopLnk), commonDesktopFile(commonDesktopLnk); - if (QFile::exists(userDesktopLnk) && QFile::exists(commonDesktopLnk) && userDesktopLnk != commonDesktopLnk) { - bool removed = QFile::remove(commonDesktopLnk); - } - } catch (...) { - }*/ -} - -int psFixPrevious() { - /*__try - { - psDoFixPrevious(); - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - return 0; - }*/ - return 0; -} - -bool psCheckReadyUpdate() { - /*QString readyPath = cWorkingDir() + qsl("tupdates/ready"); - if (!QDir(readyPath).exists()) { - return false; - } - - // check ready version - QString versionPath = readyPath + qsl("/tdata/version"); - { - QFile fVersion(versionPath); - if (!fVersion.open(QIODevice::ReadOnly)) { - LOG(("Update Error: cant read version file '%1'").arg(versionPath)); - PsUpdateDownloader::clearAll(); - return false; - } - DWORD versionNum; - if (fVersion.read((char*)&versionNum, sizeof(DWORD)) != sizeof(DWORD)) { - LOG(("Update Error: cant read version from file '%1'").arg(versionPath)); - PsUpdateDownloader::clearAll(); - return false; - } - fVersion.close(); - if (versionNum <= AppVersion) { - LOG(("Update Error: cant install version %1 having version %2").arg(versionNum).arg(AppVersion)); - PsUpdateDownloader::clearAll(); - return false; - } - } - - QString curUpdater = (cExeDir() + "Updater.exe"); - QFileInfo updater(cWorkingDir() + "tupdates/ready/Updater.exe"); - if (!updater.exists()) { - QFileInfo current(curUpdater); - if (!current.exists()) { - PsUpdateDownloader::clearAll(); - return false; - } - if (CopyFile(current.absoluteFilePath().toStdWString().c_str(), updater.absoluteFilePath().toStdWString().c_str(), TRUE) == FALSE) { - PsUpdateDownloader::clearAll(); - return false; - } - } - if (CopyFile(updater.absoluteFilePath().toStdWString().c_str(), curUpdater.toStdWString().c_str(), FALSE) == FALSE) { - PsUpdateDownloader::clearAll(); - return false; - } - if (DeleteFile(updater.absoluteFilePath().toStdWString().c_str()) == FALSE) { - PsUpdateDownloader::clearAll(); - return false; - }*/ - return false; // TODO -} - -void psPostprocessFile(const QString &name) { - /*std::wstring zoneFile = QDir::toNativeSeparators(name).toStdWString() + L":Zone.Identifier"; - HANDLE f = CreateFile(zoneFile.c_str(), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); - if (f == INVALID_HANDLE_VALUE) { // :( - return; - } - - const char data[] = "[ZoneTransfer]\r\nZoneId=3\r\n"; - - DWORD written = 0; - BOOL result = WriteFile(f, data, sizeof(data), &written, NULL); - CloseHandle(f); - - if (!result || written != sizeof(data)) { // :( - return; - }*/ -} - -void psOpenFile(const QString &name, bool openWith) { - /*std::wstring wname = QDir::toNativeSeparators(name).toStdWString(); - - if (openWith && useOpenAs) { - if (shOpenWithDialog) { - OPENASINFO info; - info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_REGISTER_EXT | OAIF_EXEC; - info.pcszClass = NULL; - info.pcszFile = wname.c_str(); - shOpenWithDialog(0, &info); - } else { - openAs_RunDLL(0, 0, wname.c_str(), SW_SHOWNORMAL); - } - } else { - ShellExecute(0, L"open", wname.c_str(), 0, 0, SW_SHOWNORMAL); - }*/ -} - -void psShowInFolder(const QString &name) { - //QString nameEscaped = QDir::toNativeSeparators(name).replace('"', qsl("\"\"")); - //ShellExecute(0, 0, qsl("explorer").toStdWString().c_str(), (qsl("/select,") + nameEscaped).toStdWString().c_str(), 0, SW_SHOWNORMAL); -} - -void psExecUpdater() { - /*QString targs = qsl("-update"); - if (cFromAutoStart()) targs += qsl(" -autostart"); - if (cDebug()) targs += qsl(" -debug"); - - QString updater(QDir::toNativeSeparators(cExeDir() + "Updater.exe")), wdir(QDir::toNativeSeparators(cWorkingDir())); - - DEBUG_LOG(("Application Info: executing %1 %2").arg(cExeDir() + "Updater.exe").arg(targs)); - HINSTANCE r = ShellExecute(0, 0, updater.toStdWString().c_str(), targs.toStdWString().c_str(), wdir.isEmpty() ? 0 : wdir.toStdWString().c_str(), SW_SHOWNORMAL); - if (long(r) < 32) { - DEBUG_LOG(("Application Error: failed to execute %1, working directory: '%2', result: %3").arg(updater).arg(wdir).arg(long(r))); - QString readyPath = cWorkingDir() + qsl("tupdates/ready"); - PsUpdateDownloader::deleteDir(readyPath); - }*/ -} - -void psExecTelegram() { - /*QString targs = qsl("-noupdate -tosettings"); - if (cFromAutoStart()) targs += qsl(" -autostart"); - if (cDebug()) targs += qsl(" -debug"); - if (cDataFile() != (cTestMode() ? qsl("data_test") : qsl("data"))) targs += qsl(" -key \"") + cDataFile() + '"'; - - QString telegram(QDir::toNativeSeparators(cExeDir() + "Telegram.exe")), wdir(QDir::toNativeSeparators(cWorkingDir())); - - DEBUG_LOG(("Application Info: executing %1 %2").arg(cExeDir() + "Telegram.exe").arg(targs)); - HINSTANCE r = ShellExecute(0, 0, telegram.toStdWString().c_str(), targs.toStdWString().c_str(), wdir.isEmpty() ? 0 : wdir.toStdWString().c_str(), SW_SHOWNORMAL); - if (long(r) < 32) { - DEBUG_LOG(("Application Error: failed to execute %1, working directory: '%2', result: %3").arg(telegram).arg(wdir).arg(long(r))); - }*/ -} - -void psAutoStart(bool start, bool silent) { - /*WCHAR startupFolder[MAX_PATH]; - HRESULT hres = SHGetFolderPath(0, CSIDL_STARTUP, 0, SHGFP_TYPE_CURRENT, startupFolder); - if (SUCCEEDED(hres)) { - QString lnk = QString::fromWCharArray(startupFolder) + "\\Telegram.lnk"; - if (start) { - IShellLink* psl; - hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); - if (SUCCEEDED(hres)) { - IPersistFile* ppf; - - QString exe = QDir::toNativeSeparators(QDir(cExeDir()).absolutePath() + "//Telegram.exe"), dir = QDir::toNativeSeparators(QDir(cWorkingDir()).absolutePath()); - psl->SetArguments(L"-autostart"); - psl->SetPath(exe.toStdWString().c_str()); - psl->SetWorkingDirectory(dir.toStdWString().c_str()); - psl->SetDescription(L"Telegram autorun link.\nYou can disable autorun in Telegram settings."); - - hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf); - - if (SUCCEEDED(hres)) { - hres = ppf->Save(lnk.toStdWString().c_str(), TRUE); - ppf->Release(); - } else { - if (!silent) LOG(("App Error: could not create interface IID_IPersistFile %1").arg(hres)); - } - psl->Release(); - } else { - if (!silent) LOG(("App Error: could not create instance of IID_IShellLink %1").arg(hres)); - } - } else { - QFile::remove(lnk); - } - } else { - if (!silent) LOG(("App Error: could not get CSIDL_STARTUP folder %1").arg(hres)); - }*/ -} diff --git a/Telegram/SourceFiles/pspecific_wnd.cpp b/Telegram/SourceFiles/pspecific_wnd.cpp index 93660eeb0..532fde78b 100644 --- a/Telegram/SourceFiles/pspecific_wnd.cpp +++ b/Telegram/SourceFiles/pspecific_wnd.cpp @@ -868,8 +868,6 @@ PsMainWindow::PsMainWindow(QWidget *parent) : QMainWindow(parent), ps_hWnd(0), p icon32 = icon256.scaledToWidth(32, Qt::SmoothTransformation); connect(&psIdleTimer, SIGNAL(timeout()), this, SLOT(psIdleTimeout())); psIdleTimer.setSingleShot(false); - connect(¬ifyWaitTimer, SIGNAL(timeout()), this, SLOT(psNotifyFire())); - notifyWaitTimer.setSingleShot(true); } void PsMainWindow::psNotIdle() const { @@ -1388,506 +1386,41 @@ PsMainWindow::~PsMainWindow() { if (ps_menu) DestroyMenu(ps_menu); psDestroyIcons(); _psShadowWindows.destroy(); - psClearNotifyFast(); if (ps_tbHider_hWnd) DestroyWindow(ps_tbHider_hWnd); } -void PsMainWindow::psNotify(History *history, MsgId msgId) { - if (App::quiting() || !history->currentNotification()) return; - - bool haveSetting = (history->peer->notify != UnknownNotifySettings); - if (haveSetting) { - if (history->peer->notify != EmptyNotifySettings && history->peer->notify->mute > unixtime()) { - history->clearNotifications(); - return; - } - } else { - App::wnd()->getNotifySetting(MTP_inputNotifyPeer(history->peer->input)); - } - - uint64 ms = getms() + NotifyWaitTimeout; - notifyWhenAlerts[history].insert(ms); - if (cDesktopNotify()) { - NotifyWhenMaps::iterator i = notifyWhenMaps.find(history); - if (i == notifyWhenMaps.end()) { - i = notifyWhenMaps.insert(history, NotifyWhenMap()); - } - if (i.value().constFind(msgId) == i.value().cend()) { - i.value().insert(msgId, ms); - } - NotifyWaiters *addTo = haveSetting ? ¬ifyWaiters : ¬ifySettingWaiters; - if (addTo->constFind(history) == addTo->cend()) { - addTo->insert(history, NotifyWaiter(msgId, ms)); - } - } - if (haveSetting) { - if (!notifyWaitTimer.isActive()) { - notifyWaitTimer.start(NotifyWaitTimeout); - } - } -} - -void PsMainWindow::psNotifyFire() { - psShowNextNotify(); -} - -void PsMainWindow::psNotifySettingGot() { - int32 t = unixtime(); - for (NotifyWaiters::iterator i = notifySettingWaiters.begin(); i != notifySettingWaiters.end();) { - History *history = i.key(); - if (history->peer->notify == UnknownNotifySettings) { - ++i; - } else { - if (history->peer->notify == EmptyNotifySettings || history->peer->notify->mute <= t) { - notifyWaiters.insert(i.key(), i.value()); - } - i = notifySettingWaiters.erase(i); - } - } - notifyWaitTimer.stop(); - psShowNextNotify(); -} - -void PsMainWindow::psClearNotify(History *history) { - if (!history) { - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->unlinkHistory(); - } - for (NotifyWhenMaps::const_iterator i = notifyWhenMaps.cbegin(), e = notifyWhenMaps.cend(); i != e; ++i) { - i.key()->clearNotifications(); - } - notifyWaiters.clear(); - notifySettingWaiters.clear(); - notifyWhenMaps.clear(); - return; - } - notifyWaiters.remove(history); - notifySettingWaiters.remove(history); - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->unlinkHistory(history); - } - notifyWhenMaps.remove(history); - notifyWhenAlerts.remove(history); -} - -void PsMainWindow::psClearNotifyFast() { - notifyWaiters.clear(); - notifySettingWaiters.clear(); - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->deleteLater(); - } - notifyWindows.clear(); - notifyWhenMaps.clear(); - notifyWhenAlerts.clear(); -} - -// QApplication::desktop()->availableGeometry(App::wnd()) works not very fine, returns not nearest namespace { - //RECT _monitorRECT; QRect _monitorRect; - //uint32 _monitorDelta; - //int32 _wndX, _wndY; uint64 _monitorLastGot = 0; - - //BOOL CALLBACK _monitorRectProc( - //_In_ HMONITOR hMonitor, - //_In_ HDC hdcMonitor, - //_In_ LPRECT lprcMonitor, - //_In_ LPARAM dwData - //) { - // MONITORINFOEX info; - // info.cbSize = sizeof(info); - // GetMonitorInfo(hMonitor, &info); - // int32 centerx = (info.rcWork.right + info.rcWork.left) / 2, centery = (info.rcWork.bottom + info.rcWork.top) / 2; - // uint32 delta = (info.rcWork.right > _wndX && info.rcWork.left <= _wndX && info.rcWork.bottom > _wndY && info.rcWork.top <= _wndY) ? 0 : ((centerx - _wndX) * (centerx - _wndX) + (centery - _wndY) * (centery - _wndY)); - // if (delta < _monitorDelta) { - // _monitorDelta = delta; - // _monitorRECT = info.rcWork; - // } - // return !!delta; - //} - QRect _desktopRect() { - uint64 tnow = getms(); - if (tnow > _monitorLastGot + 1000 || tnow < _monitorLastGot) { - _monitorLastGot = tnow; - //RECT r; - //GetWindowRect(App::wnd()->psHwnd(), &r); - //_wndX = (r.right + r.left) / 2; - //_wndY = (r.bottom + r.top) / 2; - //_monitorDelta = INT_MAX; - //EnumDisplayMonitors(0, 0, &_monitorRectProc, 0); - //_monitorRect = (_monitorDelta < INT_MAX) ? QRect(_monitorRECT.left, _monitorRECT.top, _monitorRECT.right - _monitorRECT.left, _monitorRECT.bottom - _monitorRECT.top) : QApplication::desktop()->availableGeometry(App::wnd()); - HMONITOR hMonitor = MonitorFromWindow(App::wnd()->psHwnd(), MONITOR_DEFAULTTONEAREST); - if (hMonitor) { - MONITORINFOEX info; - info.cbSize = sizeof(info); - GetMonitorInfo(hMonitor, &info); - _monitorRect = QRect(info.rcWork.left, info.rcWork.top, info.rcWork.right - info.rcWork.left, info.rcWork.bottom - info.rcWork.top); - } else { - _monitorRect = QApplication::desktop()->availableGeometry(App::wnd()); - } - } - return _monitorRect; - } } -void PsMainWindow::psShowNextNotify(PsNotifyWindow *remove) { - if (App::quiting()) return; - - int32 count = NotifyWindows; - if (remove) { - for (PsNotifyWindows::iterator i = notifyWindows.begin(), e = notifyWindows.end(); i != e; ++i) { - if ((*i) == remove) { - notifyWindows.erase(i); - break; - } - } - } - - uint64 ms = getms(), nextAlert = 0; - bool alert = false; - for (NotifyWhenAlerts::iterator i = notifyWhenAlerts.begin(); i != notifyWhenAlerts.end();) { - while (!i.value().isEmpty() && *i.value().begin() <= ms) { - i.value().erase(i.value().begin()); - NotifySettingsPtr n = i.key()->peer->notify; - if (n == EmptyNotifySettings || n != UnknownNotifySettings && n->mute <= unixtime()) { - alert = true; - } - } - if (i.value().isEmpty()) { - i = notifyWhenAlerts.erase(i); +QRect psDesktopRect() { + uint64 tnow = getms(); + if (tnow > _monitorLastGot + 1000 || tnow < _monitorLastGot) { + _monitorLastGot = tnow; + HMONITOR hMonitor = MonitorFromWindow(App::wnd()->psHwnd(), MONITOR_DEFAULTTONEAREST); + if (hMonitor) { + MONITORINFOEX info; + info.cbSize = sizeof(info); + GetMonitorInfo(hMonitor, &info); + _monitorRect = QRect(info.rcWork.left, info.rcWork.top, info.rcWork.right - info.rcWork.left, info.rcWork.bottom - info.rcWork.top); } else { - if (!nextAlert || nextAlert > *i.value().begin()) { - nextAlert = *i.value().begin(); - } - ++i; + _monitorRect = QApplication::desktop()->availableGeometry(App::wnd()); } } - if (alert) { - psFlash(); - App::playSound(); - } - - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - int32 ind = (*i)->index(); - if (ind < 0) continue; - --count; - } - if (count <= 0 || !cDesktopNotify()) { - if (nextAlert) { - notifyWaitTimer.start(nextAlert - ms); - } - return; - } - - QRect r = _desktopRect(); - int32 x = r.x() + r.width() - st::notifyWidth - st::notifyDeltaX, y = r.y() + r.height() - st::notifyHeight - st::notifyDeltaY; - while (count > 0) { - uint64 next = 0; - HistoryItem *notifyItem = 0; - NotifyWaiters::iterator notifyWaiter; - for (NotifyWaiters::iterator i = notifyWaiters.begin(); i != notifyWaiters.end(); ++i) { - History *history = i.key(); - if (history->currentNotification() && history->currentNotification()->id != i.value().msg) { - NotifyWhenMaps::iterator j = notifyWhenMaps.find(history); - if (j == notifyWhenMaps.end()) { - history->clearNotifications(); - i = notifyWaiters.erase(i); - continue; - } - do { - NotifyWhenMap::const_iterator k = j.value().constFind(history->currentNotification()->id); - if (k != j.value().cend()) { - i.value().msg = k.key(); - i.value().when = k.value(); - break; - } - history->skipNotification(); - } while (history->currentNotification()); - } - if (!history->currentNotification()) { - notifyWhenMaps.remove(history); - i = notifyWaiters.erase(i); - continue; - } - uint64 when = i.value().when; - if (!notifyItem || next > when) { - next = when; - notifyItem = history->currentNotification(); - notifyWaiter = i; - } - } - if (notifyItem) { - if (next > ms) { - if (nextAlert && nextAlert < next) { - next = nextAlert; - nextAlert = 0; - } - notifyWaitTimer.start(next - ms); - break; - } else { - notifyWindows.push_back(new PsNotifyWindow(notifyItem, x, y)); - --count; - - uint64 ms = getms(); - History *history = notifyItem->history(); - history->skipNotification(); - NotifyWhenMaps::iterator j = notifyWhenMaps.find(history); - if (j == notifyWhenMaps.end() || !history->currentNotification()) { - history->clearNotifications(); - notifyWaiters.erase(notifyWaiter); - if (j != notifyWhenMaps.end()) notifyWhenMaps.erase(j); - continue; - } - j.value().remove(notifyItem->id); - do { - NotifyWhenMap::const_iterator k = j.value().constFind(history->currentNotification()->id); - if (k != j.value().cend()) { - notifyWaiter.value().msg = k.key(); - notifyWaiter.value().when = k.value(); - break; - } - history->skipNotification(); - } while (history->currentNotification()); - if (!history->currentNotification()) { - notifyWaiters.erase(notifyWaiter); - notifyWhenMaps.erase(j); - continue; - } - } - } else { - break; - } - } - if (nextAlert) { - notifyWaitTimer.start(nextAlert - ms); - } - - count = NotifyWindows - count; - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - int32 ind = (*i)->index(); - if (ind < 0) continue; - --count; - (*i)->moveTo(x, y - count * (st::notifyHeight + st::notifyDeltaY)); - } + return _monitorRect; } -void PsMainWindow::psStopHiding() { - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->stopHiding(); - } +void PsMainWindow::psActivateNotify(NotifyWindow *w) { } -void PsMainWindow::psStartHiding() { - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->startHiding(); - } +void PsMainWindow::psClearNotifies(PeerId peerId) { } -void PsMainWindow::psUpdateNotifies() { - for (PsNotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->updatePeerPhoto(); - } +void PsMainWindow::psNotifyShown(NotifyWindow *w) { } -PsNotifyWindow::PsNotifyWindow(HistoryItem *item, int32 x, int32 y) : history(item->history()), aOpacity(0), _index(0), hiding(false), started(GetTickCount()), - alphaDuration(st::notifyFastAnim), posDuration(st::notifyFastAnim), aY(y + st::notifyHeight + st::notifyDeltaY), close(this, st::notifyClose), aOpacityFunc(st::notifyFastAnimFunc) { - - int32 w = st::notifyWidth, h = st::notifyHeight; - QImage img(w, h, QImage::Format_ARGB32_Premultiplied); - img.fill(st::notifyBG->c); - - { - QPainter p(&img); - p.setPen(st::notifyBorder->p); - p.setBrush(Qt::NoBrush); - p.drawRect(0, 0, w - 1, h - 1); - - if (history->peer->photo->loaded()) { - p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), history->peer->photo->pix(st::notifyPhotoSize)); - } else { - MTP::clearLoaderPriorities(); - peerPhoto = history->peer->photo; - peerPhoto->load(true, true); - } - - int32 itemWidth = w - st::notifyPhotoPos.x() - st::notifyPhotoSize - st::notifyTextLeft - st::notifyClosePos.x() - st::notifyClose.width; - - QRect rectForName(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyTextTop, itemWidth, st::msgNameFont->height); - if (history->peer->chat) { - p.drawPixmap(QPoint(rectForName.left() + st::dlgChatImgLeft, rectForName.top() + st::dlgChatImgTop), App::sprite(), st::dlgChatImg); - rectForName.setLeft(rectForName.left() + st::dlgChatImgSkip); - } - - QDateTime now(QDateTime::currentDateTime()), lastTime(item->date); - QDate nowDate(now.date()), lastDate(lastTime.date()); - QString dt = lastTime.toString(qsl("hh:mm")); - int32 dtWidth = st::dlgHistFont->m.width(dt); - rectForName.setWidth(rectForName.width() - dtWidth - st::dlgDateSkip); - p.setFont(st::dlgDateFont->f); - p.setPen(st::dlgDateColor->p); - p.drawText(rectForName.left() + rectForName.width() + st::dlgDateSkip, rectForName.top() + st::dlgHistFont->ascent, dt); - - const HistoryItem *textCachedFor = 0; - Text itemTextCache(itemWidth); - bool active = false; - item->drawInDialog(p, QRect(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height, itemWidth, 2 * st::dlgFont->height), active, textCachedFor, itemTextCache); - - p.setPen(st::dlgNameColor->p); - history->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); - } - pm = QPixmap::fromImage(img); - - hideTimer.setSingleShot(true); - connect(&hideTimer, SIGNAL(timeout()), this, SLOT(hideByTimer())); - - inputTimer.setSingleShot(true); - connect(&inputTimer, SIGNAL(timeout()), this, SLOT(checkLastInput())); - - connect(&close, SIGNAL(clicked()), this, SLOT(unlinkHistory())); - close.setAcceptBoth(true); - close.move(w - st::notifyClose.width - st::notifyClosePos.x(), st::notifyClosePos.y()); - close.show(); - - aY.start(y); - setGeometry(x, aY.current(), st::notifyWidth, st::notifyHeight); - - aOpacity.start(1); - setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint); - - show(); - - setWindowOpacity(aOpacity.current()); - - alphaDuration = posDuration = st::notifyFastAnim; - anim::start(this); - - checkLastInput(); -} - -void PsNotifyWindow::checkLastInput() { - LASTINPUTINFO lii; - lii.cbSize = sizeof(LASTINPUTINFO); - BOOL res = GetLastInputInfo(&lii); - if (!res || lii.dwTime >= started) { - hideTimer.start(st::notifyWaitLongHide); - } else { - inputTimer.start(300); - } -} - -void PsNotifyWindow::moveTo(int32 x, int32 y, int32 index) { - if (index >= 0) { - _index = index; - } - move(x, aY.current()); - aY.start(y); - aOpacity.restart(); - posDuration = st::notifyFastAnim; - anim::start(this); -} - -void PsNotifyWindow::updatePeerPhoto() { - if (!peerPhoto->isNull() && peerPhoto->loaded()) { - QImage img(pm.toImage()); - { - QPainter p(&img); - p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), peerPhoto->pix(st::notifyPhotoSize)); - } - peerPhoto = ImagePtr(); - pm = QPixmap::fromImage(img); - update(); - } -} - -void PsNotifyWindow::unlinkHistory(History *hist) { - if (!hist || hist == history) { - animHide(st::notifyFastAnim, st::notifyFastAnimFunc); - history = 0; - App::wnd()->psShowNextNotify(); - } -} - -void PsNotifyWindow::enterEvent(QEvent *e) { - if (!history) return; - if (App::wnd()) App::wnd()->psStopHiding(); -} - -void PsNotifyWindow::leaveEvent(QEvent *e) { - if (!history) return; - App::wnd()->psStartHiding(); -} - -void PsNotifyWindow::startHiding() { - hideTimer.start(st::notifyWaitShortHide); -} - -void PsNotifyWindow::mousePressEvent(QMouseEvent *e) { - if (!history) return; - if (e->button() == Qt::RightButton) { - unlinkHistory(); - } else if (history) { - App::wnd()->showFromTray(); - App::wnd()->hideSettings(); - App::main()->showPeer(history->peer->id, 0, false, true); - e->ignore(); - } -} - -void PsNotifyWindow::paintEvent(QPaintEvent *e) { - QPainter p(this); - p.drawPixmap(0, 0, pm); -} - -void PsNotifyWindow::animHide(float64 duration, anim::transition func) { - if (!history) return; - alphaDuration = duration; - aOpacityFunc = func; - aOpacity.start(0); - aY.restart(); - hiding = true; - anim::start(this); -} - -void PsNotifyWindow::stopHiding() { - if (!history) return; - alphaDuration = st::notifyFastAnim; - aOpacityFunc = st::notifyFastAnimFunc; - aOpacity.start(1); - aY.restart(); - hiding = false; - hideTimer.stop(); - anim::start(this); -} - -void PsNotifyWindow::hideByTimer() { - if (!history) return; - animHide(st::notifySlowHide, st::notifySlowHideFunc); -} - -bool PsNotifyWindow::animStep(float64 ms) { - float64 dtAlpha = ms / alphaDuration, dtPos = ms / posDuration; - if (dtAlpha >= 1) { - aOpacity.finish(); - if (hiding) { - deleteLater(); - } - } else { - aOpacity.update(dtAlpha, aOpacityFunc); - } - setWindowOpacity(aOpacity.current()); - if (dtPos >= 1) { - aY.finish(); - } else { - aY.update(dtPos, anim::linear); - } - move(x(), aY.current()); - update(); - return (dtAlpha < 1 || !hiding && dtPos < 1); -} - -PsNotifyWindow::~PsNotifyWindow() { - if (App::wnd()) App::wnd()->psShowNextNotify(this); +void PsMainWindow::psPlatformNotify(HistoryItem *item) { } PsApplication::PsApplication(int &argc, char **argv) : QApplication(argc, argv) { diff --git a/Telegram/SourceFiles/pspecific_wnd.h b/Telegram/SourceFiles/pspecific_wnd.h index cb188d63c..5dfd4341f 100644 --- a/Telegram/SourceFiles/pspecific_wnd.h +++ b/Telegram/SourceFiles/pspecific_wnd.h @@ -23,58 +23,7 @@ inline QString psServerPrefix() { inline void psCheckLocalSocket(const QString &) { } -class PsNotifyWindow : public QWidget, public Animated { - Q_OBJECT - -public: - - PsNotifyWindow(HistoryItem *item, int32 x, int32 y); - - void enterEvent(QEvent *e); - void leaveEvent(QEvent *e); - void mousePressEvent(QMouseEvent *e); - void paintEvent(QPaintEvent *e); - - bool animStep(float64 ms); - void animHide(float64 duration, anim::transition func); - void startHiding(); - void stopHiding(); - void moveTo(int32 x, int32 y, int32 index = -1); - - void updatePeerPhoto(); - - int32 index() const { - return history ? _index : -1; - } - - ~PsNotifyWindow(); - -public slots: - - void hideByTimer(); - void checkLastInput(); - - void unlinkHistory(History *hist = 0); - -private: - - DWORD started; - - History *history; - IconedButton close; - QPixmap pm; - float64 alphaDuration, posDuration; - QTimer hideTimer, inputTimer; - bool hiding; - int32 _index; - anim::fvalue aOpacity; - anim::transition aOpacityFunc; - anim::ivalue aY; - ImagePtr peerPhoto; - -}; - -typedef QList PsNotifyWindows; +class NotifyWindow; class PsMainWindow : public QMainWindow { Q_OBJECT @@ -112,18 +61,15 @@ public: return false; } - void psNotify(History *history, MsgId msgId); - void psClearNotify(History *history = 0); - void psClearNotifyFast(); - void psShowNextNotify(PsNotifyWindow *remove = 0); - void psStopHiding(); - void psStartHiding(); - void psUpdateNotifies(); - bool psPosInited() const { return posInited; } + void psActivateNotify(NotifyWindow *w); + void psClearNotifies(PeerId peerId = 0); + void psNotifyShown(NotifyWindow *w); + void psPlatformNotify(HistoryItem *item); + ~PsMainWindow(); public slots: @@ -132,7 +78,6 @@ public slots: void psUpdateCounter(); void psSavePosition(Qt::WindowState state = Qt::WindowActive); void psIdleTimeout(); - void psNotifyFire(); protected: @@ -145,26 +90,6 @@ protected: virtual void setupTrayIcon() { } - typedef QMap NotifyWhenMap; - typedef QMap NotifyWhenMaps; - NotifyWhenMaps notifyWhenMaps; - struct NotifyWaiter { - NotifyWaiter(MsgId msg, uint64 when) : msg(msg), when(when) { - } - MsgId msg; - uint64 when; - }; - typedef QMap NotifyWaiters; - NotifyWaiters notifyWaiters; - NotifyWaiters notifySettingWaiters; - QTimer notifyWaitTimer; - - typedef QSet NotifyWhenAlert; - typedef QMap NotifyWhenAlerts; - NotifyWhenAlerts notifyWhenAlerts; - - PsNotifyWindows notifyWindows; - QTimer psUpdatedPositionTimer; private: @@ -251,6 +176,8 @@ QString psAppDataPath(); QString psCurrentExeDirectory(int argc, char *argv[]); void psAutoStart(bool start, bool silent = false); +QRect psDesktopRect(); + int psCleanup(); int psFixPrevious(); diff --git a/Telegram/SourceFiles/settings.cpp b/Telegram/SourceFiles/settings.cpp index 7fd4066fc..1c100f6f8 100644 --- a/Telegram/SourceFiles/settings.cpp +++ b/Telegram/SourceFiles/settings.cpp @@ -86,6 +86,11 @@ QUrl gUpdateURL = QUrl(qsl("http://tdesktop.com/linux/tupdates/current")); #endif void settingsParseArgs(int argc, char *argv[]) { + if (cPlatform() == dbipMac) { + gCustomNotifies = false; + } else { + gCustomNotifies = true; + } memset_rand(&gInstance, sizeof(gInstance)); gExeDir = psCurrentExeDirectory(argc, argv); for (int32 i = 0; i < argc; ++i) { diff --git a/Telegram/SourceFiles/settingswidget.cpp b/Telegram/SourceFiles/settingswidget.cpp index 5fced5e7b..dd359d2ae 100644 --- a/Telegram/SourceFiles/settingswidget.cpp +++ b/Telegram/SourceFiles/settingswidget.cpp @@ -75,11 +75,7 @@ void Slider::setSelected(int32 sel) { void Slider::paintEvent(QPaintEvent *e) { QPainter p(this); - p.setPen(_st.color->p); - int32 from = (height() - _st.thikness) / 2, to = from + _st.thikness; - for (int32 i = from; i < to; ++i) { - p.drawLine(0, i, width() - 1, i); - } + p.fillRect(0, (height() - _st.thikness) / 2, width(), _st.thikness, _st.color->b); int32 x = qFloor(_sel * float64(width() - _st.bar.pxWidth()) / (_count - 1)), y = (height() - _st.bar.pxHeight()) / 2; p.drawPixmap(QPoint(x, y), App::sprite(), _st.bar); @@ -908,7 +904,7 @@ void SettingsInner::onSoundNotify() { void SettingsInner::onDesktopNotify() { cSetDesktopNotify(_desktopNotify.checked()); if (!_desktopNotify.checked()) { - App::wnd()->psClearNotify(); + App::wnd()->notifyClear(); } App::writeUserConfig(); } diff --git a/Telegram/SourceFiles/window.cpp b/Telegram/SourceFiles/window.cpp index 7d0f6e4db..3e383e113 100644 --- a/Telegram/SourceFiles/window.cpp +++ b/Telegram/SourceFiles/window.cpp @@ -76,6 +76,229 @@ void TempDirDeleter::onStart() { } } + +NotifyWindow::NotifyWindow(HistoryItem *item, int32 x, int32 y) : history(item->history()) +#ifdef Q_OS_WIN +, started(GetTickCount()) +#endif +, close(this, st::notifyClose) +, alphaDuration(st::notifyFastAnim) +, posDuration(st::notifyFastAnim) +, hiding(false) +, _index(0) +, aOpacity(0) +, aOpacityFunc(st::notifyFastAnimFunc) +, aY(y + st::notifyHeight + st::notifyDeltaY) { + + int32 w = st::notifyWidth, h = st::notifyHeight; + QImage img(w * cIntRetinaFactor(), h * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); + if (cRetina()) img.setDevicePixelRatio(cRetinaFactor()); + img.fill(st::notifyBG->c); + + { + QPainter p(&img); + p.fillRect(0, 0, w - st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder->b); + p.fillRect(w - st::notifyBorderWidth, 0, st::notifyBorderWidth, h - st::notifyBorderWidth, st::notifyBorder->b); + p.fillRect(st::notifyBorderWidth, h - st::notifyBorderWidth, w - st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder->b); + p.fillRect(0, st::notifyBorderWidth, st::notifyBorderWidth, h - st::notifyBorderWidth, st::notifyBorder->b); + + if (history->peer->photo->loaded()) { + p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), history->peer->photo->pix(st::notifyPhotoSize)); + } else { + MTP::clearLoaderPriorities(); + peerPhoto = history->peer->photo; + peerPhoto->load(true, true); + } + + int32 itemWidth = w - st::notifyPhotoPos.x() - st::notifyPhotoSize - st::notifyTextLeft - st::notifyClosePos.x() - st::notifyClose.width; + + QRect rectForName(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyTextTop, itemWidth, st::msgNameFont->height); + if (history->peer->chat) { + p.drawPixmap(QPoint(rectForName.left() + st::dlgChatImgLeft, rectForName.top() + st::dlgChatImgTop), App::sprite(), st::dlgChatImg); + rectForName.setLeft(rectForName.left() + st::dlgChatImgSkip); + } + + QDateTime now(QDateTime::currentDateTime()), lastTime(item->date); + QDate nowDate(now.date()), lastDate(lastTime.date()); + QString dt = lastTime.toString(qsl("hh:mm")); + int32 dtWidth = st::dlgHistFont->m.width(dt); + rectForName.setWidth(rectForName.width() - dtWidth - st::dlgDateSkip); + p.setFont(st::dlgDateFont->f); + p.setPen(st::dlgDateColor->p); + p.drawText(rectForName.left() + rectForName.width() + st::dlgDateSkip, rectForName.top() + st::dlgHistFont->ascent, dt); + + const HistoryItem *textCachedFor = 0; + Text itemTextCache(itemWidth); + bool active = false; + item->drawInDialog(p, QRect(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height, itemWidth, 2 * st::dlgFont->height), active, textCachedFor, itemTextCache); + + p.setPen(st::dlgNameColor->p); + history->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); + } + pm = QPixmap::fromImage(img); + + hideTimer.setSingleShot(true); + connect(&hideTimer, SIGNAL(timeout()), this, SLOT(hideByTimer())); + + inputTimer.setSingleShot(true); + connect(&inputTimer, SIGNAL(timeout()), this, SLOT(checkLastInput())); + + connect(&close, SIGNAL(clicked()), this, SLOT(unlinkHistory())); + close.setAcceptBoth(true); + close.move(w - st::notifyClose.width - st::notifyClosePos.x(), st::notifyClosePos.y()); + close.show(); + + aY.start(y); + setGeometry(x, aY.current(), st::notifyWidth, st::notifyHeight); + + aOpacity.start(1); + setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint); + setAttribute(Qt::WA_MacAlwaysShowToolWindow); + + show(); + + setWindowOpacity(aOpacity.current()); + + alphaDuration = posDuration = st::notifyFastAnim; + anim::start(this); + + checkLastInput(); +} + +void NotifyWindow::checkLastInput() { +#ifdef Q_OS_WIN + LASTINPUTINFO lii; + lii.cbSize = sizeof(LASTINPUTINFO); + BOOL res = GetLastInputInfo(&lii); + if (!res || lii.dwTime >= started) { + hideTimer.start(st::notifyWaitLongHide); + } else { + inputTimer.start(300); + } +#else + // TODO + if (true) { + hideTimer.start(st::notifyWaitLongHide); + } else { + inputTimer.start(300); + } +#endif +} + +void NotifyWindow::moveTo(int32 x, int32 y, int32 index) { + if (index >= 0) { + _index = index; + } + move(x, aY.current()); + aY.start(y); + aOpacity.restart(); + posDuration = st::notifyFastAnim; + anim::start(this); +} + +void NotifyWindow::updatePeerPhoto() { + if (!peerPhoto->isNull() && peerPhoto->loaded()) { + QImage img(pm.toImage()); + { + QPainter p(&img); + p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), peerPhoto->pix(st::notifyPhotoSize)); + } + peerPhoto = ImagePtr(); + pm = QPixmap::fromImage(img); + update(); + } +} + +void NotifyWindow::unlinkHistory(History *hist) { + if (!hist || hist == history) { + animHide(st::notifyFastAnim, st::notifyFastAnimFunc); + history = 0; + App::wnd()->notifyShowNext(); + } +} + +void NotifyWindow::enterEvent(QEvent *e) { + if (!history) return; + if (App::wnd()) App::wnd()->notifyStopHiding(); +} + +void NotifyWindow::leaveEvent(QEvent *e) { + if (!history) return; + App::wnd()->notifyStartHiding(); +} + +void NotifyWindow::startHiding() { + hideTimer.start(st::notifyWaitShortHide); +} + +void NotifyWindow::mousePressEvent(QMouseEvent *e) { + if (!history) return; + if (e->button() == Qt::RightButton) { + unlinkHistory(); + } else if (history) { + App::wnd()->showFromTray(); + App::wnd()->hideSettings(); + App::main()->showPeer(history->peer->id, 0, false, true); + e->ignore(); + } +} + +void NotifyWindow::paintEvent(QPaintEvent *e) { + QPainter p(this); + p.drawPixmap(0, 0, pm); +} + +void NotifyWindow::animHide(float64 duration, anim::transition func) { + if (!history) return; + alphaDuration = duration; + aOpacityFunc = func; + aOpacity.start(0); + aY.restart(); + hiding = true; + anim::start(this); +} + +void NotifyWindow::stopHiding() { + if (!history) return; + alphaDuration = st::notifyFastAnim; + aOpacityFunc = st::notifyFastAnimFunc; + aOpacity.start(1); + aY.restart(); + hiding = false; + hideTimer.stop(); + anim::start(this); +} + +void NotifyWindow::hideByTimer() { + if (!history) return; + animHide(st::notifySlowHide, st::notifySlowHideFunc); +} + +bool NotifyWindow::animStep(float64 ms) { + float64 dtAlpha = ms / alphaDuration, dtPos = ms / posDuration; + if (dtAlpha >= 1) { + aOpacity.finish(); + if (hiding) { + deleteLater(); + } + } else { + aOpacity.update(dtAlpha, aOpacityFunc); + } + setWindowOpacity(aOpacity.current()); + if (dtPos >= 1) { + aY.finish(); + } else { + aY.update(dtPos, anim::linear); + } + move(x(), aY.current()); + update(); + return (dtAlpha < 1 || (!hiding && dtPos < 1)); +} + +NotifyWindow::~NotifyWindow() { + if (App::wnd()) App::wnd()->notifyShowNext(this); +} + Window::Window(QWidget *parent) : PsMainWindow(parent), intro(0), main(0), settings(0), layer(0), layerBG(0), _topWidget(0), _connecting(0), _tempDeleter(0), _tempDeleterThread(0), myIcon(QPixmap::fromImage(icon256)), dragging(false), _inactivePress(false) { @@ -93,6 +316,9 @@ Window::Window(QWidget *parent) : PsMainWindow(parent), _inactiveTimer.setSingleShot(true); connect(&_inactiveTimer, SIGNAL(timeout()), this, SLOT(onInactiveTimer())); + + connect(¬ifyWaitTimer, SIGNAL(timeout()), this, SLOT(notifyFire())); + notifyWaitTimer.setSingleShot(true); } void Window::inactivePress(bool inactive) { @@ -650,7 +876,282 @@ void Window::onTempDirClearFailed() { emit tempDirClearFailed(); } +void Window::notifySchedule(History *history, MsgId msgId) { + if (App::quiting() || !history->currentNotification()) return; + + bool haveSetting = (history->peer->notify != UnknownNotifySettings); + if (haveSetting) { + if (history->peer->notify != EmptyNotifySettings && history->peer->notify->mute > unixtime()) { + history->clearNotifications(); + return; + } + } else { + App::wnd()->getNotifySetting(MTP_inputNotifyPeer(history->peer->input)); + } + + uint64 ms = getms() + NotifyWaitTimeout; + notifyWhenAlerts[history].insert(ms); + if (cDesktopNotify()) { + NotifyWhenMaps::iterator i = notifyWhenMaps.find(history); + if (i == notifyWhenMaps.end()) { + i = notifyWhenMaps.insert(history, NotifyWhenMap()); + } + if (i.value().constFind(msgId) == i.value().cend()) { + i.value().insert(msgId, ms); + } + NotifyWaiters *addTo = haveSetting ? ¬ifyWaiters : ¬ifySettingWaiters; + if (addTo->constFind(history) == addTo->cend()) { + addTo->insert(history, NotifyWaiter(msgId, ms)); + } + } + if (haveSetting) { + if (!notifyWaitTimer.isActive()) { + notifyWaitTimer.start(NotifyWaitTimeout); + } + } +} + +void Window::notifyFire() { + notifyShowNext(); +} + +void Window::notifyClear(History *history) { + if (!history) { + for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { + (*i)->unlinkHistory(); + } + psClearNotifies(); + for (NotifyWhenMaps::const_iterator i = notifyWhenMaps.cbegin(), e = notifyWhenMaps.cend(); i != e; ++i) { + i.key()->clearNotifications(); + } + notifyWaiters.clear(); + notifySettingWaiters.clear(); + notifyWhenMaps.clear(); + return; + } + notifyWaiters.remove(history); + notifySettingWaiters.remove(history); + for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { + (*i)->unlinkHistory(history); + } + psClearNotifies(history->peer->id); + notifyWhenMaps.remove(history); + notifyWhenAlerts.remove(history); +} + +void Window::notifyClearFast() { + notifyWaiters.clear(); + notifySettingWaiters.clear(); + for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { + (*i)->deleteLater(); + } + psClearNotifies(); + notifyWindows.clear(); + notifyWhenMaps.clear(); + notifyWhenAlerts.clear(); +} + +void Window::notifySettingGot() { + int32 t = unixtime(); + for (NotifyWaiters::iterator i = notifySettingWaiters.begin(); i != notifySettingWaiters.end();) { + History *history = i.key(); + if (history->peer->notify == UnknownNotifySettings) { + ++i; + } else { + if (history->peer->notify == EmptyNotifySettings || history->peer->notify->mute <= t) { + notifyWaiters.insert(i.key(), i.value()); + } + i = notifySettingWaiters.erase(i); + } + } + notifyWaitTimer.stop(); + notifyShowNext(); +} + +void Window::notifyShowNext(NotifyWindow *remove) { + if (App::quiting()) return; + + int32 count = NotifyWindowsCount; + if (remove) { + for (NotifyWindows::iterator i = notifyWindows.begin(), e = notifyWindows.end(); i != e; ++i) { + if ((*i) == remove) { + notifyWindows.erase(i); + break; + } + } + } + + uint64 ms = getms(), nextAlert = 0; + bool alert = false; + for (NotifyWhenAlerts::iterator i = notifyWhenAlerts.begin(); i != notifyWhenAlerts.end();) { + while (!i.value().isEmpty() && *i.value().begin() <= ms) { + i.value().erase(i.value().begin()); + NotifySettingsPtr n = i.key()->peer->notify; + if (n == EmptyNotifySettings || (n != UnknownNotifySettings && n->mute <= unixtime())) { + alert = true; + } + } + if (i.value().isEmpty()) { + i = notifyWhenAlerts.erase(i); + } else { + if (!nextAlert || nextAlert > *i.value().begin()) { + nextAlert = *i.value().begin(); + } + ++i; + } + } + if (alert) { + psFlash(); + App::playSound(); + } + + if (cCustomNotifies()) { + for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { + int32 ind = (*i)->index(); + if (ind < 0) continue; + --count; + } + } + if (count <= 0 || !cDesktopNotify()) { + if (nextAlert) { + notifyWaitTimer.start(nextAlert - ms); + } + return; + } + + QRect r = psDesktopRect(); + int32 x = r.x() + r.width() - st::notifyWidth - st::notifyDeltaX, y = r.y() + r.height() - st::notifyHeight - st::notifyDeltaY; + while (count > 0) { + uint64 next = 0; + HistoryItem *notifyItem = 0; + NotifyWaiters::iterator notifyWaiter; + for (NotifyWaiters::iterator i = notifyWaiters.begin(); i != notifyWaiters.end(); ++i) { + History *history = i.key(); + if (history->currentNotification() && history->currentNotification()->id != i.value().msg) { + NotifyWhenMaps::iterator j = notifyWhenMaps.find(history); + if (j == notifyWhenMaps.end()) { + history->clearNotifications(); + i = notifyWaiters.erase(i); + continue; + } + do { + NotifyWhenMap::const_iterator k = j.value().constFind(history->currentNotification()->id); + if (k != j.value().cend()) { + i.value().msg = k.key(); + i.value().when = k.value(); + break; + } + history->skipNotification(); + } while (history->currentNotification()); + } + if (!history->currentNotification()) { + notifyWhenMaps.remove(history); + i = notifyWaiters.erase(i); + continue; + } + uint64 when = i.value().when; + if (!notifyItem || next > when) { + next = when; + notifyItem = history->currentNotification(); + notifyWaiter = i; + } + } + if (notifyItem) { + if (next > ms) { + if (nextAlert && nextAlert < next) { + next = nextAlert; + nextAlert = 0; + } + notifyWaitTimer.start(next - ms); + break; + } else { + if (cCustomNotifies()) { + NotifyWindow *notify = new NotifyWindow(notifyItem, x, y); + notifyWindows.push_back(notify); + psNotifyShown(notify); + --count; + } else { + psPlatformNotify(notifyItem); + } + + + uint64 ms = getms(); + History *history = notifyItem->history(); + history->skipNotification(); + NotifyWhenMaps::iterator j = notifyWhenMaps.find(history); + if (j == notifyWhenMaps.end() || !history->currentNotification()) { + history->clearNotifications(); + notifyWaiters.erase(notifyWaiter); + if (j != notifyWhenMaps.end()) notifyWhenMaps.erase(j); + continue; + } + j.value().remove(notifyItem->id); + do { + NotifyWhenMap::const_iterator k = j.value().constFind(history->currentNotification()->id); + if (k != j.value().cend()) { + notifyWaiter.value().msg = k.key(); + notifyWaiter.value().when = k.value(); + break; + } + history->skipNotification(); + } while (history->currentNotification()); + if (!history->currentNotification()) { + notifyWaiters.erase(notifyWaiter); + notifyWhenMaps.erase(j); + continue; + } + } + } else { + break; + } + } + if (nextAlert) { + notifyWaitTimer.start(nextAlert - ms); + } + + count = NotifyWindowsCount - count; + for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { + int32 ind = (*i)->index(); + if (ind < 0) continue; + --count; + (*i)->moveTo(x, y - count * (st::notifyHeight + st::notifyDeltaY)); + } +} + +void Window::notifyStopHiding() { + if (cCustomNotifies()) { + for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { + (*i)->stopHiding(); + } + } +} + +void Window::notifyStartHiding() { + if (cCustomNotifies()) { + for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { + (*i)->startHiding(); + } + } +} + +void Window::notifyUpdateAll() { + if (cCustomNotifies()) { + for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { + (*i)->updatePeerPhoto(); + } + } +} + +void Window::notifyActivateAll() { + if (cCustomNotifies()) { + for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { + psActivateNotify(*i); + } + } +} + Window::~Window() { + notifyClearFast(); delete _tempDeleter; delete _tempDeleterThread; delete _connecting; diff --git a/Telegram/SourceFiles/window.h b/Telegram/SourceFiles/window.h index 66fca6df2..395219ceb 100644 --- a/Telegram/SourceFiles/window.h +++ b/Telegram/SourceFiles/window.h @@ -66,6 +66,61 @@ signals: }; + +class NotifyWindow : public QWidget, public Animated { + Q_OBJECT + +public: + + NotifyWindow(HistoryItem *item, int32 x, int32 y); + + void enterEvent(QEvent *e); + void leaveEvent(QEvent *e); + void mousePressEvent(QMouseEvent *e); + void paintEvent(QPaintEvent *e); + + bool animStep(float64 ms); + void animHide(float64 duration, anim::transition func); + void startHiding(); + void stopHiding(); + void moveTo(int32 x, int32 y, int32 index = -1); + + void updatePeerPhoto(); + + int32 index() const { + return history ? _index : -1; + } + + ~NotifyWindow(); + +public slots: + + void hideByTimer(); + void checkLastInput(); + + void unlinkHistory(History *hist = 0); + +private: + +#ifdef Q_OS_WIN + DWORD started; +#endif + History *history; + IconedButton close; + QPixmap pm; + float64 alphaDuration, posDuration; + QTimer hideTimer, inputTimer; + bool hiding; + int32 _index; + anim::fvalue aOpacity; + anim::transition aOpacityFunc; + anim::ivalue aY; + ImagePtr peerPhoto; + +}; + +typedef QList NotifyWindows; + class Window : public PsMainWindow { Q_OBJECT @@ -150,6 +205,16 @@ public: TempDirState tempDirState(); void tempDirDelete(); + void notifySettingGot(); + void notifySchedule(History *history, MsgId msgId); + void notifyClear(History *history = 0); + void notifyClearFast(); + void notifyShowNext(NotifyWindow *remove = 0); + void notifyStopHiding(); + void notifyStartHiding(); + void notifyUpdateAll(); + void notifyActivateAll(); + public slots: void checkHistoryActivation(int state = -1); @@ -165,6 +230,8 @@ public slots: void onTempDirCleared(); void onTempDirClearFailed(); + + void notifyFire(); signals: @@ -202,6 +269,27 @@ private: bool _inactivePress; QTimer _inactiveTimer; + typedef QMap NotifyWhenMap; + typedef QMap NotifyWhenMaps; + NotifyWhenMaps notifyWhenMaps; + struct NotifyWaiter { + NotifyWaiter(MsgId msg, uint64 when) : msg(msg), when(when) { + } + MsgId msg; + uint64 when; + }; + typedef QMap NotifyWaiters; + NotifyWaiters notifyWaiters; + NotifyWaiters notifySettingWaiters; + QTimer notifyWaitTimer; + + typedef QSet NotifyWhenAlert; + typedef QMap NotifyWhenAlerts; + NotifyWhenAlerts notifyWhenAlerts; + + NotifyWindows notifyWindows; + + }; #endif // MAINWINDOW_H diff --git a/Telegram/Telegram.plist b/Telegram/Telegram.plist index c4e8ffab3..5e8852f73 100644 --- a/Telegram/Telegram.plist +++ b/Telegram/Telegram.plist @@ -11,7 +11,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.5.5 + 0.5.6 CFBundleSignature ???? NOTE diff --git a/Telegram/Telegram.xcodeproj/project.pbxproj b/Telegram/Telegram.xcodeproj/project.pbxproj index e2b170c38..a0da74670 100644 --- a/Telegram/Telegram.xcodeproj/project.pbxproj +++ b/Telegram/Telegram.xcodeproj/project.pbxproj @@ -40,6 +40,8 @@ 06EABCC49D2EEE4076322BE7 /* moc_mtp.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 924D4939FD169BB4B8AEB1C9 /* moc_mtp.cpp */; settings = {ATTRIBUTES = (); }; }; 07055CC4194EE85B0008DEF6 /* libcrypto.a in Link Binary With Libraries */ = {isa = PBXBuildFile; fileRef = 07055CC3194EE85B0008DEF6 /* libcrypto.a */; }; 0749CE69194D723400345D61 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 07C3AF24194335ED0016CFF1 /* Images.xcassets */; }; + 07C4753B1967DF1C00CAAFE9 /* switcher.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07C475391967DF1C00CAAFE9 /* switcher.cpp */; }; + 07C4753F1967E37300CAAFE9 /* moc_switcher.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07C4753E1967E37300CAAFE9 /* moc_switcher.cpp */; }; 0A49F3A5DC0680FB31519670 /* phoneinput.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 7C8F9CA4FCE8AF8FCCCB961E /* phoneinput.cpp */; settings = {ATTRIBUTES = (); }; }; 0CB7DE9A54CC9BF86FB7B5CA /* mtp.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 6D50D70712776D7ED3B00E5C /* mtp.cpp */; settings = {ATTRIBUTES = (); }; }; 0F0FC25286E16E5F78962FEE /* moc_newgroupbox.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 69FE16874104731CE2A66E0D /* moc_newgroupbox.cpp */; settings = {ATTRIBUTES = (); }; }; @@ -241,6 +243,9 @@ 07C3AF2819433ABF0016CFF1 /* lang.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = lang.txt; path = Resources/lang.txt; sourceTree = SOURCE_ROOT; }; 07C3AF2919433ABF0016CFF1 /* style_classes.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = style_classes.txt; path = Resources/style_classes.txt; sourceTree = SOURCE_ROOT; }; 07C3AF2A19433ABF0016CFF1 /* style.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = style.txt; path = Resources/style.txt; sourceTree = SOURCE_ROOT; }; + 07C475391967DF1C00CAAFE9 /* switcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = switcher.cpp; path = SourceFiles/gui/switcher.cpp; sourceTree = SOURCE_ROOT; }; + 07C4753A1967DF1C00CAAFE9 /* switcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = switcher.h; path = SourceFiles/gui/switcher.h; sourceTree = SOURCE_ROOT; }; + 07C4753E1967E37300CAAFE9 /* moc_switcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = moc_switcher.cpp; path = GeneratedFiles/Debug/moc_switcher.cpp; sourceTree = SOURCE_ROOT; }; 08A7682548FB7E671FF03822 /* boxshadow.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = boxshadow.cpp; path = SourceFiles/gui/boxshadow.cpp; sourceTree = ""; }; 098EA7CE256AAFAE4A17EB77 /* introcode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = introcode.h; path = SourceFiles/intro/introcode.h; sourceTree = ""; }; 09FD01F2BD652EB838A296D8 /* application.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = application.h; path = SourceFiles/application.h; sourceTree = ""; }; @@ -757,6 +762,7 @@ 7C8F9CA4FCE8AF8FCCCB961E /* phoneinput.cpp */, 6E1859D714E4471E053D90C9 /* scrollarea.cpp */, 420A06A32B66D250142B4B6D /* style_core.cpp */, + 07C475391967DF1C00CAAFE9 /* switcher.cpp */, 135FD3715BFDC50AD7B00E04 /* text.cpp */, BB1602EA641643DE565005B1 /* twidget.cpp */, 85FABD67716E36CD8B3CA4FA /* animation.h */, @@ -775,6 +781,7 @@ F1B68FFCE8AE823F6D45EB06 /* phoneinput.h */, 83A36F229E897566E011B79E /* scrollarea.h */, 0FC38EE7F29EF895925A2C49 /* style_core.h */, + 07C4753A1967DF1C00CAAFE9 /* switcher.h */, 6E8FD0ED1B60D43929944CD2 /* text.h */, 507CCEEC4CBA3E3BD6EEDED1 /* twidget.h */, ); @@ -994,6 +1001,7 @@ 801973D3334D0FCA849CF485 /* Debug */ = { isa = PBXGroup; children = ( + 07C4753E1967E37300CAAFE9 /* moc_switcher.cpp */, E181C525E21A16F2D4396CA7 /* moc_application.cpp */, 3B3ED09AB00290D78CF1181B /* moc_dialogswidget.cpp */, AC9B5F6FB4B984C8D76F7AE2 /* moc_dropdown.cpp */, @@ -1360,11 +1368,13 @@ E9F1CE7F9B18C7C85A50E62D /* style_auto.cpp in Compile Sources */, EBE29731916DB43BF49FE7A4 /* aboutbox.cpp in Compile Sources */, 4426AF526AAD86D6F73CE36F /* addcontactbox.cpp in Compile Sources */, + 07C4753B1967DF1C00CAAFE9 /* switcher.cpp in Compile Sources */, 830CB6F547B8C80A569A0271 /* addparticipantbox.cpp in Compile Sources */, A0A6B97F7DBEC81004EC9461 /* confirmbox.cpp in Compile Sources */, 4FEA8F51B7BC7CAC71347A1A /* connectionbox.cpp in Compile Sources */, 298BFAB73BF182297584F96F /* contactsbox.cpp in Compile Sources */, BA41D511A9BBCA09365DF88C /* downloadpathbox.cpp in Compile Sources */, + 07C4753F1967E37300CAAFE9 /* moc_switcher.cpp in Compile Sources */, 3ABE4F9B2264F770D944106D /* emojibox.cpp in Compile Sources */, 7422A321DF80CF9FAC7CB51B /* newgroupbox.cpp in Compile Sources */, 77B998AC22A13EF3DDEE07AC /* photocropbox.cpp in Compile Sources */, @@ -1491,9 +1501,9 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 0.5.4; + CURRENT_PROJECT_VERSION = 0.5.6; DYLIB_COMPATIBILITY_VERSION = 0.5; - DYLIB_CURRENT_VERSION = 0.5.5; + DYLIB_CURRENT_VERSION = 0.5.6; FRAMEWORK_SEARCH_PATHS = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_OPTIMIZATION_LEVEL = fast; @@ -1615,10 +1625,10 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.5.4; + CURRENT_PROJECT_VERSION = 0.5.6; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 0.5; - DYLIB_CURRENT_VERSION = 0.5.5; + DYLIB_CURRENT_VERSION = 0.5.6; FRAMEWORK_SEARCH_PATHS = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; diff --git a/Telegram/Telegram.xcodeproj/qt_preprocess.mak b/Telegram/Telegram.xcodeproj/qt_preprocess.mak index 034888753..55b17c763 100644 --- a/Telegram/Telegram.xcodeproj/qt_preprocess.mak +++ b/Telegram/Telegram.xcodeproj/qt_preprocess.mak @@ -40,7 +40,7 @@ compilers: GeneratedFiles/qrc_telegram.cpp GeneratedFiles/Debug/moc_application. GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp\ GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp\ GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp\ - GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp\ + GeneratedFiles/Debug/moc_switcher.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp\ GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_addparticipantbox.cpp\ GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp\ GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_newgroupbox.cpp\ @@ -88,9 +88,9 @@ GeneratedFiles/qrc_telegram.cpp: SourceFiles/telegram.qrc \ SourceFiles/art/chatcolor2.png /usr/local/Qt-5.3.0/bin/rcc -name telegram SourceFiles/telegram.qrc -o GeneratedFiles/qrc_telegram.cpp -compiler_moc_header_make_all: GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_mainwidget.cpp GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_addparticipantbox.cpp GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_newgroupbox.cpp GeneratedFiles/Debug/moc_photocropbox.cpp GeneratedFiles/Debug/moc_photosendbox.cpp GeneratedFiles/Debug/moc_intro.cpp GeneratedFiles/Debug/moc_introcode.cpp GeneratedFiles/Debug/moc_introphone.cpp GeneratedFiles/Debug/moc_introsignup.cpp GeneratedFiles/Debug/moc_pspecific_mac.cpp +compiler_moc_header_make_all: GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_mainwidget.cpp GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp GeneratedFiles/Debug/moc_switcher.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_addparticipantbox.cpp GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_newgroupbox.cpp GeneratedFiles/Debug/moc_photocropbox.cpp GeneratedFiles/Debug/moc_photosendbox.cpp GeneratedFiles/Debug/moc_intro.cpp GeneratedFiles/Debug/moc_introcode.cpp GeneratedFiles/Debug/moc_introphone.cpp GeneratedFiles/Debug/moc_introsignup.cpp GeneratedFiles/Debug/moc_pspecific_mac.cpp compiler_moc_header_clean: - -$(DEL_FILE) GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_mainwidget.cpp GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_addparticipantbox.cpp GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_newgroupbox.cpp GeneratedFiles/Debug/moc_photocropbox.cpp GeneratedFiles/Debug/moc_photosendbox.cpp GeneratedFiles/Debug/moc_intro.cpp GeneratedFiles/Debug/moc_introcode.cpp GeneratedFiles/Debug/moc_introphone.cpp GeneratedFiles/Debug/moc_introsignup.cpp GeneratedFiles/Debug/moc_pspecific_mac.cpp + -$(DEL_FILE) GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_mainwidget.cpp GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp GeneratedFiles/Debug/moc_switcher.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_addparticipantbox.cpp GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_newgroupbox.cpp GeneratedFiles/Debug/moc_photocropbox.cpp GeneratedFiles/Debug/moc_photosendbox.cpp GeneratedFiles/Debug/moc_intro.cpp GeneratedFiles/Debug/moc_introcode.cpp GeneratedFiles/Debug/moc_introphone.cpp GeneratedFiles/Debug/moc_introsignup.cpp GeneratedFiles/Debug/moc_pspecific_mac.cpp GeneratedFiles/Debug/moc_application.cpp: ../../Libraries/QtStatic/qtbase/include/QtNetwork/QLocalSocket \ ../../Libraries/QtStatic/qtbase/include/QtNetwork/QLocalServer \ ../../Libraries/QtStatic/qtbase/include/QtNetwork/QNetworkReply \ @@ -377,6 +377,20 @@ GeneratedFiles/Debug/moc_flattextarea.cpp: ../../Libraries/QtStatic/qtbase/inclu SourceFiles/gui/flattextarea.h /usr/local/Qt-5.3.0/bin/moc $(DEFINES) -D__APPLE__ -D__GNUC__=4 -I/usr/local/Qt-5.3.0/mkspecs/macx-clang -I. -I/usr/local/Qt-5.3.0/include/QtGui/5.3.0/QtGui -I/usr/local/Qt-5.3.0/include/QtCore/5.3.0/QtCore -I/usr/local/Qt-5.3.0/include -I./SourceFiles -I./GeneratedFiles -I../../Libraries/lzma/C -I../../Libraries/libexif-0.6.20 -I/usr/local/Qt-5.3.0/include -I/usr/local/Qt-5.3.0/include/QtMultimedia -I/usr/local/Qt-5.3.0/include/QtWidgets -I/usr/local/Qt-5.3.0/include/QtNetwork -I/usr/local/Qt-5.3.0/include/QtGui -I/usr/local/Qt-5.3.0/include/QtCore -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/c++/4.2.1 -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/c++/4.2.1/backward -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/5.1/include -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include SourceFiles/gui/flattextarea.h -o GeneratedFiles/Debug/moc_flattextarea.cpp +GeneratedFiles/Debug/moc_switcher.cpp: ../../Libraries/QtStatic/qtbase/include/QtWidgets/QWidget \ + SourceFiles/gui/twidget.h \ + SourceFiles/style.h \ + GeneratedFiles/style_classes.h \ + GeneratedFiles/style_auto.h \ + SourceFiles/gui/animation.h \ + SourceFiles/types.h \ + ../../Libraries/QtStatic/qtbase/include/QtCore/QReadWriteLock \ + SourceFiles/logs.h \ + ../../Libraries/QtStatic/qtbase/include/QtCore/QTimer \ + ../../Libraries/QtStatic/qtbase/include/QtGui/QColor \ + SourceFiles/gui/switcher.h + /usr/local/Qt-5.3.0/bin/moc $(DEFINES) -D__APPLE__ -D__GNUC__=4 -I/usr/local/Qt-5.3.0/mkspecs/macx-clang -I. -I/usr/local/Qt-5.3.0/include/QtGui/5.3.0/QtGui -I/usr/local/Qt-5.3.0/include/QtCore/5.3.0/QtCore -I/usr/local/Qt-5.3.0/include -I./SourceFiles -I./GeneratedFiles -I../../Libraries/lzma/C -I../../Libraries/libexif-0.6.20 -I/usr/local/Qt-5.3.0/include -I/usr/local/Qt-5.3.0/include/QtMultimedia -I/usr/local/Qt-5.3.0/include/QtWidgets -I/usr/local/Qt-5.3.0/include/QtNetwork -I/usr/local/Qt-5.3.0/include/QtGui -I/usr/local/Qt-5.3.0/include/QtCore -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/c++/4.2.1 -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/c++/4.2.1/backward -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/5.1/include -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include SourceFiles/gui/switcher.h -o GeneratedFiles/Debug/moc_switcher.cpp + GeneratedFiles/Debug/moc_phoneinput.cpp: SourceFiles/gui/flatinput.h \ ../../Libraries/QtStatic/qtbase/include/QtWidgets/QLineEdit \ SourceFiles/style.h \