New wxWidget! MultiFile-FromManyFolders-Selection-Dialog

Huh!

Long name, but that is what it does. It select any number of files from any number of folders, and stores them in a list. Than, with all these files, you can do whatever you want in your application. You can see why I made this box, and how I use it here:

http://www.inverudio.com/programs/BiosAnalyzer/BiosAnalyzer.php

That is, if you have Windows, as for Linux I need to change the threading stuff, so that it could work (plot graphs).

Why I am submitting here, and not to SVN? Because, widget is not polished for library, and since I don’t have experience in writing libraries, I thought that someone on this list may know better how to encapsulate these two classes in the best way.

In particular, in my application, I use some globals, and for libraries, that is not acceptable, as far as I know. Code is below. Note that ‘ba.frame…’ stuff is my main application (BiosAnalyzer -> ba), and I left it in this code so that you could see how I use this widget. To me it is not that obvious what functions and variables should be kept/added in order to make this widget most usable, and extensible. That is why I am showing it here to more experienced programmers.

#nameofthiswidgetcanbeanythingmeaningfulbuthopefullyshorterthansubjectofthisemail

global fileformats

global numberOfSelectedFiles

global currentPath

global filesAndPathsT

numberOfSelectedFiles = 0

currentPath = ‘’

filesAndPathsT = []

MyTextDropTarget and dragAndDropMenu class select many files from different folders.

class MyTextDropTarget(wx.TextDropTarget):

def __init__(self, object):

    wx.TextDropTarget.__init__(self)

    self.object = object

    i=0

    global filesAndPathsT

    for [data,currentPath] in filesAndPathsT:

        data = data+'|'+currentPath

        self.object.InsertStringItem(i, data)

        i +=1


def OnDropText(self, x, y, data):

    global currentPath

    global filesAndPathsT

    global numberOfSelectedFiles

    if [data,currentPath] not in filesAndPathsT:

        filesAndPathsT.append([data,currentPath])

        data = data+'|'+currentPath

        self.object.InsertStringItem(numberOfSelectedFiles, data)

        numberOfSelectedFiles +=1

class dragAndDropMenu(wx.Frame):

def __init__(self, parent, id, title):

    global currentPath

    global numberOfSelectedFiles

    wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(690, 460))

    self.SetIcon(wx.Icon('ba.ico', wx.BITMAP_TYPE_ICO))

    panel = wx.Panel(self, -1)

    extensionLabel = wx.StaticText(panel, -1, 'Show files with extension.\nLeave blanc to show all files:')

    self.extension = wx.TextCtrl(panel, -1, 'txt', size = (23,20))

    self.dir = wx.GenericDirCtrl(panel, -1, dir='/home/', style=wx.DIRCTRL_DIR_ONLY, size = wx.Size(250, 400))

    self.dir.SetDefaultPath(self.dir.GetPath())

    tip_label = wx.StaticText(panel, -1, '  Select and drag files here.\n Press "Ctrl" to select many files.')

    self.files = wx.ListCtrl(panel, -1, style=wx.LC_LIST, size = wx.Size(170, 370))

    self.selected = wx.ListCtrl(panel, -1, style=wx.LC_LIST, size = wx.Size(220, 350))

    self.moreFiles = []

    self.diselected = []

    self.fileIndex = []

    hbox1 = wx.BoxSizer(wx.HORIZONTAL)

    vbox1 = wx.BoxSizer(wx.VERTICAL)

    vbox = wx.BoxSizer(wx.VERTICAL)

    hbox = wx.BoxSizer(wx.HORIZONTAL)

    self.clear = wx.Button(panel, -1, 'Clear All', size = wx.Size(100, 25))

    self.done = wx.Button(panel, -1, 'Done', size = wx.Size(50, 25))

    self.cancel = wx.Button(panel, -1, 'Cancel', size = wx.Size(50, 25))

    hbox1.Add(extensionLabel, 0, wx.ALIGN_CENTRE)

    hbox1.Add(self.extension, 0, wx.ALIGN_CENTRE)

    vbox1.Add(hbox1, 0, wx.ALIGN_CENTRE)

    vbox1.Add(self.files, 0, wx.ALIGN_CENTRE)

    vbox.Add(tip_label, 0, wx.ALIGN_CENTRE)

    vbox.Add(self.selected, 0, wx.ALIGN_CENTRE)

    hbox.Add(self.clear, 0, wx.ALIGN_CENTRE)

    hbox.Add(self.done, 0, wx.ALIGN_CENTRE)

    hbox.Add(self.cancel, 0, wx.ALIGN_CENTRE)

    vbox.Add(hbox, 0, wx.ALIGN_CENTRE)

    dt = MyTextDropTarget(self.selected)

    self.selected.SetDropTarget(dt)

    self.Bind(wx.EVT_CLOSE, self.OnClose)

    wx.EVT_LIST_BEGIN_DRAG(self, self.files.GetId(), self.OnDragInit)

    wx.EVT_LIST_ITEM_SELECTED(self, self.files.GetId(), self.OnSelectFile)

    wx.EVT_LIST_ITEM_DESELECTED(self, self.files.GetId(), self.OnDeselectFile)

    wx.EVT_LIST_ITEM_SELECTED(self, self.selected.GetId(), self.OnSelectSelectedFiles)

    wx.EVT_LIST_ITEM_DESELECTED(self, self.selected.GetId(), self.OnDeselectSelectedFiles)

    wx.EVT_BUTTON(self.clear, self.clear.GetId(), self.OnClearAll)

    wx.EVT_BUTTON(self.done, self.done.GetId(), self.OnDone)

    wx.EVT_BUTTON(self.cancel, self.cancel.GetId(), self.OnCancel)

    #wx.EVT_LIST_DELETE_ITEM(self, self.selected.GetId(), self.OnClearSelect)

    tree = self.dir.GetTreeCtrl()

    wx.EVT_TREE_SEL_CHANGED(self, tree.GetId(), self.OnSelectFolder)

    sizer = wx.FlexGridSizer(1, 3, 5, 5)

    sizer.AddMany((self.dir,vbox1,vbox))

    border = wx.BoxSizer()

    border.Add(sizer, 10, wx.ALL, 15)

    panel.SetSizer(border)

    self.Centre()

    #self.OnClearAll(None)

    #numberOfSelectedFiles = 0

    #currentPath = os.path.basename(currentPath)

    # this is not working. should set the trenutno path, not blank

    self.dir.SetDefaultPath(currentPath)


