browser.py :  » Network » FtpCube » ftpcube-0.5.1 » libftpcube » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Network » FtpCube 
FtpCube » ftpcube 0.5.1 » libftpcube » browser.py
"""
FtpCube
Copyright (C) Michael Gilfix

This file is part of FtpCube.

You should have received a file COPYING containing license terms
along with this program; if not, write to Michael Gilfix
(mgilfix@eecs.tufts.edu) for a copy.

This version of FtpCube is open source; you can redistribute it and/or
modify it under the terms listed in the file COPYING.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
"""

import dialog
import utils
import icons.folder

import wx

import os

class Browser(dialog.DialogWindow):
    """An abstract base class for a directory browsing windows.

    A browser window provides a directory navigation tree structure for navigating
    directory structures. This is a custom widget that allows for a consistent look
    and feel between browsing local directories and the remote directory cache.
    This window uses a tree structure to represent the directory folders, where each
    directory folder can then be expanded."""

    idTREE = wx.NewId()

    def __init__(self, parent, title):
        """Creates a new browser instance.

        This constructs the tree view, populated with directory icon."""
        dialog.DialogWindow.__init__(self, parent, title)
        self.SetIcon(utils.getAppIcon())

        panel = self.getDialogPanel()
        label = wx.StaticText(panel, -1, _("Directory:"))
        self.dir_entry = wx.TextCtrl(panel, -1)
        dsizer = wx.FlexGridSizer(5, 3)
        dsizer.AddMany([
            ((20, 5)), (label, 0, wx.EXPAND), ((20, 5)),
            ((20, 5)), ((20, 5)), ((20, 5)),
            ((20, 5)), (self.dir_entry, 1, wx.EXPAND), ((20, 5)),
        ])
        dsizer.AddGrowableCol(1)

        self.tree = wx.TreeCtrl(panel, self.idTREE, style=wx.SUNKEN_BORDER | wx.TR_HAS_BUTTONS)
        self.image_list = wx.ImageList(15, 17)
        self.folder_index = self.image_list.Add(icons.folder.getBitmap())
        self.tree.SetImageList(self.image_list)
        tsizer = wx.BoxSizer(wx.HORIZONTAL)
        tsizer.Add((15, 5))
        tsizer.Add(self.tree, 1, wx.EXPAND)
        tsizer.Add((10, 5))

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add((5, 5))
        sizer.Add(dsizer, 0, wx.EXPAND)
        sizer.Add((5, 10))
        sizer.Add(tsizer, 1, wx.EXPAND)
        sizer.Add((5, 5))
        panel.SetAutoLayout(True)
        panel.SetSizer(sizer)
        sizer.Fit(panel)
        sizer.SetSizeHints(panel)

        # Render the dialog buttons and set the sizers
        self.renderDialog()
        self.SetSize((400, 350))

        self.Bind(wx.EVT_TREE_SEL_CHANGED, self.onTreeSelect, id=self.idTREE)

    def getDirectory(self):
        """Returns the directory whose contents is represented by the browser."""
        return self.dir_entry.GetValue()

    def onTreeSelect(self, event):
        """Handles the selection of a tree element."""
        raise NotImplementedError

class LocalBrowser(Browser):
    """A local directory browser.

    Provides tree navigation of the local filesystem. All directory nodes are expandable.
    No files are shown. The directory entry box allows for typing in the current directory
    directly and is updated during browsing of the filesystem."""

    def __init__(self, parent, path):
        """Creates the local browser window, starting at the specified path."""
        Browser.__init__(self, parent, _("Ftpcube - Change Local Directory"))

        self.root = self.tree.AddRoot(os.sep, self.folder_index, self.folder_index)
        self.loadTree(path, self.root)

        # Set the entry box to the starting path
        self.dir_entry.SetValue(path)

    def loadTree(self, path, parent):
        """Loads the tree structure up to the current path.

        This loads all directories higher in the hierarchy for the current directory, as
        is typically done in such browsing widgets for OS UIs. If the supplied path points
        to a file, then the parent directory for the file is used."""
        if not os.path.isdir(path):
            path = os.path.dirname(path)

        # Create a list of paths to cycle through
        dirs = path.split(os.sep)
        dirs[0] = os.sep

        cur_path = os.sep
        parent_list = [ parent ]
        while dirs:
            dir = dirs.pop(0)
            cur_path = os.path.join(cur_path, dir)
            listing = self.getDirectoryList(cur_path)

            new_parent = None
            for item in listing:
                node = self.tree.AppendItem(parent, item, self.folder_index, self.folder_index)
                if dirs and item == dirs[0]:
                    new_parent = node

            if new_parent is not None:
                parent = new_parent
                parent_list.append(parent)

        # Expand all parents
        for p in parent_list:
            self.tree.Expand(p)

    def getDirectoryList(self, path):
        """Gets the listing of directories within the specified path."""
        try:
            listing = os.listdir(path)
        except OSError, strerror:
            return [ ]
        listing = [ x for x in listing
                      if os.path.isdir(os.path.join(path, x)) ]
        return listing

    def onTreeSelect(self, event):
        """Handles the selection of a directory within the directory tree.

        This updates the directory entry box to reflect the selected directory.
        This also expands sub-nodes if need be."""
        node = event.GetItem()
        path = self.nodeToPath(node)
        self.dir_entry.SetValue(path)
        if not self.tree.GetChildrenCount(node):
            self.expandNode(node, path)
            self.tree.Expand(node)

    def expandNode(self, parent, path):
        """Expands a directory node within the tree."""
        listing = self.getDirectoryList(path)
        self.tree.Freeze()
        for item in listing:
            node = self.tree.AppendItem(parent, item, self.folder_index, self.folder_index)
        self.tree.Thaw()

    def nodeToPath(self, node):
        """Returns the path to the specified node within the directory tree."""
        path = [ ]
        while node != self.root:
            path.insert(0, self.tree.GetItemText(node))
            node = self.tree.GetItemParent(node)
        path = os.sep + os.sep.join(path)
        return path

