// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! \example draganddrop/dropsite \title Drop Site Example \brief The example shows how to distinguish the various MIME formats available in a drag and drop operation. \image dropsite-example.png Screenshot of the Drop Site example The Drop Site example accepts drops from other applications, and displays the MIME formats provided by the drag object. There are two classes, \c DropArea and \c DropSiteWindow, and a \c main() function in this example. A \c DropArea object is instantiated in \c DropSiteWindow; a \c DropSiteWindow object is then invoked in the \c main() function. \section1 DropArea Class Definition The \c DropArea class is a subclass of QLabel with a public slot, \c clear(), and a \c changed() signal. \snippet draganddrop/dropsite/droparea.h DropArea header part1 In addition, \c DropArea contains reimplementations of four \l{QWidget} event handlers: \list 1 \li \l{QWidget::dragEnterEvent()}{dragEnterEvent()} \li \l{QWidget::dragMoveEvent()}{dragMoveEvent()} \li \l{QWidget::dragLeaveEvent()}{dragLeaveEvent()} \li \l{QWidget::dropEvent()}{dropEvent()} \endlist These event handlers are further explained in the implementation of the \c DropArea class. \snippet draganddrop/dropsite/droparea.h DropArea header part2 \section1 DropArea Class Implementation In the \c DropArea constructor, we set the \l{QWidget::setMinimumSize()} {minimum size} to 200x200 pixels, the \l{QFrame::setFrameStyle()} {frame style} to both QFrame::Sunken and QFrame::StyledPanel, and we align its contents to the center. \snippet draganddrop/dropsite/droparea.cpp DropArea constructor Also, we enable drop events in \c DropArea by setting the \l{QWidget::acceptDrops()}{acceptDrops} property to \c true. Then, we enable the \l{QWidget::autoFillBackground()}{autoFillBackground} property and invoke the \c clear() function. The \l{QWidget::dragEnterEvent()}{dragEnterEvent()} event handler is called when a drag is in progress and the mouse enters the \c DropArea object. For the \c DropSite example, when the mouse enters \c DropArea, we set its text to "" and highlight its background. \snippet draganddrop/dropsite/droparea.cpp dragEnterEvent() function Then, we invoke \l{QDropEvent::acceptProposedAction()} {acceptProposedAction()} on \a event, setting the drop action to the one proposed. Lastly, we emit the \c changed() signal, with the data that was dropped and its MIME type information as a parameter. For \l{QWidget::dragMoveEvent()}{dragMoveEvent()}, we just accept the proposed QDragMoveEvent object, \a event, with \l{QDropEvent::acceptProposedAction()}{acceptProposedAction()}. \snippet draganddrop/dropsite/droparea.cpp dragMoveEvent() function The \c DropArea class's implementation of \l{QWidget::dropEvent()} {dropEvent()} extracts the \a{event}'s mime data and displays it accordingly. \snippet draganddrop/dropsite/droparea.cpp dropEvent() function part1 The \c mimeData object can contain one of the following objects: an image, HTML text, Markdown text, plain text, or a list of URLs. \snippet draganddrop/dropsite/droparea.cpp dropEvent() function part2 \list \li If \c mimeData contains an image, we display it in \c DropArea with \l{QLabel::setPixmap()}{setPixmap()}. \li If \c mimeData contains HTML, we display it with \l{QLabel::setText()}{setText()} and set \c{DropArea}'s text format as Qt::RichText. \li If \c mimeData contains Markdown, we display it with \l{QLabel::setText()}{setText()} and set \c{DropArea}'s text format as Qt::MarkdownText. \li If \c mimeData contains plain text, we display it with \l{QLabel::setText()}{setText()} and set \c{DropArea}'s text format as Qt::PlainText. In the event that \c mimeData contains URLs, we iterate through the list of URLs to display them on individual lines. \li If \c mimeData contains other types of objects, we set \c{DropArea}'s text, with \l{QLabel::setText()}{setText()} to "Cannot display data" to inform the user. \endlist We then set \c{DropArea}'s \l{QWidget::backgroundRole()}{backgroundRole} to QPalette::Dark and we accept \c{event}'s proposed action. \snippet draganddrop/dropsite/droparea.cpp dropEvent() function part3 The \l{QWidget::dragLeaveEvent()}{dragLeaveEvent()} event handler is called when a drag is in progress and the mouse leaves the widget. \snippet draganddrop/dropsite/droparea.cpp dragLeaveEvent() function For \c{DropArea}'s implementation, we clear invoke \c clear() and then accept the proposed event. The \c clear() function sets the text in \c DropArea to "" and sets the \l{QWidget::backgroundRole()}{backgroundRole} to QPalette::Dark. Lastly, it emits the \c changed() signal. \snippet draganddrop/dropsite/droparea.cpp clear() function \section1 DropSiteWindow Class Definition The \c DropSiteWindow class contains a constructor and a public slot, \c updateFormatsTable(). \snippet draganddrop/dropsite/dropsitewindow.h DropSiteWindow header The class also contains a private instance of \c DropArea, \c dropArea, QLabel, \c abstractLabel, QTableWidget, \c formatsTable, QDialogButtonBox, \c buttonBox, and two QPushButton objects, \c clearButton and \c quitButton. \section1 DropSiteWindow Class Implementation In the constructor of \c DropSiteWindow, we instantiate \c abstractLabel and set its \l{QLabel::setWordWrap()}{wordWrap} property to \c true. We also call the \l{QLabel::adjustSize()}{adjustSize()} function to adjust \c{abstractLabel}'s size according to its contents. \snippet draganddrop/dropsite/dropsitewindow.cpp constructor part1 Then we instantiate \c dropArea and connect its \c changed() signal to \c{DropSiteWindow}'s \c updateFormatsTable() slot. \snippet draganddrop/dropsite/dropsitewindow.cpp constructor part2 We now set up the QTableWidget object, \c formatsTable. Its horizontal header is set using a QStringList object, \c labels. The number of columms are set to two and the table is not editable. Also, the \c{formatTable}'s horizontal header is formatted to ensure that its second column stretches to occupy additional space available. \snippet draganddrop/dropsite/dropsitewindow.cpp constructor part3 Three QPushButton objects, \c clearButton, \c copyButton, and \c quitButton, are instantiated and added to \c buttonBox - a QDialogButtonBox object. We use QDialogButtonBox here to ensure that the push buttons are presented in a layout that conforms to the platform's style. \snippet draganddrop/dropsite/dropsitewindow.cpp constructor part4 The \l{QPushButton::clicked()}{clicked()} signals for \c copyButton, \c clearButton, and \c quitButton are connected to \c copy(), \c clear() and \l{QWidget::close()}{close()}, respectively. For the layout, we use a QVBoxLayout, \c mainLayout, to arrange our widgets vertically. We also set the window title to "Drop Site" and the minimum size to 350x500 pixels. \snippet draganddrop/dropsite/dropsitewindow.cpp constructor part5 We move on to the \c updateFormatsTable() function. This function updates the \c formatsTable, displaying the MIME formats of the object dropped onto the \c DropArea object. First, we set \l{QTableWidget}'s \l{QTableWidget::setRowCount()}{rowCount} property to 0. Then, we validate to ensure that the QMimeData object passed in is a valid object. \snippet draganddrop/dropsite/dropsitewindow.cpp updateFormatsTable() part1 Once we are sure that \c mimeData is valid, we iterate through its supported formats. \note The \l{QMimeData::formats()}{formats()} function returns a QStringList object, containing all the formats supported by the \c mimeData. \snippet draganddrop/dropsite/dropsitewindow.cpp updateFormatsTable() part2 Within each iteration, we create a QTableWidgetItem, \c formatItem and we set its \l{QTableWidgetItem::setFlags()}{flags} to Qt::ItemIsEnabled, and its \l{QTableWidgetItem::setTextAlignment()}{text alignment} to Qt::AlignTop and Qt::AlignLeft. A QString object, \c text, is customized to display data according to the contents of \c format. We invoke \l{QString}'s \l{QString::simplified()} {simplified()} function on \c text, to obtain a string that has no additional space before, after or in between words. \snippet draganddrop/dropsite/dropsitewindow.cpp updateFormatsTable() part3 If \c format contains a list of URLs, we iterate through them, using spaces to separate them. On the other hand, if \c format contains an image, we display the data by converting the text to hexadecimal. \snippet draganddrop/dropsite/dropsitewindow.cpp updateFormatsTable() part4 Once \c text has been customized to contain the appropriate data, we insert both \c format and \c text into \c formatsTable with \l{QTableWidget::setItem()}{setItem()}. Lastly, we invoke \l{QTableView::resizeColumnToContents()}{resizeColumnToContents()} on \c{formatsTable}'s first column. \section1 The main() Function Within the \c main() function, we instantiate \c DropSiteWindow and invoke its \l{QWidget::show()}{show()} function. \snippet draganddrop/dropsite/main.cpp main() function */