def OnSelectFolder(self, event, cdir = ''):

    global currentPath

    if cdir == '':

        currentPath = self.dir.GetPath()

    else:

        currentPath = cdir

    list = os.listdir(currentPath)

    self.files.ClearAll()

    fil = re.compile("."+str(self.extension.GetValue())+"$", re.IGNORECASE)

    filtered = filter(fil.search, list)

    for i in range(len(filtered)):

        self.files.InsertStringItem(0, filtered[i])

    self.moreFiles = []


def OnSelectFile(self, event):

    self.moreFiles.append(self.files.GetItemText(event.GetIndex()))



def OnDeselectFile(self, event):

    cur = self.files.GetItemText(event.GetIndex())

    if cur in self.moreFiles:

        self.moreFiles.remove(cur)


def OnSelectSelectedFiles(self, event):

    ind = (array(self.fileIndex)).searchsorted(event.GetIndex())

    self.diselected.insert(ind, self.selected.GetItemText(event.GetIndex()))

    self.fileIndex.insert(ind, event.GetIndex())

    if len(self.diselected) > 0:

        self.clear.SetLabel('Clear selection')

    else:

        self.clear.SetLabel('Clear All')



def OnDeselectSelectedFiles(self, event):

    cur = self.selected.GetItemText(event.GetIndex())

    if cur in self.diselected:

        self.fileIndex.remove(self.fileIndex[self.diselected.index(cur)])

        self.diselected.remove(cur)

    if len(self.diselected) > 0:

        self.clear.SetLabel('Clear selection')

    else:

        self.clear.SetLabel('Clear All')


def OnDragInit(self, event):

    for i in range(len(self.moreFiles)):

        text = self.moreFiles[i]

        tdo = wx.PyTextDataObject(text)

        tds = wx.DropSource(self.files)

        tds.SetData(tdo)

        tds.DoDragDrop(True)

        

def OnClearAll(self, event):

    if len(self.diselected)>0:

        self.OnClearSelected(None)

    else:

        global filesAndPathsT

        global numberOfSelectedFiles

        numberOfSelectedFiles = 0

        self.selected.ClearAll()

        filesAndPathsT = []


def OnClearSelected(self, event):

    global filesAndPathsT

    global numberOfSelectedFiles

    for i in range(len(self.diselected)-1,-1,-1):

        if self.diselected[i].split('|') in filesAndPathsT:

            filesAndPathsT.remove(self.diselected[i].split('|'))

            self.selected.DeleteItem(self.fileIndex[i])

            numberOfSelectedFiles -= 1

    self.diselected = []

    self.fileIndex = []

    self.clear.SetLabel('Clear All')


