media overview multiple selection done, fixed search result delete crash

This commit is contained in:
John Preston 2014-08-21 16:18:56 +04:00
parent db7fa9ba2f
commit 8a817eb204
13 changed files with 267 additions and 83 deletions

View File

@ -241,9 +241,9 @@ lng_profile_no_media: "No media in this conversation.";
lng_profile_photo: "{count} photo »";
lng_profile_photos: "{count} photos »";
lng_profile_photos_header: "Photos overview";
lng_profile_video: "{count} videofile »";
lng_profile_videos: "{count} videofiles »";
lng_profile_videos_header: "Videofiles overview";
lng_profile_video: "{count} video file »";
lng_profile_videos: "{count} video files »";
lng_profile_videos_header: "Video files overview";
lng_profile_document: "{count} document »";
lng_profile_documents: "{count} documents »";
lng_profile_documents_header: "Documents overview";
@ -288,21 +288,27 @@ lng_action_checked_in: "{from} checked in";
lng_forwarded_from: "Forwarded from ";
lng_attach_failed: "Failed";
lng_attach_file: "File";
lng_attach_file: "Document";
lng_attach_photo: "Photo";
lng_media_type: "Media type";
lng_media_type_photos: "Photos";
lng_media_type_videos: "Video files";
lng_media_type_documents: "Documents";
lng_media_type_audios: "Voice messages";
lng_media_open_with: "Open With";
lng_media_download: "Download";
lng_media_cancel: "Cancel";
lng_media_video: "Video";
lng_media_audio: "Audio";
lng_media_video: "Video file";
lng_media_audio: "Voice message";
lng_in_dlg_photo: "Photo";
lng_in_dlg_video: "Video";
lng_in_dlg_geo: "Map";
lng_in_dlg_contact: "Contact";
lng_in_dlg_audio: "Audio";
lng_in_dlg_document: "File";
lng_in_dlg_document: "Document";
lng_send_button: "Send";
lng_message_ph: "Write a message...";

View File

@ -1303,6 +1303,20 @@ dropdownAttachPhoto: iconedButton(dropdownAttachDocument) {
icon: sprite(113px, 0px, 24px, 24px);
downIcon: sprite(113px, 0px, 24px, 24px);
}
dropdownMediaPhotos: iconedButton(dropdownAttachPhoto) {
width: 200px;
}
dropdownMediaVideos: iconedButton(dropdownMediaPhotos) {
icon: sprite(79px, 348px, 24px, 24px);
downIcon: sprite(79px, 348px, 24px, 24px);
}
dropdownMediaDocuments: iconedButton(dropdownAttachDocument) {
width: 200px;
}
dropdownMediaAudios: iconedButton(dropdownMediaDocuments) {
icon: sprite(49px, 348px, 24px, 24px);
downIcon: sprite(49px, 348px, 24px, 24px);
}
dragFont: font(28px semibold);
dragSubfont: font(20px semibold);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View File

