mirror of https://github.com/procxx/kepka.git
Implement drag-n-drop from HistoryView::ListWidget.
This commit is contained in:
parent
681b9b5ba3
commit
7435bd7fb0
|
@ -1052,8 +1052,15 @@ void HistoryInner::mouseActionCancel() {
|
||||||
_widget->noSelectingScroll();
|
_widget->noSelectingScroll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryInner::performDrag() {
|
std::unique_ptr<QMimeData> HistoryInner::prepareDrag() {
|
||||||
if (_mouseAction != MouseAction::Dragging) return;
|
if (_mouseAction != MouseAction::Dragging) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto pressedHandler = ClickHandler::getPressed();
|
||||||
|
if (dynamic_cast<VoiceSeekClickHandler*>(pressedHandler.get())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
const auto mouseActionView = _mouseActionItem
|
const auto mouseActionView = _mouseActionItem
|
||||||
? _mouseActionItem->mainView()
|
? _mouseActionItem->mainView()
|
||||||
|
@ -1082,11 +1089,6 @@ void HistoryInner::performDrag() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto pressedHandler = ClickHandler::getPressed();
|
|
||||||
|
|
||||||
if (dynamic_cast<VoiceSeekClickHandler*>(pressedHandler.get())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TextWithEntities sel;
|
TextWithEntities sel;
|
||||||
QList<QUrl> urls;
|
QList<QUrl> urls;
|
||||||
|
@ -1110,48 +1112,49 @@ void HistoryInner::performDrag() {
|
||||||
mimeData->setData(qsl("application/x-td-forward"), "1");
|
mimeData->setData(qsl("application/x-td-forward"), "1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_controller->window()->launchDrag(std::move(mimeData));
|
return mimeData;
|
||||||
return;
|
} else if (_dragStateItem) {
|
||||||
} else {
|
const auto view = _dragStateItem->mainView();
|
||||||
auto forwardMimeType = QString();
|
if (!view) {
|
||||||
auto pressedMedia = static_cast<HistoryMedia*>(nullptr);
|
return nullptr;
|
||||||
if (auto pressedItem = App::pressedItem()) {
|
}
|
||||||
pressedMedia = pressedItem->media();
|
auto forwardIds = MessageIdsList();
|
||||||
if (_mouseCursorState == CursorState::Date
|
if (_mouseCursorState == CursorState::Date) {
|
||||||
|| (pressedMedia && pressedMedia->dragItem())) {
|
forwardIds = Auth().data().itemOrItsGroup(_dragStateItem);
|
||||||
Auth().data().setMimeForwardIds(
|
} else if (view->isHiddenByGroup() && pressedHandler) {
|
||||||
Auth().data().itemOrItsGroup(pressedItem->data()));
|
forwardIds = MessageIdsList(1, _dragStateItem->fullId());
|
||||||
forwardMimeType = qsl("application/x-td-forward");
|
} else if (const auto media = view->media()) {
|
||||||
|
if (media->dragItemByHandler(pressedHandler)
|
||||||
|
|| media->dragItem()) {
|
||||||
|
forwardIds = MessageIdsList(1, _dragStateItem->fullId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (const auto pressedLnkItem = _mouseActionItem) {
|
if (forwardIds.empty()) {
|
||||||
if (const auto view = pressedLnkItem->mainView()) {
|
return nullptr;
|
||||||
if ((pressedMedia = view->media())) {
|
|
||||||
if (forwardMimeType.isEmpty()
|
|
||||||
&& pressedMedia->dragItemByHandler(pressedHandler)) {
|
|
||||||
Auth().data().setMimeForwardIds(
|
|
||||||
{ 1, pressedLnkItem->fullId() });
|
|
||||||
forwardMimeType = qsl("application/x-td-forward");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!forwardMimeType.isEmpty()) {
|
Auth().data().setMimeForwardIds(std::move(forwardIds));
|
||||||
auto mimeData = std::make_unique<QMimeData>();
|
auto result = std::make_unique<QMimeData>();
|
||||||
mimeData->setData(forwardMimeType, "1");
|
result->setData(qsl("application/x-td-forward"), "1");
|
||||||
if (auto document = (pressedMedia ? pressedMedia->getDocument() : nullptr)) {
|
if (const auto media = view->media()) {
|
||||||
auto filepath = document->filepath(DocumentData::FilePathResolveChecked);
|
if (const auto document = media->getDocument()) {
|
||||||
|
const auto filepath = document->filepath(
|
||||||
|
DocumentData::FilePathResolveChecked);
|
||||||
if (!filepath.isEmpty()) {
|
if (!filepath.isEmpty()) {
|
||||||
QList<QUrl> urls;
|
QList<QUrl> urls;
|
||||||
urls.push_back(QUrl::fromLocalFile(filepath));
|
urls.push_back(QUrl::fromLocalFile(filepath));
|
||||||
mimeData->setUrls(urls);
|
result->setUrls(urls);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This call enters event loop and can destroy any QObject.
|
|
||||||
_controller->window()->launchDrag(std::move(mimeData));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryInner::performDrag() {
|
||||||
|
if (auto mimeData = prepareDrag()) {
|
||||||
|
// This call enters event loop and can destroy any QObject.
|
||||||
|
_controller->window()->launchDrag(std::move(mimeData));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1739,8 +1742,11 @@ void HistoryInner::saveContextGif(FullMsgId itemId) {
|
||||||
|
|
||||||
void HistoryInner::copyContextText(FullMsgId itemId) {
|
void HistoryInner::copyContextText(FullMsgId itemId) {
|
||||||
if (const auto item = App::histItemById(itemId)) {
|
if (const auto item = App::histItemById(itemId)) {
|
||||||
// #TODO check for a group
|
if (const auto group = Auth().data().groups().find(item)) {
|
||||||
SetClipboardWithEntities(HistoryItemText(item));
|
SetClipboardWithEntities(HistoryGroupText(group));
|
||||||
|
} else {
|
||||||
|
SetClipboardWithEntities(HistoryItemText(item));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2326,7 +2332,7 @@ void HistoryInner::mouseActionUpdate() {
|
||||||
if (item != _mouseActionItem || (m - _dragStartPosition).manhattanLength() >= QApplication::startDragDistance()) {
|
if (item != _mouseActionItem || (m - _dragStartPosition).manhattanLength() >= QApplication::startDragDistance()) {
|
||||||
if (_mouseAction == MouseAction::PrepareDrag) {
|
if (_mouseAction == MouseAction::PrepareDrag) {
|
||||||
_mouseAction = MouseAction::Dragging;
|
_mouseAction = MouseAction::Dragging;
|
||||||
InvokeQueued(this, [this] { performDrag(); });
|
crl::on_main(this, [=] { performDrag(); });
|
||||||
} else if (_mouseAction == MouseAction::PrepareSelect) {
|
} else if (_mouseAction == MouseAction::PrepareSelect) {
|
||||||
_mouseAction = MouseAction::Selecting;
|
_mouseAction = MouseAction::Selecting;
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,6 +194,7 @@ private:
|
||||||
void mouseActionUpdate(const QPoint &screenPos);
|
void mouseActionUpdate(const QPoint &screenPos);
|
||||||
void mouseActionFinish(const QPoint &screenPos, Qt::MouseButton button);
|
void mouseActionFinish(const QPoint &screenPos, Qt::MouseButton button);
|
||||||
void mouseActionCancel();
|
void mouseActionCancel();
|
||||||
|
std::unique_ptr<QMimeData> prepareDrag();
|
||||||
void performDrag();
|
void performDrag();
|
||||||
|
|
||||||
QPoint mapPointToItem(QPoint p, const Element *view);
|
QPoint mapPointToItem(QPoint p, const Element *view);
|
||||||
|
|
|
@ -649,6 +649,35 @@ auto ListWidget::itemUnderPressSelection() -> SelectedMap::iterator {
|
||||||
: _selected.end();
|
: _selected.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ListWidget::isInsideSelection(
|
||||||
|
not_null<const Element*> view,
|
||||||
|
not_null<HistoryItem*> exactItem,
|
||||||
|
const MouseState &state) const {
|
||||||
|
if (!_selected.empty()) {
|
||||||
|
if (state.pointState == PointState::GroupPart) {
|
||||||
|
return _selected.contains(exactItem->fullId());
|
||||||
|
} else {
|
||||||
|
return isSelectedAsGroup(_selected, view->data());
|
||||||
|
}
|
||||||
|
} else if (_selectedTextItem
|
||||||
|
&& _selectedTextItem == view->data()
|
||||||
|
&& state.pointState != PointState::Outside) {
|
||||||
|
StateRequest stateRequest;
|
||||||
|
stateRequest.flags |= Text::StateRequest::Flag::LookupSymbol;
|
||||||
|
const auto dragState = view->textState(
|
||||||
|
state.point,
|
||||||
|
stateRequest);
|
||||||
|
if (dragState.cursor == CursorState::Text
|
||||||
|
&& base::in_range(
|
||||||
|
dragState.symbol,
|
||||||
|
_selectedTextRange.from,
|
||||||
|
_selectedTextRange.to)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto ListWidget::itemUnderPressSelection() const
|
auto ListWidget::itemUnderPressSelection() const
|
||||||
-> SelectedMap::const_iterator {
|
-> SelectedMap::const_iterator {
|
||||||
return (_pressState.itemId
|
return (_pressState.itemId
|
||||||
|
@ -1300,37 +1329,14 @@ void ListWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
request.overView = _overElement
|
request.overView = _overElement
|
||||||
&& (_overState.pointState != PointState::Outside);
|
&& (_overState.pointState != PointState::Outside);
|
||||||
request.selectedText = _selectedText;
|
request.selectedText = _selectedText;
|
||||||
const auto itemId = request.view
|
|
||||||
? request.view->data()->fullId()
|
|
||||||
: FullMsgId();
|
|
||||||
if (!_selected.empty()) {
|
if (!_selected.empty()) {
|
||||||
request.selectedItems = collectSelectedIds();
|
request.selectedItems = collectSelectedIds();
|
||||||
if (request.overView && _selected.find(itemId) != end(_selected)) {
|
|
||||||
request.overSelection = true;
|
|
||||||
}
|
|
||||||
} else if (_selectedTextItem
|
|
||||||
&& request.view
|
|
||||||
&& _selectedTextItem == request.view->data()
|
|
||||||
&& request.overView) {
|
|
||||||
const auto pointInItem = mapPointToItem(
|
|
||||||
mapFromGlobal(_mousePosition),
|
|
||||||
request.view);
|
|
||||||
StateRequest stateRequest;
|
|
||||||
stateRequest.flags |= Text::StateRequest::Flag::LookupSymbol;
|
|
||||||
const auto dragState = request.view->textState(
|
|
||||||
pointInItem,
|
|
||||||
stateRequest);
|
|
||||||
if (dragState.cursor == CursorState::Text
|
|
||||||
&& base::in_range(
|
|
||||||
dragState.symbol,
|
|
||||||
_selectedTextRange.from,
|
|
||||||
_selectedTextRange.to)) {
|
|
||||||
request.overSelection = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (showFromTouch) {
|
|
||||||
request.overSelection = true;
|
|
||||||
}
|
}
|
||||||
|
request.overSelection = showFromTouch
|
||||||
|
|| (_overElement && isInsideSelection(
|
||||||
|
_overElement,
|
||||||
|
_overItemExact ? _overItemExact : _overElement->data().get(),
|
||||||
|
_overState));
|
||||||
|
|
||||||
_menu = FillContextMenu(this, request);
|
_menu = FillContextMenu(this, request);
|
||||||
if (_menu && !_menu->actions().isEmpty()) {
|
if (_menu && !_menu->actions().isEmpty()) {
|
||||||
|
@ -1575,7 +1581,8 @@ void ListWidget::mouseActionStart(
|
||||||
_pressState = _overState;
|
_pressState = _overState;
|
||||||
repaintItem(_overState.itemId);
|
repaintItem(_overState.itemId);
|
||||||
}
|
}
|
||||||
const auto pressedView = _overElement;
|
_pressItemExact = _overItemExact;
|
||||||
|
const auto pressElement = _overElement;
|
||||||
|
|
||||||
_mouseAction = MouseAction::None;
|
_mouseAction = MouseAction::None;
|
||||||
_pressWasInactive = _controller->window()->wasInactivePress();
|
_pressWasInactive = _controller->window()->wasInactivePress();
|
||||||
|
@ -1590,7 +1597,7 @@ void ListWidget::mouseActionStart(
|
||||||
_mouseAction = MouseAction::PrepareSelect;
|
_mouseAction = MouseAction::PrepareSelect;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_mouseAction == MouseAction::None && pressedView) {
|
if (_mouseAction == MouseAction::None && pressElement) {
|
||||||
validateTrippleClickStartTime();
|
validateTrippleClickStartTime();
|
||||||
TextState dragState;
|
TextState dragState;
|
||||||
auto startDistance = (globalPosition - _trippleClickPoint).manhattanLength();
|
auto startDistance = (globalPosition - _trippleClickPoint).manhattanLength();
|
||||||
|
@ -1598,9 +1605,9 @@ void ListWidget::mouseActionStart(
|
||||||
if (_trippleClickStartTime != 0 && validStartPoint) {
|
if (_trippleClickStartTime != 0 && validStartPoint) {
|
||||||
StateRequest request;
|
StateRequest request;
|
||||||
request.flags = Text::StateRequest::Flag::LookupSymbol;
|
request.flags = Text::StateRequest::Flag::LookupSymbol;
|
||||||
dragState = pressedView->textState(_pressState.point, request);
|
dragState = pressElement->textState(_pressState.point, request);
|
||||||
if (dragState.cursor == CursorState::Text) {
|
if (dragState.cursor == CursorState::Text) {
|
||||||
setTextSelection(pressedView, TextSelection(
|
setTextSelection(pressElement, TextSelection(
|
||||||
dragState.symbol,
|
dragState.symbol,
|
||||||
dragState.symbol
|
dragState.symbol
|
||||||
));
|
));
|
||||||
|
@ -1610,23 +1617,23 @@ void ListWidget::mouseActionStart(
|
||||||
mouseActionUpdate();
|
mouseActionUpdate();
|
||||||
_trippleClickStartTime = getms();
|
_trippleClickStartTime = getms();
|
||||||
}
|
}
|
||||||
} else if (pressedView) {
|
} else if (pressElement) {
|
||||||
StateRequest request;
|
StateRequest request;
|
||||||
request.flags = Text::StateRequest::Flag::LookupSymbol;
|
request.flags = Text::StateRequest::Flag::LookupSymbol;
|
||||||
dragState = pressedView->textState(_pressState.point, request);
|
dragState = pressElement->textState(_pressState.point, request);
|
||||||
}
|
}
|
||||||
if (_mouseSelectType != TextSelectType::Paragraphs) {
|
if (_mouseSelectType != TextSelectType::Paragraphs) {
|
||||||
_mouseTextSymbol = dragState.symbol;
|
_mouseTextSymbol = dragState.symbol;
|
||||||
if (isPressInSelectedText(dragState)) {
|
if (isPressInSelectedText(dragState)) {
|
||||||
_mouseAction = MouseAction::PrepareDrag; // start text drag
|
_mouseAction = MouseAction::PrepareDrag; // start text drag
|
||||||
} else if (!_pressWasInactive) {
|
} else if (!_pressWasInactive) {
|
||||||
if (requiredToStartDragging(pressedView)) {
|
if (requiredToStartDragging(pressElement)) {
|
||||||
_mouseAction = MouseAction::PrepareDrag;
|
_mouseAction = MouseAction::PrepareDrag;
|
||||||
} else {
|
} else {
|
||||||
if (dragState.afterSymbol) ++_mouseTextSymbol;
|
if (dragState.afterSymbol) ++_mouseTextSymbol;
|
||||||
if (!hasSelectedItems()
|
if (!hasSelectedItems()
|
||||||
&& _overState.pointState != PointState::Outside) {
|
&& _overState.pointState != PointState::Outside) {
|
||||||
setTextSelection(pressedView, TextSelection(
|
setTextSelection(pressElement, TextSelection(
|
||||||
_mouseTextSymbol,
|
_mouseTextSymbol,
|
||||||
_mouseTextSymbol));
|
_mouseTextSymbol));
|
||||||
_mouseAction = MouseAction::Selecting;
|
_mouseAction = MouseAction::Selecting;
|
||||||
|
@ -1637,7 +1644,7 @@ void ListWidget::mouseActionStart(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!pressedView) {
|
if (!pressElement) {
|
||||||
_mouseAction = MouseAction::None;
|
_mouseAction = MouseAction::None;
|
||||||
} else if (_mouseAction == MouseAction::None) {
|
} else if (_mouseAction == MouseAction::None) {
|
||||||
mouseActionCancel();
|
mouseActionCancel();
|
||||||
|
@ -1651,6 +1658,7 @@ void ListWidget::mouseActionUpdate(const QPoint &globalPosition) {
|
||||||
|
|
||||||
void ListWidget::mouseActionCancel() {
|
void ListWidget::mouseActionCancel() {
|
||||||
_pressState = MouseState();
|
_pressState = MouseState();
|
||||||
|
_pressItemExact = nullptr;
|
||||||
_mouseAction = MouseAction::None;
|
_mouseAction = MouseAction::None;
|
||||||
clearDragSelection();
|
clearDragSelection();
|
||||||
_wasSelectedText = false;
|
_wasSelectedText = false;
|
||||||
|
@ -1663,6 +1671,7 @@ void ListWidget::mouseActionFinish(
|
||||||
mouseActionUpdate(globalPosition);
|
mouseActionUpdate(globalPosition);
|
||||||
|
|
||||||
auto pressState = base::take(_pressState);
|
auto pressState = base::take(_pressState);
|
||||||
|
base::take(_pressItemExact);
|
||||||
repaintItem(pressState.itemId);
|
repaintItem(pressState.itemId);
|
||||||
|
|
||||||
const auto toggleByHandler = [&](const ClickHandlerPtr &handler) {
|
const auto toggleByHandler = [&](const ClickHandlerPtr &handler) {
|
||||||
|
@ -1894,102 +1903,104 @@ style::cursor ListWidget::computeMouseCursor() const {
|
||||||
return style::cur_default;
|
return style::cur_default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<QMimeData> ListWidget::prepareDrag() {
|
||||||
|
if (_mouseAction != MouseAction::Dragging) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto pressedHandler = ClickHandler::getPressed();
|
||||||
|
if (dynamic_cast<VoiceSeekClickHandler*>(pressedHandler.get())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto pressedItem = App::histItemById(_pressState.itemId);
|
||||||
|
const auto pressedView = viewForItem(pressedItem);
|
||||||
|
const auto uponSelected = pressedView && isInsideSelection(
|
||||||
|
pressedView,
|
||||||
|
_pressItemExact ? _pressItemExact : pressedItem,
|
||||||
|
_pressState);
|
||||||
|
|
||||||
|
QList<QUrl> urls;
|
||||||
|
auto text = [&] {
|
||||||
|
if (uponSelected) {
|
||||||
|
return getSelectedText();
|
||||||
|
} else if (pressedHandler) {
|
||||||
|
return TextWithEntities{
|
||||||
|
pressedHandler->dragText(),
|
||||||
|
EntitiesInText()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return TextWithEntities();
|
||||||
|
//if (!sel.isEmpty() && sel.at(0) != '/' && sel.at(0) != '@' && sel.at(0) != '#') {
|
||||||
|
// urls.push_back(QUrl::fromEncoded(sel.toUtf8())); // Google Chrome crashes in Mac OS X O_o
|
||||||
|
//}
|
||||||
|
}();
|
||||||
|
if (auto mimeData = MimeDataFromTextWithEntities(text)) {
|
||||||
|
clearDragSelection();
|
||||||
|
// _widget->noSelectingScroll(); #TODO scroll
|
||||||
|
|
||||||
|
if (!urls.isEmpty()) {
|
||||||
|
mimeData->setUrls(urls);
|
||||||
|
}
|
||||||
|
if (uponSelected && !Adaptive::OneColumn()) {
|
||||||
|
const auto canForwardAll = [&] {
|
||||||
|
for (const auto &[itemId, data] : _selected) {
|
||||||
|
if (!data.canForward) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}();
|
||||||
|
auto items = canForwardAll
|
||||||
|
? getSelectedItems()
|
||||||
|
: MessageIdsList();
|
||||||
|
if (!items.empty()) {
|
||||||
|
Auth().data().setMimeForwardIds(std::move(items));
|
||||||
|
mimeData->setData(qsl("application/x-td-forward"), "1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mimeData;
|
||||||
|
} else if (pressedView) {
|
||||||
|
auto forwardIds = MessageIdsList();
|
||||||
|
const auto exactItem = _pressItemExact
|
||||||
|
? _pressItemExact
|
||||||
|
: pressedItem;
|
||||||
|
if (_mouseCursorState == CursorState::Date) {
|
||||||
|
forwardIds = Auth().data().itemOrItsGroup(_overElement->data());
|
||||||
|
} else if (_pressState.pointState == PointState::GroupPart) {
|
||||||
|
forwardIds = MessageIdsList(1, exactItem->fullId());
|
||||||
|
} else if (const auto media = pressedView->media()) {
|
||||||
|
if (media->dragItemByHandler(pressedHandler)
|
||||||
|
|| media->dragItem()) {
|
||||||
|
forwardIds = MessageIdsList(1, exactItem->fullId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (forwardIds.empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
Auth().data().setMimeForwardIds(std::move(forwardIds));
|
||||||
|
auto result = std::make_unique<QMimeData>();
|
||||||
|
result->setData(qsl("application/x-td-forward"), "1");
|
||||||
|
if (const auto media = pressedView->media()) {
|
||||||
|
if (const auto document = media->getDocument()) {
|
||||||
|
const auto filepath = document->filepath(
|
||||||
|
DocumentData::FilePathResolveChecked);
|
||||||
|
if (!filepath.isEmpty()) {
|
||||||
|
QList<QUrl> urls;
|
||||||
|
urls.push_back(QUrl::fromLocalFile(filepath));
|
||||||
|
result->setUrls(urls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void ListWidget::performDrag() {
|
void ListWidget::performDrag() {
|
||||||
if (_mouseAction != MouseAction::Dragging) return;
|
if (auto mimeData = prepareDrag()) {
|
||||||
|
// This call enters event loop and can destroy any QObject.
|
||||||
auto uponSelected = false;
|
_controller->window()->launchDrag(std::move(mimeData));
|
||||||
//if (_mouseActionItem) {
|
}
|
||||||
// if (!_selected.isEmpty() && _selected.cbegin().value() == FullSelection) {
|
|
||||||
// uponSelected = _selected.contains(_mouseActionItem);
|
|
||||||
// } else {
|
|
||||||
// StateRequest request;
|
|
||||||
// request.flags |= Text::StateRequest::Flag::LookupSymbol;
|
|
||||||
// auto dragState = _mouseActionItem->textState(_dragStartPosition.x(), _dragStartPosition.y(), request);
|
|
||||||
// uponSelected = (dragState.cursor == CursorState::Text);
|
|
||||||
// if (uponSelected) {
|
|
||||||
// if (_selected.isEmpty() ||
|
|
||||||
// _selected.cbegin().value() == FullSelection ||
|
|
||||||
// _selected.cbegin().key() != _mouseActionItem
|
|
||||||
// ) {
|
|
||||||
// uponSelected = false;
|
|
||||||
// } else {
|
|
||||||
// uint16 selFrom = _selected.cbegin().value().from, selTo = _selected.cbegin().value().to;
|
|
||||||
// if (dragState.symbol < selFrom || dragState.symbol >= selTo) {
|
|
||||||
// uponSelected = false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//auto pressedHandler = ClickHandler::getPressed();
|
|
||||||
|
|
||||||
//if (dynamic_cast<VoiceSeekClickHandler*>(pressedHandler.data())) {
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//TextWithEntities sel;
|
|
||||||
//QList<QUrl> urls;
|
|
||||||
//if (uponSelected) {
|
|
||||||
// sel = getSelectedText();
|
|
||||||
//} else if (pressedHandler) {
|
|
||||||
// sel = { pressedHandler->dragText(), EntitiesInText() };
|
|
||||||
// //if (!sel.isEmpty() && sel.at(0) != '/' && sel.at(0) != '@' && sel.at(0) != '#') {
|
|
||||||
// // urls.push_back(QUrl::fromEncoded(sel.toUtf8())); // Google Chrome crashes in Mac OS X O_o
|
|
||||||
// //}
|
|
||||||
//}
|
|
||||||
//if (auto mimeData = mimeDataFromTextWithEntities(sel)) {
|
|
||||||
// updateDragSelection(0, 0, false);
|
|
||||||
// _widget->noSelectingScroll();
|
|
||||||
|
|
||||||
// if (!urls.isEmpty()) mimeData->setUrls(urls);
|
|
||||||
// if (uponSelected && !Adaptive::OneColumn()) {
|
|
||||||
// auto selectedState = getSelectionState();
|
|
||||||
// if (selectedState.count > 0 && selectedState.count == selectedState.canForwardCount) {
|
|
||||||
// Auth().data().setMimeForwardIds(getSelectedItems());
|
|
||||||
// mimeData->setData(qsl("application/x-td-forward"), "1");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// _controller->window()->launchDrag(std::move(mimeData));
|
|
||||||
// return;
|
|
||||||
//} else {
|
|
||||||
// auto forwardMimeType = QString();
|
|
||||||
// auto pressedMedia = static_cast<HistoryMedia*>(nullptr);
|
|
||||||
// if (auto pressedItem = App::pressedItem()) { // #TODO no App::
|
|
||||||
// pressedMedia = pressedItem->media();
|
|
||||||
// if (_mouseCursorState == CursorState::Date
|
|
||||||
// || (pressedMedia && pressedMedia->dragItem())) {
|
|
||||||
// Auth().data().setMimeForwardIds(
|
|
||||||
// Auth().data().itemOrItsGroup(pressedItem->data()));
|
|
||||||
// forwardMimeType = qsl("application/x-td-forward");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (auto pressedLnkItem = App::pressedLinkItem()) { // #TODO no App::
|
|
||||||
// if ((pressedMedia = pressedLnkItem->media())) {
|
|
||||||
// if (forwardMimeType.isEmpty()
|
|
||||||
// && pressedMedia->dragItemByHandler(pressedHandler)) {
|
|
||||||
// Auth().data().setMimeForwardIds(
|
|
||||||
// { 1, pressedLnkItem->fullId() });
|
|
||||||
// forwardMimeType = qsl("application/x-td-forward");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (!forwardMimeType.isEmpty()) {
|
|
||||||
// auto mimeData = std::make_unique<QMimeData>();
|
|
||||||
// mimeData->setData(forwardMimeType, "1");
|
|
||||||
// if (auto document = (pressedMedia ? pressedMedia->getDocument() : nullptr)) {
|
|
||||||
// auto filepath = document->filepath(DocumentData::FilePathResolveChecked);
|
|
||||||
// if (!filepath.isEmpty()) {
|
|
||||||
// QList<QUrl> urls;
|
|
||||||
// urls.push_back(QUrl::fromLocalFile(filepath));
|
|
||||||
// mimeData->setUrls(urls);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // This call enters event loop and can destroy any QObject.
|
|
||||||
// _controller->window()->launchDrag(std::move(mimeData));
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//} // #TODO drag
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ListWidget::itemTop(not_null<const Element*> view) const {
|
int ListWidget::itemTop(not_null<const Element*> view) const {
|
||||||
|
@ -2097,6 +2108,9 @@ void ListWidget::itemRemoved(not_null<const HistoryItem*> item) {
|
||||||
if (_overItemExact == item) {
|
if (_overItemExact == item) {
|
||||||
_overItemExact = nullptr;
|
_overItemExact = nullptr;
|
||||||
}
|
}
|
||||||
|
if (_pressItemExact == item) {
|
||||||
|
_pressItemExact = nullptr;
|
||||||
|
}
|
||||||
const auto i = _views.find(item);
|
const auto i = _views.find(item);
|
||||||
if (i == end(_views)) {
|
if (i == end(_views)) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -245,6 +245,7 @@ private:
|
||||||
const QPoint &globalPosition,
|
const QPoint &globalPosition,
|
||||||
Qt::MouseButton button);
|
Qt::MouseButton button);
|
||||||
void mouseActionCancel();
|
void mouseActionCancel();
|
||||||
|
std::unique_ptr<QMimeData> prepareDrag();
|
||||||
void performDrag();
|
void performDrag();
|
||||||
style::cursor computeMouseCursor() const;
|
style::cursor computeMouseCursor() const;
|
||||||
int itemTop(not_null<const Element*> view) const;
|
int itemTop(not_null<const Element*> view) const;
|
||||||
|
@ -322,6 +323,10 @@ private:
|
||||||
SelectedMap::iterator itemUnderPressSelection();
|
SelectedMap::iterator itemUnderPressSelection();
|
||||||
SelectedMap::const_iterator itemUnderPressSelection() const;
|
SelectedMap::const_iterator itemUnderPressSelection() const;
|
||||||
bool isItemUnderPressSelected() const;
|
bool isItemUnderPressSelected() const;
|
||||||
|
bool isInsideSelection(
|
||||||
|
not_null<const Element*> view,
|
||||||
|
not_null<HistoryItem*> exactItem,
|
||||||
|
const MouseState &state) const;
|
||||||
bool requiredToStartDragging(not_null<Element*> view) const;
|
bool requiredToStartDragging(not_null<Element*> view) const;
|
||||||
bool isPressInSelectedText(TextState state) const;
|
bool isPressInSelectedText(TextState state) const;
|
||||||
void updateDragSelection();
|
void updateDragSelection();
|
||||||
|
@ -408,6 +413,7 @@ private:
|
||||||
MouseState _pressState;
|
MouseState _pressState;
|
||||||
Element *_overElement = nullptr;
|
Element *_overElement = nullptr;
|
||||||
HistoryItem *_overItemExact = nullptr;
|
HistoryItem *_overItemExact = nullptr;
|
||||||
|
HistoryItem *_pressItemExact = nullptr;
|
||||||
CursorState _mouseCursorState = CursorState();
|
CursorState _mouseCursorState = CursorState();
|
||||||
uint16 _mouseTextSymbol = 0;
|
uint16 _mouseTextSymbol = 0;
|
||||||
bool _pressWasInactive = false;
|
bool _pressWasInactive = false;
|
||||||
|
|
Loading…
Reference in New Issue