def OnDone(self, event):

    global filesAndPathsT

    ba.frame.filesAndPaths = filesAndPathsT[:]

    ba.frame.file_choice.SetValue(True)

    ba.frame.fileIndex = 0

    ba.frame.checkUserInput(self)

    ba.frame.Enable()

    self.Close(True)


def OnCancel(self, event):

    ba.frame.Enable()

    ba.frame.checkUserInput(self)

    self.Close(True)


def OnClose(self, event):

    ba.frame.Enable()

    ba.frame.checkUserInput(self)

    self.Destroy()

There it is. There are many places for improvement, like the appearance, which is in my opinion very ugly, but my main aim was functionality.

If you decide to fix this, let me know when you do, as I would like to see what will this become!

Take care

Lazar Kovacevic
inverudio.com

PS. i didn’t mention benefits of having this widget, but I think it is obvious.

Thanks for suggestion.

However, I don’t plan to maintain this widget for the time being, as currently I am very busy with other projects. I just wanted to show this code to others, as I think this widget can be very useful in certain applications, and with very little additional work it can become a part of wx library. Only part the needs some real work is appearance but I am sure for more experienced programmers and with use of layouts, that won’t be a problem. The ‘logic’ code can remain as it is with only minor changes. One feature I think is important to preserve, and that is ‘persistence’ of file list during application session (which I use in my application), or even persistence over different sessions by saving last used list in temp file. This can be done by passing current file list to widget when it is called (instead of using globals). This way, the next time widget is called, user has files from previous session already selected, and can just modify the selection.

Cheers,

Lazar

···

On 4/10/07, jupan ghe jupanghe1@gmail.com wrote:

Hi Lazarus,

I;m not an expert first of all.

I’m using only win2k and python 2.5 with wxpython 2.8.3 and Boa to design my GUIs.

In the Boa properties editor for almost all the widgets there is an option called enable system theme or operating system theme. In my case I tried to activate and I haven;t seen any difference but maybe on vista you will be able to see some difference.
I would start by looking at this flag called enable them or something similar.

Let me know if it helps some how,

With kind regards

On 4/10/07, Lazar Kovacevic lakinekaki@gmail.com wrote:

some may wonder why i didn’t use dictionary instead of list. well, because i needed an option to have files with same name from different folders. i know i could have had path+filename as unique key, but for some reason i decided to implement the way i did.

Lazar
On 4/10/07, Lazar Kovacevic < > > > > lakinekaki@gmail.com> wrote:

Huh!

Long name, but that is what it does. It select any number of files from any number of folders, and stores them in a list. Than, with all these files, you can do whatever you want in your application. You can see why I made this box, and how I use it here:

http://www.inverudio.com/programs/BiosAnalyzer/BiosAnalyzer.php

That is, if you have Windows, as for Linux I need to change the threading stuff, so that it could work (plot graphs).

Why I am submitting here, and not to SVN? Because, widget is not polished for library, and since I don’t have experience in writing libraries, I thought that someone on this list may know better how to encapsulate these two classes in the best way.

In particular, in my application, I use some globals, and for libraries, that is not acceptable, as far as I know. Code is below. Note that ‘ba.frame…’ stuff is my main application (BiosAnalyzer → ba), and I left it in this code so that you could see how I use this widget. To me it is not that obvious what functions and variables should be kept/added in order to make this widget most usable, and extensible. That is why I am showing it here to more experienced programmers.

#nameofthiswidgetcanbeanythingmeaningfulbuthopefullyshorterthansubjectofthisemail

global fileformats

global numberOfSelectedFiles

global currentPath

global filesAndPathsT

numberOfSelectedFiles = 0

currentPath = ‘’

filesAndPathsT =

MyTextDropTarget and dragAndDropMenu class select many files from different folders.

class MyTextDropTarget(wx.TextDropTarget):

def __init__(self, object):

    wx.TextDropTarget.__init__(self)

    self.object = object

    i=0

    global filesAndPathsT

    for [data,currentPath] in filesAndPathsT:

        data = data+'|'+currentPath

        self.object.InsertStringItem(i, data)

        i +=1


def OnDropText(self, x, y, data):

    global currentPath

    global filesAndPathsT

    global numberOfSelectedFiles

    if [data,currentPath] not in filesAndPathsT:

        filesAndPathsT.append([data,currentPath])

        data = data+'|'+currentPath

        self.object.InsertStringItem(numberOfSelectedFiles, data)

        numberOfSelectedFiles +=1

class dragAndDropMenu(wx.Frame):

def __init__(self, parent, id, title):

    global currentPath

    global numberOfSelectedFiles

    wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(690, 460))

    self.SetIcon(wx.Icon('ba.ico', wx.BITMAP_TYPE_ICO))

    panel = wx.Panel(self, -1)

    extensionLabel = wx.StaticText(panel, -1, 'Show files with extension.\nLeave blanc to show all files:')

    self.extension = wx.TextCtrl(panel, -1, 'txt', size = (23,20))

    self.dir = wx.GenericDirCtrl(panel, -1, dir='/home/', style=wx.DIRCTRL_DIR_ONLY, size = wx.Size(250, 400))

    self.dir.SetDefaultPath(self.dir.GetPath())

    tip_label = wx.StaticText(panel, -1, '  Select and drag files here.\n Press "Ctrl" to select many files.')

    self.files = wx.ListCtrl(panel, -1, style=wx.LC_LIST, size = wx.Size(170, 370))

    self.selected = wx.ListCtrl(panel, -1, style=wx.LC_LIST, size = wx.Size(220, 350))

    self.moreFiles = []

    self.diselected = []

    self.fileIndex = []

    hbox1 = wx.BoxSizer(wx.HORIZONTAL)

    vbox1 = wx.BoxSizer(wx.VERTICAL)

    vbox = wx.BoxSizer(wx.VERTICAL)

    hbox = wx.BoxSizer(wx.HORIZONTAL)

    self.clear = wx.Button(panel, -1, 'Clear All', size = wx.Size(100, 25))

    self.done = wx.Button(panel, -1, 'Done', size = wx.Size(50, 25))

    self.cancel = wx.Button(panel, -1, 'Cancel', size = wx.Size(50, 25))

    hbox1.Add(extensionLabel, 0, wx.ALIGN_CENTRE)

    hbox1.Add(self.extension, 0, wx.ALIGN_CENTRE)

    vbox1.Add(hbox1, 0, wx.ALIGN_CENTRE)

    vbox1.Add(self.files, 0, wx.ALIGN_CENTRE)

    vbox.Add(tip_label, 0, wx.ALIGN_CENTRE)

    vbox.Add(self.selected, 0, wx.ALIGN_CENTRE)

    hbox.Add(self.clear, 0, wx.ALIGN_CENTRE)

    hbox.Add(self.done, 0, wx.ALIGN_CENTRE)

    hbox.Add(self.cancel, 0, wx.ALIGN_CENTRE)

    vbox.Add(hbox, 0, wx.ALIGN_CENTRE)

    dt = MyTextDropTarget(self.selected)

    self.selected.SetDropTarget(dt)

    self.Bind(wx.EVT_CLOSE, self.OnClose)

    wx.EVT_LIST_BEGIN_DRAG(self, self.files.GetId(), self.OnDragInit)

    wx.EVT_LIST_ITEM_SELECTED(self, self.files.GetId(), self.OnSelectFile)

    wx.EVT_LIST_ITEM_DESELECTED(self, self.files.GetId(), self.OnDeselectFile)

    wx.EVT_LIST_ITEM_SELECTED(self, self.selected.GetId(), self.OnSelectSelectedFiles)

    wx.EVT_LIST_ITEM_DESELECTED(self, self.selected.GetId(), self.OnDeselectSelectedFiles)

    wx.EVT_BUTTON(self.clear, self.clear.GetId(), self.OnClearAll)

    wx.EVT_BUTTON(self.done, self.done.GetId(), self.OnDone)

    wx.EVT_BUTTON(self.cancel, self.cancel.GetId(), self.OnCancel)

    #wx.EVT_LIST_DELETE_ITEM(self, self.selected.GetId(), self.OnClearSelect)

    tree = self.dir.GetTreeCtrl()

    wx.EVT_TREE_SEL_CHANGED(self, tree.GetId(), self.OnSelectFolder)

    sizer = wx.FlexGridSizer(1, 3, 5, 5)

    sizer.AddMany((self.dir,vbox1,vbox))

    border = wx.BoxSizer()

    border.Add(sizer, 10, wx.ALL, 15)

    panel.SetSizer(border)

    self.Centre()

    #self.OnClearAll(None)

    #numberOfSelectedFiles = 0

    #currentPath = os.path.basename(currentPath)

    # this is not working. should set the trenutno path, not blank

    self.dir.SetDefaultPath(currentPath)


def OnSelectFolder(self, event, cdir = ''):

    global currentPath

    if cdir == '':

        currentPath = self.dir.GetPath()

    else:

        currentPath = cdir

    list = os.listdir(currentPath)

    self.files.ClearAll()

    fil = re.compile("."+str(self.extension.GetValue())+"$", re.IGNORECASE)

    filtered = filter(fil.search, list)

    for i in range(len(filtered)):

        self.files.InsertStringItem(0, filtered[i])

    self.moreFiles = []