@ -461,7 +461,7 @@ void DialogsListWidget::onItemReplaced(HistoryItem *oldItem, HistoryItem *newIte
void DialogsListWidget::onItemRemoved(HistoryItem *item) {
int wasCount = searchResults.size();
for (int i = 0; i < searchResults.size(); ++i) {
for (int i = 0; i < searchResults.size();) {
if (searchResults[i]->_item == item) {
searchResults.remove(i);
} else {

View File

@ -24,9 +24,7 @@ Copyright (c) 2014 John Preston, https://tdesktop.com
Dropdown::Dropdown(QWidget *parent) : TWidget(parent),
_hiding(false), a_opacity(0), _shadow(st::dropdownShadow) {
_width = st::dropdownPadding.left() + st::dropdownPadding.right();
_height = st::dropdownPadding.top() + st::dropdownPadding.bottom();
resize(_width, _height);
resetButtons();
_hideTimer.setSingleShot(true);
connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(hideStart()));
@ -48,6 +46,16 @@ IconedButton *Dropdown::addButton(IconedButton *button) {
return button;
}
void Dropdown::resetButtons() {
_width = st::dropdownPadding.left() + st::dropdownPadding.right();
_height = st::dropdownPadding.top() + st::dropdownPadding.bottom();
resize(_width, _height);
for (int32 i = 0, l = _buttons.size(); i < l; ++i) {
delete _buttons[i];
}
_buttons.clear();
}
void Dropdown::resizeEvent(QResizeEvent *e) {
int32 top = st::dropdownPadding.top();
for (Buttons::const_iterator i = _buttons.cbegin(), e = _buttons.cend(); i != e; ++i) {

View File

@ -28,6 +28,7 @@ public:
Dropdown(QWidget *parent);
IconedButton *addButton(IconedButton *button);
void resetButtons();
void resizeEvent(QResizeEvent *e);
void paintEvent(QPaintEvent *e);

View File

@ -126,15 +126,15 @@ struct PeerData {
class PeerLink : public ITextLink {
public:
PeerLink(const PeerData *peer) : _peer(peer) {
PeerLink(PeerData *peer) : _peer(peer) {
}
void onClick(Qt::MouseButton button) const;
const PeerData *peer() const {
PeerData *peer() const {
return _peer;
}
private:
const PeerData *_peer;
PeerData *_peer;
};
struct PhotoData;

View File

@ -241,6 +241,10 @@ void HistoryList::touchEvent(QTouchEvent *e) {
switch (e->type()) {
case QEvent::TouchBegin:
if (_menu) {
e->accept();
return; // ignore mouse press, that was hiding context menu
}
if (_touchInProgress) return;
if (e->touchPoints().isEmpty()) return;

View File

@ -34,7 +34,8 @@ TopBarWidget::TopBarWidget(MainWidget *w) : QWidget(w),
_edit(this, lang(lng_profile_edit_contact), st::topBarButton),
_leaveGroup(this, lang(lng_profile_delete_and_exit), st::topBarButton),
_addContact(this, lang(lng_profile_add_contact), st::topBarButton),
_deleteContact(this, lang(lng_profile_delete_contact), st::topBarButton) {
_deleteContact(this, lang(lng_profile_delete_contact), st::topBarButton),
_mediaType(this, lang(lng_media_type), st::topBarButton) {
connect(&_forward, SIGNAL(clicked()), this, SLOT(onForwardSelection()));
connect(&_delete, SIGNAL(clicked()), this, SLOT(onDeleteSelection()));
@ -178,6 +179,7 @@ void TopBarWidget::resizeEvent(QResizeEvent *e) {
if (!_leaveGroup.isHidden()) _leaveGroup.move(r -= _leaveGroup.width(), 0);
if (!_edit.isHidden()) _edit.move(r -= _edit.width(), 0);
if (!_addContact.isHidden()) _addContact.move(r -= _addContact.width(), 0);
if (!_mediaType.isHidden()) _mediaType.move(r -= _mediaType.width(), 0);
}
void TopBarWidget::startAnim() {
@ -188,6 +190,7 @@ void TopBarWidget::startAnim() {
_clearSelection.hide();
_delete.hide();
_forward.hide();
_mediaType.hide();
_animating = true;
}
@ -226,6 +229,7 @@ void TopBarWidget::showAll() {
_clearSelection.hide();
_delete.hide();
_forward.hide();
_mediaType.hide();
} else {
_edit.hide();
_leaveGroup.hide();
@ -235,10 +239,16 @@ void TopBarWidget::showAll() {
_clearSelection.show();
_delete.show();
_forward.show();
_mediaType.hide();
} else {
_clearSelection.hide();
_delete.hide();
_forward.hide();
if (App::main() && App::main()->mediaTypeSwitch()) {
_mediaType.show();
} else {
_mediaType.hide();
}
}
}
resizeEvent(0);
@ -253,13 +263,17 @@ void TopBarWidget::showSelected(uint32 selCount) {
showAll();
}
FlatButton *TopBarWidget::mediaTypeButton() {
return &_mediaType;
}
MainWidget *TopBarWidget::main() {
return static_cast<MainWidget*>(parentWidget());
}
MainWidget::MainWidget(Window *window) : QWidget(window), failedObjId(0), _dialogsWidth(st::dlgMinWidth),
dialogs(this), history(this), profile(0), overview(0), _topBar(this), hider(0),
updPts(0), updDate(0), updQts(0), updSeq(0), updInited(false), onlineRequest(0) {
dialogs(this), history(this), profile(0), overview(0), _topBar(this), hider(0), _mediaType(this), _mediaTypeMask(0),
updPts(0), updDate(0), updQts(0), updSeq(0), updInited(false), onlineRequest(0) {
setGeometry(QRect(0, st::titleHeight, App::wnd()->width(), App::wnd()->height() - st::titleHeight));
connect(window, SIGNAL(resized(const QSize &)), this, SLOT(onParentResize(const QSize &)));
@ -286,9 +300,13 @@ MainWidget::MainWidget(Window *window) : QWidget(window), failedObjId(0), _dialo
_topBar.raise();
dialogs.raise();
_mediaType.raise();
MTP::setGlobalFailHandler(rpcFail(&MainWidget::updateFail));
_mediaType.hide();
_topBar.mediaTypeButton()->installEventFilter(&_mediaType);
show();
setFocus();
}
@ -639,7 +657,35 @@ void MainWidget::overviewPreloaded(PeerData *peer, const MTPmessages_Messages &r
void MainWidget::mediaOverviewUpdated(PeerData *peer) {
if (profile) profile->mediaOverviewUpdated(peer);
if (overview) overview->mediaOverviewUpdated(peer);
if (overview && overview->peer() == peer) {
overview->mediaOverviewUpdated(peer);
int32 mask = 0;
History *h = peer ? App::historyLoaded(peer->id) : 0;
if (h) {
for (int32 i = 0; i < OverviewCount; ++i) {
if (!h->_overview[i].isEmpty() || h->_overviewCount[i] > 0 || i == overview->type()) {
mask |= (1 << i);
}
}
}
if (mask != _mediaTypeMask) {
_mediaType.resetButtons();
for (int32 i = 0; i < OverviewCount; ++i) {
if (mask & (1 << i)) {
switch (i) {
case OverviewPhotos: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaPhotos, lang(lng_media_type_photos))), SIGNAL(clicked()), this, SLOT(onPhotosSelect())); break;
case OverviewVideos: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaVideos, lang(lng_media_type_videos))), SIGNAL(clicked()), this, SLOT(onVideosSelect())); break;
case OverviewDocuments: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaDocuments, lang(lng_media_type_documents))), SIGNAL(clicked()), this, SLOT(onDocumentsSelect())); break;
case OverviewAudios: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaAudios, lang(lng_media_type_audios))), SIGNAL(clicked()), this, SLOT(onAudiosSelect())); break;
}
}
}
_mediaTypeMask = mask;
_mediaType.move(width() - _mediaType.width(), st::topBarHeight);
overview->updateTopBarSelection();
}
}
}
void MainWidget::changingMsgId(HistoryItem *row, MsgId newId) {
@ -982,7 +1028,18 @@ PeerData *MainWidget::profilePeer() {
return profile ? profile->peer() : 0;
}
void MainWidget::showMediaOverview(const PeerData *peer, MediaOverviewType type, bool back, int32 lastScrollTop) {
bool MainWidget::mediaTypeSwitch() {
if (!overview) return false;
for (int32 i = 0; i < OverviewCount; ++i) {
if (!(_mediaTypeMask & ~(1 << i))) {
return false;
}
}
return true;
}
void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool back, int32 lastScrollTop) {
App::wnd()->hideSettings();
if (overview && overview->peer() == peer) {
if (overview->type() != type) {
@ -1018,6 +1075,8 @@ void MainWidget::showMediaOverview(const PeerData *peer, MediaOverviewType type,
profile = 0;
}
overview = new OverviewWidget(this, peer, type);
_mediaTypeMask = 0;
mediaOverviewUpdated(peer);
_topBar.show();
resizeEvent(0);
overview->animShow(animCache, animTopBarCache, back, lastScrollTop);
@ -1026,10 +1085,11 @@ void MainWidget::showMediaOverview(const PeerData *peer, MediaOverviewType type,
history.hide();
_topBar.raise();
dialogs.raise();
_mediaType.raise();
if (hider) hider->raise();
}
void MainWidget::showPeerProfile(const PeerData *peer, bool back, int32 lastScrollTop, bool allMediaShown) {
void MainWidget::showPeerProfile(PeerData *peer, bool back, int32 lastScrollTop, bool allMediaShown) {
App::wnd()->hideSettings();
if (profile && profile->peer() == peer) return;
@ -1068,6 +1128,7 @@ void MainWidget::showPeerProfile(const PeerData *peer, bool back, int32 lastScro
history.hide();
_topBar.raise();
dialogs.raise();
_mediaType.raise();
if (hider) hider->raise();
}
@ -1338,6 +1399,7 @@ void MainWidget::hideAll() {
overview->hide();
}
_topBar.hide();
_mediaType.hide();
}
void MainWidget::showAll() {
@ -1360,6 +1422,7 @@ void MainWidget::resizeEvent(QResizeEvent *e) {
int32 tbh = _topBar.isHidden() ? 0 : st::topBarHeight;
dialogs.setGeometry(0, 0, _dialogsWidth + st::dlgShadow, height());
_topBar.setGeometry(_dialogsWidth, 0, width() - _dialogsWidth, st::topBarHeight + st::titleShadow);
_mediaType.move(width() - _mediaType.width(), st::topBarHeight);
history.setGeometry(_dialogsWidth, tbh, width() - _dialogsWidth, height() - tbh);
if (profile) profile->setGeometry(history.geometry());
if (overview) overview->setGeometry(history.geometry());
@ -1379,6 +1442,26 @@ void MainWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth) {
}
}
void MainWidget::onPhotosSelect() {
if (overview) overview->switchType(OverviewPhotos);
_mediaType.hideStart();
}
void MainWidget::onVideosSelect() {
if (overview) overview->switchType(OverviewVideos);
_mediaType.hideStart();
}
void MainWidget::onDocumentsSelect() {
if (overview) overview->switchType(OverviewDocuments);
_mediaType.hideStart();
}
void MainWidget::onAudiosSelect() {
if (overview) overview->switchType(OverviewAudios);
_mediaType.hideStart();
}
TopBarWidget *MainWidget::topBar() {
return &_topBar;
}

View File

@ -50,6 +50,8 @@ public:
void showAll();
void showSelected(uint32 selCount);
FlatButton *mediaTypeButton();
public slots:
void onForwardSelection();
@ -81,6 +83,7 @@ private:
FlatButton _clearSelection;
FlatButton _forward, _delete;
FlatButton _edit, _leaveGroup, _addContact, _deleteContact;
FlatButton _mediaType;
};
@ -204,8 +207,9 @@ public:
PeerData *activePeer();
MsgId activeMsgId();
PeerData *profilePeer();
void showPeerProfile(const PeerData *peer, bool back = false, int32 lastScrollTop = -1, bool allMediaShown = false);
void showMediaOverview(const PeerData *peer, MediaOverviewType type, bool back = false, int32 lastScrollTop = -1);
bool mediaTypeSwitch();
void showPeerProfile(PeerData *peer, bool back = false, int32 lastScrollTop = -1, bool allMediaShown = false);
void showMediaOverview(PeerData *peer, MediaOverviewType type, bool back = false, int32 lastScrollTop = -1);
void showBackFromStack();
QRect historyRect() const;
@ -316,6 +320,11 @@ public slots:
void onUpdateNotifySettings();
void onPhotosSelect();
void onVideosSelect();
void onDocumentsSelect();
void onAudiosSelect();
private:
void partWasRead(PeerData *peer, const MTPmessages_AffectedHistory &result);
@ -360,6 +369,9 @@ private:
StackItems _stack;
QPixmap profileAnimCache;
Dropdown _mediaType;
int32 _mediaTypeMask;
int updPts, updDate, updQts, updSeq;
bool updInited;
QTimer noUpdatesTimer;

View File

@ -245,15 +245,17 @@ void MediaView::showPhoto(PhotoData *photo, HistoryItem *context) {
_index = -1;
_msgid = context ? context->id : 0;
for (int i = 0, l = _history->_overview[OverviewPhotos].size(); i < l; ++i) {
if (_history->_overview[OverviewPhotos].at(i) == _msgid) {
_index = i;
break;
if (_history) {
for (int i = 0, l = _history->_overview[OverviewPhotos].size(); i < l; ++i) {
if (_history->_overview[OverviewPhotos].at(i) == _msgid) {
_index = i;
break;
}
}
}
if (_history->_overviewCount[OverviewPhotos] < 0) {
loadPhotosBack();
if (_history->_overviewCount[OverviewPhotos] < 0) {
loadPhotosBack();
}
}
showPhoto(photo);

View File

@ -381,7 +381,23 @@ void OverviewInner::dragActionStart(const QPoint &screenPos, Qt::MouseButton but
if (_dragAction == NoDrag && _dragItem) {
bool afterDragSymbol = false , uponSymbol = false;
uint16 symbol = 0;
_dragAction = PrepareSelect; // start items select
if (textlnkDown()) {
_dragSymbol = symbol;
uint32 selStatus = (_dragSymbol << 16) | _dragSymbol;
if (selStatus != FullItemSel && (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel)) {
if (!_selected.isEmpty()) {
updateMsg(_selected.cbegin().key(), -1);
_selected.clear();
}
_selected.insert(_dragItem, selStatus);
_dragAction = Selecting;
updateMsg(_dragItem, _dragItemIndex);
} else {
_dragAction = PrepareSelect;
}
} else {
_dragAction = PrepareSelect; // start items select
}
}
if (!_dragItem) {
@ -831,66 +847,73 @@ void OverviewInner::onUpdateSelected() {
}
cur = textlnkDown() ? style::cur_pointer : style::cur_default;
if (_dragAction == Selecting) {
bool selectingDown = (_type == OverviewPhotos ? (_mousedItemIndex > _dragItemIndex) : (_mousedItemIndex < _dragItemIndex)) || (_mousedItemIndex == _dragItemIndex && (_type == OverviewPhotos ? (_dragStartPos.x() < m.x()) : (_dragStartPos.y() < m.y())));
MsgId dragSelFrom = _dragItem, dragSelTo = _mousedItem;
int32 dragSelFromIndex = _dragItemIndex, dragSelToIndex = _mousedItemIndex;
if (!itemHasPoint(dragSelFrom, dragSelFromIndex, _dragStartPos.x(), _dragStartPos.y())) { // maybe exclude dragSelFrom
if (selectingDown) {
if (_type == OverviewPhotos) {
if (_dragStartPos.x() >= _vsize || ((_mousedItem == dragSelFrom) && (m.x() < _dragStartPos.x() + QApplication::startDragDistance()))) {
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, 1);
if (_mousedItem == _dragItem && lnk && !_selected.isEmpty() && _selected.cbegin().value() != FullItemSel) {
bool afterSymbol = false, uponSymbol = false;
uint16 second = 0;
_selected[_dragItem] = 0;
updateDragSelection(0, -1, 0, -1, false);
} else {
bool selectingDown = (_type == OverviewPhotos ? (_mousedItemIndex > _dragItemIndex) : (_mousedItemIndex < _dragItemIndex)) || (_mousedItemIndex == _dragItemIndex && (_type == OverviewPhotos ? (_dragStartPos.x() < m.x()) : (_dragStartPos.y() < m.y())));
MsgId dragSelFrom = _dragItem, dragSelTo = _mousedItem;
int32 dragSelFromIndex = _dragItemIndex, dragSelToIndex = _mousedItemIndex;
if (!itemHasPoint(dragSelFrom, dragSelFromIndex, _dragStartPos.x(), _dragStartPos.y())) { // maybe exclude dragSelFrom
if (selectingDown) {
if (_type == OverviewPhotos) {
if (_dragStartPos.x() >= _vsize || ((_mousedItem == dragSelFrom) && (m.x() < _dragStartPos.x() + QApplication::startDragDistance()))) {
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, 1);
}
} else {
if (_dragStartPos.y() >= (itemHeight(dragSelFrom, dragSelFromIndex) - st::msgMargin.bottom()) || ((_mousedItem == dragSelFrom) && (m.y() < _dragStartPos.y() + QApplication::startDragDistance()))) {
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, -1);
}
}
} else {
if (_dragStartPos.y() >= (itemHeight(dragSelFrom, dragSelFromIndex) - st::msgMargin.bottom()) || ((_mousedItem == dragSelFrom) && (m.y() < _dragStartPos.y() + QApplication::startDragDistance()))) {
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, -1);
}
}
} else {
if (_type == OverviewPhotos) {
if (_dragStartPos.x() < 0 || ((_mousedItem == dragSelFrom) && (m.x() >= _dragStartPos.x() - QApplication::startDragDistance()))) {
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, -1);
}
} else {
if (_dragStartPos.y() < st::msgMargin.top() || ((_mousedItem == dragSelFrom) && (m.y() >= _dragStartPos.y() - QApplication::startDragDistance()))) {
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, 1);
if (_type == OverviewPhotos) {
if (_dragStartPos.x() < 0 || ((_mousedItem == dragSelFrom) && (m.x() >= _dragStartPos.x() - QApplication::startDragDistance()))) {
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, -1);
}
} else {
if (_dragStartPos.y() < st::msgMargin.top() || ((_mousedItem == dragSelFrom) && (m.y() >= _dragStartPos.y() - QApplication::startDragDistance()))) {
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, 1);
}
}
}
}
}
if (_dragItem != _mousedItem) { // maybe exclude dragSelTo
if (selectingDown) {
if (_type == OverviewPhotos) {
if (m.x() < 0) {
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, -1);
if (_dragItem != _mousedItem) { // maybe exclude dragSelTo
if (selectingDown) {
if (_type == OverviewPhotos) {
if (m.x() < 0) {
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, -1);
}
} else {
if (m.y() < st::msgMargin.top()) {
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, 1);
}
}
} else {
if (m.y() < st::msgMargin.top()) {
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, 1);
}
}
} else {
if (_type == OverviewPhotos) {
if (m.x() >= _vsize) {
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, 1);
}
} else {
if (m.y() >= itemHeight(dragSelTo, dragSelToIndex) - st::msgMargin.bottom()) {
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, -1);
if (_type == OverviewPhotos) {
if (m.x() >= _vsize) {
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, 1);
}
} else {
if (m.y() >= itemHeight(dragSelTo, dragSelToIndex) - st::msgMargin.bottom()) {
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, -1);
}
}
}
}
bool dragSelecting = false;
MsgId dragFirstAffected = dragSelFrom;
int32 dragFirstAffectedIndex = dragSelFromIndex;
while (dragFirstAffectedIndex >= 0 && dragFirstAffected <= 0) {
moveToNextItem(dragFirstAffected, dragFirstAffectedIndex, dragSelTo, ((selectingDown && (_type == OverviewPhotos)) || (!selectingDown && (_type != OverviewPhotos))) ? -1 : 1);
}
if (dragFirstAffectedIndex >= 0) {
SelectedItems::const_iterator i = _selected.constFind(dragFirstAffected);
dragSelecting = (i == _selected.cend() || i.value() != FullItemSel);
}
updateDragSelection(dragSelFrom, dragSelFromIndex, dragSelTo, dragSelToIndex, dragSelecting);
}
bool dragSelecting = false;
MsgId dragFirstAffected = dragSelFrom;
int32 dragFirstAffectedIndex = dragSelFromIndex;
while (dragFirstAffectedIndex >= 0 && dragFirstAffected <= 0) {
moveToNextItem(dragFirstAffected, dragFirstAffectedIndex, dragSelTo, ((selectingDown && (_type == OverviewPhotos)) || (!selectingDown && (_type != OverviewPhotos))) ? -1 : 1);
}
if (dragFirstAffectedIndex >= 0) {
SelectedItems::const_iterator i = _selected.constFind(dragFirstAffected);
dragSelecting = (i == _selected.cend() || i.value() != FullItemSel);
}
updateDragSelection(dragSelFrom, dragSelFromIndex, dragSelTo, dragSelToIndex, dragSelecting);
} else if (_dragAction == Dragging) {
}
@ -987,6 +1010,23 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
dragActionUpdate(e->globalPos());
}
// -2 - has full selected items, but not over, 0 - no selection, 2 - over full selected items
int32 isUponSelected = 0, hasSelected = 0;
if (!_selected.isEmpty()) {
isUponSelected = -1;
if (_selected.cbegin().value() == FullItemSel) {
hasSelected = 2;
if (App::hoveredLinkItem() && _selected.constFind(App::hoveredLinkItem()->id) != _selected.cend()) {
isUponSelected = 2;
} else {
isUponSelected = -2;
}
}
}
if (showFromTouch && hasSelected && isUponSelected < hasSelected) {
isUponSelected = hasSelected;
}
_contextMenuLnk = textlnkOver();
PhotoLink *lnkPhoto = dynamic_cast<PhotoLink*>(_contextMenuLnk.data());
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
@ -1010,13 +1050,17 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
_menu->addAction(lang(lnkVideo ? lng_context_save_video : (lnkAudio ? lng_context_save_audio : lng_context_save_document)), this, SLOT(saveContextFile()))->setEnabled(true);
}
}
if (App::hoveredLinkItem()) {
if (isUponSelected > 1) {
_menu->addAction(lang(lng_context_forward_selected), _overview, SLOT(onForwardSelected()));
_menu->addAction(lang(lng_context_delete_selected), _overview, SLOT(onDeleteSelected()));
_menu->addAction(lang(lng_context_clear_selection), _overview, SLOT(onClearSelected()));
} else if (isUponSelected != -2 && App::hoveredLinkItem()) {
if (dynamic_cast<HistoryMessage*>(App::hoveredLinkItem())) {
_menu->addAction(lang(lng_context_forward_msg), this, SLOT(forwardMessage()))->setEnabled(true);
}
_menu->addAction(lang(lng_context_delete_msg), this, SLOT(deleteMessage()))->setEnabled(true);
App::contextItem(App::hoveredLinkItem());
}
App::contextItem(App::hoveredLinkItem());
}
if (_menu) {
_menu->setAttribute(Qt::WA_DeleteOnClose);
@ -1029,6 +1073,7 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
int32 OverviewInner::resizeToWidth(int32 nwidth, int32 scrollTop, int32 minHeight) {
if (width() == nwidth && minHeight == _minHeight) return scrollTop;
_minHeight = minHeight;
_addToY = (_height < _minHeight) ? (_minHeight - _height) : 0;
if (_type == OverviewPhotos && _resizeIndex < 0) {
_resizeIndex = _photosInRow * ((scrollTop + minHeight) / int32(_vsize + st::overviewPhotoSkip)) + _photosInRow - 1;
_resizeSkip = (scrollTop + minHeight) - ((scrollTop + minHeight) / int32(_vsize + st::overviewPhotoSkip)) * int32(_vsize + st::overviewPhotoSkip);
@ -1055,7 +1100,14 @@ MediaOverviewType OverviewInner::type() const {
}
void OverviewInner::switchType(MediaOverviewType type) {
_type = type;
if (_type != type) {
_selected.clear();
_dragItemIndex = _mousedItemIndex = _dragSelFromIndex = _dragSelToIndex = -1;
_dragItem = _mousedItem = _dragSelFrom = _dragSelTo = 0;
_items.clear();
_cached.clear();
_type = type;
}
mediaOverviewUpdated();
if (App::wnd()) App::wnd()->update();
}
@ -1502,6 +1554,8 @@ void OverviewWidget::switchType(MediaOverviewType type) {
_selCount = 0;
App::main()->topBar()->showSelected(0);
updateTopBarSelection();
_scroll.scrollToY(_scroll.scrollTopMax());
onScroll();
}
void OverviewWidget::updateTopBarSelection() {
@ -1577,6 +1631,7 @@ void OverviewWidget::mediaOverviewUpdated(PeerData *p) {
if (peer() == p) {
_inner.mediaOverviewUpdated();
onScroll();
updateTopBarSelection();
}
}
@ -1700,4 +1755,3 @@ void OverviewWidget::onDeleteContextSure() {
void OverviewWidget::onClearSelected() {
_inner.clearSelectedItems();
}