class RemoteBrowser(Browser):
    """Remotes site directory browser.

    This widget makes use of the directory cache in order to render a tree of known remote
    directories. Only the directories that are held in the cache are displayed (meaning that
    the displayed tree is not complete). For directories that are in the cache, they can be
    expanded and contracted like regular directories."""

    def __init__(self, parent, cache, path):
        """Creates the remote directory browser window using the specified cache.

        The specified path is used as the starting point in the cache hierarchy. The
        directory text box is updated to the starting specified path."""
        Browser.__init__(self, parent, _("Ftpcube - Change Remote Directory"))
        self.cache = cache

        # Load the tree contents
        cache_delim = self.cache.getDelimiter()
        self.root = self.tree.AddRoot(cache_delim, self.folder_index, self.folder_index)
        self.loadTree(self.cache.getRoot(), self.root)
        self.expandPath(path)

        # Set the entry box to the starting path
        self.dir_entry.SetValue(path)

    def onTreeSelect(self, event):
        """Handles the selection of a directory within the directory tree.

        This updates the directory entry box to reflect the selected directory.
        This also expands sub-nodes if need be."""
        node = event.GetItem()
        path = self.nodeToPath(node)
        self.dir_entry.SetValue(path)
        if not self.tree.GetChildrenCount(node):
            self.expandPath(path)

    def loadTree(self, node, parent):
        """Recursively loads the tree from the specified cache node entry.

        Parent refers to the parent widget whose sub-directories are to be populated with the
        contents of the cache. It is possible that elements of the cache will have None data
        elements. This can occur when the cache is explicitly cleared and the cached data is
        not in synch with the current directory depth. When that happens, the path should be
        used to fill in whatever blanks are known."""
        if node.data is not None:
            directories = [ x[0] for x in node.data
                              if not x[0] == '..' and x[3][0] == 'd' ]
        else:
            directories = self.cache.getChildren(node)
            if directories is None:
                return

        for dir_name in directories:
            insert_node = self.tree.AppendItem(parent, dir_name, self.folder_index,
                self.folder_index)
            child = self.cache.getChildNode(node, dir_name)
            if child is not None:
                self.loadTree(child, insert_node)

    def nodeToPath(self, node):
        """Returns the path to the specified node within the directory tree."""
        path = [ ]
        while node != self.root:
            path.insert(0, self.tree.GetItemText(node))
            node = self.tree.GetItemParent(node)
        delim = self.cache.getDelimiter()
        path = self.tree.GetItemText(self.root) + delim.join(path)
        return path

    def expandPath(self, path):
        """Expands all directory elements in the cache on the way to the specified path."""
        path = [ x for x in path.split(self.cache.getDelimiter()) if x ]
        self.tree.Expand(self.root)
        if not path:
            return

        node = self.root
        for node_name in path:
            # Extract the children from the tree
            children = [ ]
            child, cookie = self.tree.GetFirstChild(node)
            while child.IsOk():
                children.append(child)
                child, cookie = self.tree.GetNextChild(node, cookie)

            # Expand the appropriate child
            child_names = [ self.tree.GetItemText(x) for x in children ]
            try:
                child_index = child_names.index(node_name)
            except ValueError:
                return None
            node = children[child_index]
            self.tree.Expand(node)
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.