def OnSelectFile(self, event):

    self.moreFiles.append(self.files.GetItemText(event.GetIndex()))



def OnDeselectFile(self, event):

    cur = self.files.GetItemText(event.GetIndex())

    if cur in self.moreFiles:

        self.moreFiles.remove(cur)


def OnSelectSelectedFiles(self, event):

    ind = (array(self.fileIndex)).searchsorted(event.GetIndex())

    self.diselected.insert(ind, self.selected.GetItemText(event.GetIndex()))

    self.fileIndex.insert(ind, event.GetIndex())

    if len(self.diselected) > 0:

        self.clear.SetLabel('Clear selection')

    else:

        self.clear.SetLabel('Clear All')



def OnDeselectSelectedFiles(self, event):

    cur = self.selected.GetItemText(event.GetIndex())

    if cur in self.diselected:

        self.fileIndex.remove(self.fileIndex[self.diselected.index(cur)])

        self.diselected.remove(cur)

    if len(self.diselected) > 0:

        self.clear.SetLabel('Clear selection')

    else:

        self.clear.SetLabel('Clear All')


def OnDragInit(self, event):

    for i in range(len(self.moreFiles)):

        text = self.moreFiles[i]

        tdo = wx.PyTextDataObject(text)

        tds = wx.DropSource(self.files)

        tds.SetData(tdo)

        tds.DoDragDrop(True)

        

def OnClearAll(self, event):

    if len(self.diselected)>0:

        self.OnClearSelected(None)

    else:

        global filesAndPathsT

        global numberOfSelectedFiles

        numberOfSelectedFiles = 0

        self.selected.ClearAll()

        filesAndPathsT = []


def OnClearSelected(self, event):

    global filesAndPathsT

    global numberOfSelectedFiles

    for i in range(len(self.diselected)-1,-1,-1):

        if self.diselected[i].split('|') in filesAndPathsT:

            filesAndPathsT.remove(self.diselected[i].split('|'))

            self.selected.DeleteItem(self.fileIndex[i])

            numberOfSelectedFiles -= 1

    self.diselected = []

    self.fileIndex = []

    self.clear.SetLabel('Clear All')


def OnDone(self, event):

    global filesAndPathsT

    ba.frame.filesAndPaths = filesAndPathsT[:]

    ba.frame.file_choice.SetValue(True)

    ba.frame.fileIndex = 0

    ba.frame.checkUserInput(self)

    ba.frame.Enable()

    self.Close(True)


def OnCancel(self, event):

    ba.frame.Enable()

    ba.frame.checkUserInput(self)

    self.Close(True)


def OnClose(self, event):

    ba.frame.Enable()

    ba.frame.checkUserInput(self)

    self.Destroy()

There it is. There are many places for improvement, like the appearance, which is in my opinion very ugly, but my main aim was functionality.

If you decide to fix this, let me know when you do, as I would like to see what will this become!

Take care

Lazar Kovacevic
inverudio.com

PS. i didn’t mention benefits of having this widget, but I think it is obvious.

I just wanted to ask you if I reinvented a wheel!

NameBright - Coming Soon

Do I understand well that there is an option in FileDialog class for
selection of many files from many folders? If yes, than I just wasted time
with this widget :frowning:
Also, if it is the case, I wish someone here had pointed that out to me.

