#!/usr/bin/python

# Modification History

# Created on 10/31/10 by  (dane):
# - Drag Drop Select tester.

import re
import sys
from PyQt4 import QtCore 
from PyQt4.QtCore import * 
from PyQt4.QtGui import *


class Global:
    """Generic container for shared variables."""
    pass 

class MyWindow(QWidget): 
    def __init__(self, *args): 
        QWidget.__init__(self, *args) 
        self.setAcceptDrops(True)
        Global.tabledata = []
        Global.tabledata.append( ['key 1', 'value 1'])
        Global.tabledata.append( ['key 2', 'value 2'])
        Global.tabledata.append( ['key 3', 'value 3'])
        Global.tabledata.append( ['key 4', 'value 4'])
        Global.selection = -1     # Global selection kludge
        self.vLayout = QVBoxLayout()
        self.vLayout.addWidget(self.createTable()) 
        self.hLayout = QHBoxLayout()
        self.vLayout.addLayout(self.hLayout)
        self.message = QLabel("Select row or drag drop")
        self.vLayout.addWidget(self.message)
        self.setLayout(self.vLayout) 

    def createTable(self):
        global tv
        tv = QTableView()
        header = [ 'Key', 'Values' ]
        global tm
        tm = MyTableModel(header, self) 
        tv.setModel(tm)
        tv.setShowGrid(True)
        vh = tv.verticalHeader()
        vh.setVisible(False)
        hh = tv.horizontalHeader()
        hh.setStretchLastSection(True)
        tv.setSelectionBehavior(QAbstractItemView.SelectRows)
        tv.setSelectionMode(QAbstractItemView.SingleSelection)
        tv.setDragEnabled(True)
        tv.setDropIndicatorShown(True)
        tv.setDragDropMode(QAbstractItemView.InternalMove)
        QObject.connect(tv.selectionModel(),\
                            SIGNAL("selectionChanged(QItemSelection, QItemSelection)"),\
                            tm.MySelChg)
        return tv
 

class MyTableModel(QAbstractTableModel): 
    def __init__(self, headerdata, parent=None, *args): 
        QAbstractTableModel.__init__(self, parent, *args) 
        self.headerdata = headerdata
        self.setSupportedDragActions(QtCore.Qt.MoveAction)

    def rowCount(self, parent=QtCore.QModelIndex()): 
        return len(Global.tabledata) 
 
    def columnCount(self, parent=QtCore.QModelIndex()): 
        return len(Global.tabledata[0]) 
 
    def timerPop(self) :
        if (Global.selection != -1) :
            self.msg=QErrorMessage()
            self.row=Global.selection+1
            self.msg.showMessage("row "+str(self.row)+" is selected")
            Global.selection=-1

    def MySelChg(self,new,old) :
        if Global.selection == -1 : # ignore second selection until timer pops
            Global.selection = new.indexes()[0].row()
        self.stimer = QTimer()
        self.stimer.singleShot(1000, self.timerPop) # one second delay

    def data(self, index, role): 
        if not index.isValid(): 
            return QVariant() 
        if role != Qt.DisplayRole: 
            return QVariant() 
        return QVariant(Global.tabledata[index.row()][index.column()]) 

    def headerData(self, col, orientation, role):
        if col > 1 :
            return QVariant() 
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return QVariant(self.headerdata[col])
        return QVariant()

    def flags(self, index):
        self.defaultFlags = QAbstractTableModel.flags(self, index)
        if not index.isValid():
            return Qt.ItemIsDropEnabled | self.defaultFlags
        return Qt.ItemIsDragEnabled | Qt.ItemIsDropEnabled | Qt.ItemIsSelectable | self.defaultFlags

    def supportedDropActions(self):
        Global.selection=-1
        return Qt.MoveAction

    def mimeTypes(self):
        return ['application/x-qabstractitemmodeldatalist']

    def insertRows(self,beginrow,count,data,parentIndex=QtCore.QModelIndex()) :
        self.beginInsertRows(parentIndex, beginrow, (beginrow + (count - 1)))
        Global.tabledata.insert(beginrow,data)
        self.endInsertRows()
        self.emit(SIGNAL("dataChanged(QModelIndex,QModelIndex)"), parentIndex, parentIndex)
        return True

    def removeRow(self, row, parentIndex=QtCore.QModelIndex()):
        return self.removeRows(row, 1, parentIndex)

    def removeRows(self,row,count,parent):
        self.beginRemoveRows(parent,row,row+count-1)
        Global.tabledata.pop(row)
        self.endRemoveRows()
        return True

    def mimeData(self, indexes) :
        mdata = QMimeData()
        encodedData = QByteArray()
        buffer = QBuffer(encodedData)
        buffer.open(QIODevice.WriteOnly)
        self.srow=indexes[0].row();
        for i in range(len(Global.tabledata[0])):
            buffer.writeData(str(Global.tabledata[self.srow][i]))
            buffer.writeData('') # field separator
        mdata.setData('application/x-qabstractitemmodeldatalist', encodedData)
        buffer.close()
        return mdata
    

    def dropMimeData(self,mdata,action,row,column,parentIndex) :
        if action == Qt.IgnoreAction:
            return True
        if not  mdata.hasFormat('application/x-qabstractitemmodeldatalist'):
            return False
        if not parentIndex.isValid():
            return False
        beginrow = parentIndex.row()
        encodedData = QByteArray()
        encodedData = mdata.data('application/x-qabstractitemmodeldatalist')
        buffer = QBuffer(encodedData)
        buffer.open(QIODevice.ReadOnly)
        rdata = buffer.readData(10000)
        buffer.close()
        self.col=0

        self.myindex=tm.createIndex(self.srow,0) # send begin/end signals.
        tm.removeRow(self.srow,self.myindex)
        self.spli = re.split('',rdata)
        self.spli.pop()
        self.insertRows(beginrow,1,self.spli,parentIndex)
        self.reset()
        return True


    def node(self, index):
        itemNode = index.internalPointer()
        if itemNode is None:
            return False
        else:
            return itemNode


    def setData(self, index, value, role):
        if index.isValid() and role == Qt.EditRole:
            self.emit(SIGNAL("DataChanged(QModelIndex,QModelIndex)"))
        return True


if __name__ == "__main__": 
    app = QApplication([]) 
    Global.myW = MyWindow() 
    Global.myW.show() 
    sys.exit(app.exec_()) 

# Local Variables:
# compile-command: "./dd_q.py" */
# End:
