1#!/usr/bin/env python
2
3
4#############################################################################
5##
6## Copyright (C) 2013 Riverbank Computing Limited
7## Copyright (C) 2010 Hans-Peter Jansen <hpj@urpla.net>.
8## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
9## All rights reserved.
10##
11## This file is part of the examples of PyQt.
12##
13## $QT_BEGIN_LICENSE:BSD$
14## You may use this file under the terms of the BSD license as follows:
15##
16## "Redistribution and use in source and binary forms, with or without
17## modification, are permitted provided that the following conditions are
18## met:
19##   * Redistributions of source code must retain the above copyright
20##     notice, this list of conditions and the following disclaimer.
21##   * Redistributions in binary form must reproduce the above copyright
22##     notice, this list of conditions and the following disclaimer in
23##     the documentation and/or other materials provided with the
24##     distribution.
25##   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
26##     the names of its contributors may be used to endorse or promote
27##     products derived from this software without specific prior written
28##     permission.
29##
30## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
41## $QT_END_LICENSE$
42##
43#############################################################################
44
45
46from PyQt5.QtCore import pyqtSignal, QMimeData, Qt
47from PyQt5.QtGui import QPalette, QPixmap
48from PyQt5.QtWidgets import (QAbstractItemView, QApplication, QDialogButtonBox,
49        QFrame, QLabel, QPushButton, QTableWidget, QTableWidgetItem,
50        QVBoxLayout, QWidget)
51
52
53class DropArea(QLabel):
54
55    changed = pyqtSignal(QMimeData)
56
57    def __init__(self, parent = None):
58        super(DropArea, self).__init__(parent)
59
60        self.setMinimumSize(200, 200)
61        self.setFrameStyle(QFrame.Sunken | QFrame.StyledPanel)
62        self.setAlignment(Qt.AlignCenter)
63        self.setAcceptDrops(True)
64        self.setAutoFillBackground(True)
65        self.clear()
66
67    def dragEnterEvent(self, event):
68        self.setText("<drop content>")
69        self.setBackgroundRole(QPalette.Highlight)
70        event.acceptProposedAction()
71        self.changed.emit(event.mimeData())
72
73    def dragMoveEvent(self, event):
74        event.acceptProposedAction()
75
76    def dropEvent(self, event):
77        mimeData = event.mimeData()
78        if mimeData.hasImage():
79            self.setPixmap(QPixmap(mimeData.imageData()))
80        elif mimeData.hasHtml():
81            self.setText(mimeData.html())
82            self.setTextFormat(Qt.RichText)
83        elif mimeData.hasText():
84            self.setText(mimeData.text())
85            self.setTextFormat(Qt.PlainText)
86        elif mimeData.hasUrls():
87            self.setText("\n".join([url.path() for url in mimeData.urls()]))
88        else:
89            self.setText("Cannot display data")
90
91        self.setBackgroundRole(QPalette.Dark)
92        event.acceptProposedAction()
93
94    def dragLeaveEvent(self, event):
95        self.clear()
96        event.accept()
97
98    def clear(self):
99        self.setText("<drop content>")
100        self.setBackgroundRole(QPalette.Dark)
101        self.changed.emit(None)
102
103
104class DropSiteWindow(QWidget):
105
106    def __init__(self):
107        super(DropSiteWindow, self).__init__()
108
109        self.abstractLabel = QLabel(
110                "This example accepts drags from other applications and "
111                "displays the MIME types provided by the drag object.")
112        self.abstractLabel.setWordWrap(True)
113        self.abstractLabel.adjustSize()
114
115        self.dropArea = DropArea()
116        self.dropArea.changed.connect(self.updateFormatsTable)
117
118        self.formatsTable = QTableWidget()
119        self.formatsTable.setColumnCount(2)
120        self.formatsTable.setEditTriggers(QAbstractItemView.NoEditTriggers)
121        self.formatsTable.setHorizontalHeaderLabels(["Format", "Content"])
122        self.formatsTable.horizontalHeader().setStretchLastSection(True)
123
124        self.clearButton = QPushButton("Clear")
125        self.quitButton = QPushButton("Quit")
126
127        self.buttonBox = QDialogButtonBox()
128        self.buttonBox.addButton(self.clearButton, QDialogButtonBox.ActionRole)
129        self.buttonBox.addButton(self.quitButton, QDialogButtonBox.RejectRole)
130
131        self.quitButton.pressed.connect(self.close)
132        self.clearButton.pressed.connect(self.dropArea.clear)
133
134        mainLayout = QVBoxLayout()
135        mainLayout.addWidget(self.abstractLabel)
136        mainLayout.addWidget(self.dropArea)
137        mainLayout.addWidget(self.formatsTable)
138        mainLayout.addWidget(self.buttonBox)
139        self.setLayout(mainLayout)
140
141        self.setWindowTitle("Drop Site")
142        self.setMinimumSize(350, 500)
143
144    def updateFormatsTable(self, mimeData=None):
145        self.formatsTable.setRowCount(0)
146
147        if mimeData is None:
148            return
149
150        for format in mimeData.formats():
151            formatItem = QTableWidgetItem(format)
152            formatItem.setFlags(Qt.ItemIsEnabled)
153            formatItem.setTextAlignment(Qt.AlignTop | Qt.AlignLeft)
154
155            if format == 'text/plain':
156                text = mimeData.text().strip()
157            elif format == 'text/html':
158                text = mimeData.html().strip()
159            elif format == 'text/uri-list':
160                text = " ".join([url.toString() for url in mimeData.urls()])
161            else:
162                text = " ".join(["%02X" % ord(datum) for datum in mimeData.data(format)])
163
164            row = self.formatsTable.rowCount()
165            self.formatsTable.insertRow(row)
166            self.formatsTable.setItem(row, 0, QTableWidgetItem(format))
167            self.formatsTable.setItem(row, 1, QTableWidgetItem(text))
168
169        self.formatsTable.resizeColumnToContents(0)
170
171
172if __name__ == '__main__':
173
174    import sys
175
176    app = QApplication(sys.argv)
177    window = DropSiteWindow()
178    window.show()
179    sys.exit(app.exec_())
180
181