There is an option to select multiple files from the dialog, but it
basically only allows you to select multiple files from a single path.
If you need to select multiple files from multiple paths, then aside
from just embedding a filesystem browser in your application (something
I've done before), your widget is the only thing out there.

- Josiah

···

"Lazar Kovacevic" <lakinekaki@gmail.com> wrote:

On 4/10/07, Lazar Kovacevic <lakinekaki@gmail.com> wrote:
>
> Thanks for suggestion.
>
> However, I don't plan to maintain this widget for the time being, as
> currently I am very busy with other projects. I just wanted to show this
> code to others, as I think this widget can be very useful in certain
> applications, and with very little additional work it can become a part of
> wx library. Only part the needs some real work is appearance but I am sure
> for more experienced programmers and with use of layouts, that won't be a
> problem. The 'logic' code can remain as it is with only minor changes. One
> feature I think is important to preserve, and that is 'persistence' of file
> list during application session (which I use in my application), or even
> persistence over different sessions by saving last used list in temp file.
> This can be done by passing current file list to widget when it is called
> (instead of using globals). This way, the next time widget is called, user
> has files from previous session already selected, and can just modify the
> selection.
>
> Cheers,
>
> Lazar
>
> On 4/10/07, jupan ghe <jupanghe1@gmail.com> wrote:
> >
> > Hi Lazarus,
> >
> > I;m not an expert first of all.
> >
> > I'm using only win2k and python 2.5 with wxpython 2.8.3 and Boa to
> > design my GUIs.
> >
> > In the Boa properties editor for almost all the widgets there is an
> > option called enable system theme or operating system theme. In my case I
> > tried to activate and I haven;t seen any difference but maybe on vista you
> > will be able to see some difference.
> > I would start by looking at this flag called enable them or something
> > similar.
> >
> > Let me know if it helps some how,
> >
> > With kind regards
> >
> >
> > On 4/10/07, Lazar Kovacevic <lakinekaki@gmail.com> wrote:
> > >
> > > some may wonder why i didn't use dictionary instead of list. well,
> > > because i needed an option to have files with same name from different
> > > folders. i know i could have had path+filename as unique key, but for some
> > > reason i decided to implement the way i did.
> > >
> > > Lazar
> > >
> > > On 4/10/07, Lazar Kovacevic < lakinekaki@gmail.com> wrote:
> > > >
> > > > Huh!
> > > >
> > > > Long name, but that is what it does. It select any number of files
> > > > from any number of folders, and stores them in a list. Than, with all these
> > > > files, you can do whatever you want in your application. You can see why I
> > > > made this box, and how I use it here:
> > > >
> > > > Free time series data analysis software
> > > >
> > > > That is, if you have Windows, as for Linux I need to change the
> > > > threading stuff, so that it could work (plot graphs).
> > > >
> > > > Why I am submitting here, and not to SVN? Because, widget is not
> > > > polished for library, and since I don't have experience in writing
> > > > libraries, I thought that someone on this list may know better how to
> > > > encapsulate these two classes in the best way.
> > > >
> > > > In particular, in my application, I use some globals, and for
> > > > libraries, that is not acceptable, as far as I know. Code is below. Note
> > > > that 'ba.frame...' stuff is my main application (BiosAnalyzer ->
> > > > ba), and I left it in this code so that you could see how I use this widget.
> > > > To me it is not that obvious what functions and variables should be
> > > > kept/added in order to make this widget most usable, and extensible. That is
> > > > why I am showing it here to more experienced programmers.
> > > >
> > > >
> > > > #nameofthiswidgetcanbeanythingmeaningfulbuthopefullyshorterthansubjectofthisemail
> > > >
> > > > global fileformats
> > > > global numberOfSelectedFiles
> > > > global currentPath
> > > > global filesAndPathsT
> > > > numberOfSelectedFiles = 0
> > > > currentPath = ''
> > > > filesAndPathsT =
> > > >
> > > > # MyTextDropTarget and dragAndDropMenu class select many files from
> > > > different folders.
> > > > class MyTextDropTarget(wx.TextDropTarget):
> > > >
> > > > def __init__(self, object):
> > > > wx.TextDropTarget.__init__(self)
> > > > self.object = object
> > > > i=0
> > > > global filesAndPathsT
> > > > for [data,currentPath] in filesAndPathsT:
> > > > data = data+'|'+currentPath
> > > > self.object.InsertStringItem(i, data)
> > > > i +=1
> > > >
> > > > def OnDropText(self, x, y, data):
> > > > global currentPath
> > > > global filesAndPathsT
> > > > global numberOfSelectedFiles
> > > > if [data,currentPath] not in filesAndPathsT:
> > > > filesAndPathsT.append([data,currentPath])
> > > > data = data+'|'+currentPath
> > > > self.object.InsertStringItem(numberOfSelectedFiles,
> > > > data)
> > > > numberOfSelectedFiles +=1
> > > >
> > > >
> > > > class dragAndDropMenu(wx.Frame):
> > > >
> > > > def __init__(self, parent, id, title):
> > > > global currentPath
> > > > global numberOfSelectedFiles
> > > > wx.Frame.__init__(self, parent, id, title,
> > > > wx.DefaultPosition, wx.Size(690, 460))
> > > > self.SetIcon(wx.Icon('ba.ico', wx.BITMAP_TYPE_ICO))
> > > > panel = wx.Panel(self, -1)
> > > > extensionLabel = wx.StaticText(panel, -1, 'Show files with
> > > > extension.\nLeave blanc to show all files:')
> > > > self.extension = wx.TextCtrl(panel, -1, 'txt', size =
> > > > (23,20))
> > > > self.dir = wx.GenericDirCtrl(panel, -1, dir='/home/', style=
> > > > wx.DIRCTRL_DIR_ONLY, size = wx.Size(250, 400))
> > > > self.dir.SetDefaultPath(self.dir.GetPath())
> > > > tip_label = wx.StaticText(panel, -1, ' Select and drag
> > > > files here.\n Press "Ctrl" to select many files.')
> > > > self.files = wx.ListCtrl(panel, -1, style=wx.LC_LIST, size =
> > > > wx.Size(170, 370))
> > > > self.selected = wx.ListCtrl(panel, -1, style=wx.LC_LIST,
> > > > size = wx.Size(220, 350))
> > > > self.moreFiles =
> > > > self.diselected =
> > > > self.fileIndex =
> > > > hbox1 = wx.BoxSizer(wx.HORIZONTAL)
> > > > vbox1 = wx.BoxSizer(wx.VERTICAL)
> > > > vbox = wx.BoxSizer(wx.VERTICAL)
> > > > hbox = wx.BoxSizer(wx.HORIZONTAL)
> > > > self.clear = wx.Button(panel, -1, 'Clear All', size =
> > > > wx.Size(100, 25))
> > > > self.done = wx.Button(panel, -1, 'Done', size = wx.Size(50,
> > > > 25))
> > > > self.cancel = wx.Button(panel, -1, 'Cancel', size = wx.Size(50,
> > > > 25))
> > > > hbox1.Add(extensionLabel, 0, wx.ALIGN_CENTRE)
> > > > hbox1.Add(self.extension, 0, wx.ALIGN_CENTRE)
> > > > vbox1.Add(hbox1, 0, wx.ALIGN_CENTRE)
> > > > vbox1.Add(self.files, 0, wx.ALIGN_CENTRE)
> > > > vbox.Add(tip_label, 0, wx.ALIGN_CENTRE)
> > > > vbox.Add(self.selected, 0, wx.ALIGN_CENTRE)
> > > > hbox.Add(self.clear, 0, wx.ALIGN_CENTRE)
> > > > hbox.Add(self.done, 0, wx.ALIGN_CENTRE)
> > > > hbox.Add(self.cancel, 0, wx.ALIGN_CENTRE)
> > > > vbox.Add(hbox, 0, wx.ALIGN_CENTRE)
> > > > dt = MyTextDropTarget(self.selected)
> > > > self.selected.SetDropTarget(dt)
> > > > self.Bind(wx.EVT_CLOSE, self.OnClose)
> > > > wx.EVT_LIST_BEGIN_DRAG(self, self.files.GetId(),
> > > > self.OnDragInit)
> > > > wx.EVT_LIST_ITEM_SELECTED(self, self.files.GetId(),
> > > > self.OnSelectFile)
> > > > wx.EVT_LIST_ITEM_DESELECTED(self, self.files.GetId(),
> > > > self.OnDeselectFile)
> > > > wx.EVT_LIST_ITEM_SELECTED(self, self.selected.GetId(),
> > > > self.OnSelectSelectedFiles)
> > > > wx.EVT_LIST_ITEM_DESELECTED(self, self.selected.GetId(),
> > > > self.OnDeselectSelectedFiles)
> > > > wx.EVT_BUTTON(self.clear, self.clear.GetId(),
> > > > self.OnClearAll)
> > > > wx.EVT_BUTTON(self.done, self.done.GetId(), self.OnDone)
> > > > wx.EVT_BUTTON(self.cancel, self.cancel.GetId(),
> > > > self.OnCancel)
> > > > #wx.EVT_LIST_DELETE_ITEM(self, self.selected.GetId(),
> > > > self.OnClearSelect)
> > > > tree = self.dir.GetTreeCtrl()
> > > > wx.EVT_TREE_SEL_CHANGED(self, tree.GetId(),
> > > > self.OnSelectFolder)
> > > > sizer = wx.FlexGridSizer(1, 3, 5, 5)
> > > > sizer.AddMany((self.dir,vbox1,vbox))
> > > > border = wx.BoxSizer()
> > > > border.Add(sizer, 10, wx.ALL, 15)
> > > > panel.SetSizer(border)
> > > > self.Centre()
> > > > #self.OnClearAll(None)
> > > > #numberOfSelectedFiles = 0
> > > > #currentPath = os.path.basename(currentPath)
> > > > # this is not working. should set the trenutno path, not
> > > > blank
> > > > self.dir.SetDefaultPath(currentPath)
> > > >
> > > > def OnSelectFolder(self, event, cdir = ''):
> > > > global currentPath
> > > > if cdir == '':
> > > > currentPath = self.dir.GetPath()
> > > > else:
> > > > currentPath = cdir
> > > > list = os.listdir(currentPath)
> > > > self.files.ClearAll()
> > > > fil = re.compile("."+str(self.extension.GetValue())+"$",
> > > > re.IGNORECASE)
> > > > filtered = filter(fil.search, list)
> > > > for i in range(len(filtered)):
> > > > self.files.InsertStringItem(0, filtered[i])
> > > > self.moreFiles =
> > > >
> > > > def OnSelectFile(self, event):
> > > > self.moreFiles.append(self.files.GetItemText(event.GetIndex()))
> > > >
> > > >
> > > > def OnDeselectFile(self, event):
> > > > cur = self.files.GetItemText(event.GetIndex())
> > > > if cur in self.moreFiles:
> > > > self.moreFiles.remove(cur)
> > > >
> > > > def OnSelectSelectedFiles(self, event):
> > > > ind = (array(self.fileIndex)).searchsorted(event.GetIndex())
> > > >
> > > > self.diselected.insert(ind, self.selected.GetItemText(
> > > > event.GetIndex()))
> > > > self.fileIndex.insert(ind, event.GetIndex())
> > > > if len(self.diselected) > 0:
> > > > self.clear.SetLabel('Clear selection')
> > > > else:
> > > > self.clear.SetLabel('Clear All')
> > > >
> > > > def OnDeselectSelectedFiles(self, event):
> > > > cur = self.selected.GetItemText(event.GetIndex())
> > > > if cur in self.diselected:
> > > > self.fileIndex.remove(self.fileIndex[
> > > > self.diselected.index(cur)])
> > > > self.diselected.remove(cur)
> > > > if len(self.diselected) > 0:
> > > > self.clear.SetLabel('Clear selection')
> > > > else:
> > > > self.clear.SetLabel('Clear All')
> > > >
> > > > def OnDragInit(self, event):
> > > > for i in range(len(self.moreFiles)):
> > > > text = self.moreFiles[i]
> > > > tdo = wx.PyTextDataObject(text)
> > > > tds = wx.DropSource(self.files)
> > > > tds.SetData(tdo)
> > > > tds.DoDragDrop(True)
> > > >
> > > > def OnClearAll(self, event):
> > > > if len(self.diselected)>0:
> > > > self.OnClearSelected(None)
> > > > else:
> > > > global filesAndPathsT
> > > > global numberOfSelectedFiles
> > > > numberOfSelectedFiles = 0
> > > > self.selected.ClearAll()
> > > > filesAndPathsT =
> > > >
> > > > def OnClearSelected(self, event):
> > > > global filesAndPathsT
> > > > global numberOfSelectedFiles
> > > > for i in range(len(self.diselected)-1,-1,-1):
> > > > if self.diselected[i].split('|') in filesAndPathsT:
> > > > filesAndPathsT.remove(self.diselected[i].split('|'))
> > > >
> > > > self.selected.DeleteItem(self.fileIndex[i])
> > > > numberOfSelectedFiles -= 1
> > > > self.diselected =
> > > > self.fileIndex =
> > > > self.clear.SetLabel('Clear All')
> > > >
> > > > def OnDone(self, event):
> > > > global filesAndPathsT
> > > > ba.frame.filesAndPaths = filesAndPathsT[:]
> > > > ba.frame.file_choice.SetValue(True)
> > > > ba.frame.fileIndex = 0
> > > > ba.frame.checkUserInput(self)
> > > > ba.frame.Enable()
> > > > self.Close(True)
> > > >
> > > > def OnCancel(self, event):
> > > > ba.frame.Enable()
> > > > ba.frame.checkUserInput(self)
> > > > self.Close(True)
> > > >
> > > > def OnClose(self, event):
> > > > ba.frame.Enable()
> > > > ba.frame.checkUserInput(self)
> > > > self.Destroy()
> > > >
> > > >
> > > >
> > > >
> > > >
> > > > There it is. There are many places for improvement, like the
> > > > appearance, which is in my opinion very ugly, but my main aim was
> > > > functionality.
> > > >
> > > > If you decide to fix this, let me know when you do, as I would like
> > > > to see what will this become!
> > > >
> > > > Take care
> > > >
> > > > Lazar Kovacevic
> > > > inverudio.com
> > > >
> > > > PS. i didn't mention benefits of having this widget, but I think it
> > > > is obvious.
> > > >
> > >
> > >
> >
>

--
Lazar

www.inverudio.com
www.explore-ideas.com