bookmarkwin.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 » bookmarkwin.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 connectwin
import bookmark
import messages
import utils
import icons.folder
import icons.quick_connect
import icons.add_folder
import icons.add_bookmark
import icons.edit_bookmark

import wx

import os

class BookmarkWindow(wx.Frame):
    """Bookmark management window.

    This window allows for the management of connection bookmarks. Bookmarks consist
    of files storing connection information for later reconnecting to the same file
    transfer site. Bookmarks can have hierarchical, directory structure organization,
    and are managed within an actual filesystem directory structure. All paths supplied
    to the bookmark manager are relative.

    The bookmark window interacts with the connection window to provide an interface
    for specifying connection options. This also allows a short-cut to initiating
    connections directly from a bookmark."""

    # Menu IDs
    idCONNECT         = wx.NewId()
    idFOLDER_ADD      = wx.NewId()
    idFOLDER_RENAME   = wx.NewId()
    idFOLDER_DELETE   = wx.NewId()
    idBOOKMARK_ADD    = wx.NewId()
    idBOOKMARK_EDIT   = wx.NewId()
    idBOOKMARK_RENAME = wx.NewId()
    idBOOKMARK_DELETE = wx.NewId()

    # Toolbar IDs
    idTOOL_CONNECT      = wx.NewId()
    idTOOL_ADDFOLDER    = wx.NewId()
    idTOOL_ADDBOOKMARK  = wx.NewId()
    idTOOL_EDITBOOKMARK = wx.NewId()

    idTREE = wx.NewId()

    # Popup Menu IDs
    idPOPUP_RENAMEFOLDER   = wx.NewId()
    idPOPUP_DELETEFOLDER   = wx.NewId()
    idPOPUP_EDITBOOKMARK   = wx.NewId()
    idPOPUP_RENAMEBOOKMARK = wx.NewId()
    idPOPUP_DELETEBOOKMARK = wx.NewId()

    def __init__(self, parent):
        """Creates and displays the bookmark window.

        This initializes the bookmark manager and initializes the bookmark tree navigation
        view."""
        wx.Frame.__init__(self, parent, -1, _("Ftpcube - Bookmarks"))
        self.SetIcon(utils.getAppIcon())
        self.SetSize((750, 500))
        self.headers = [ _("Description"), _("Host"), _("Username"), _("Directory") ]

        self.makeMenu()
        self.makeToolBar()

        # Create the tree and bookmark list
        splitter = wx.SplitterWindow(self, -1, style=wx.SP_3D)
        self.tree = wx.TreeCtrl(splitter, self.idTREE)
        self.list = wx.ListCtrl(splitter, -1, style=wx.LC_REPORT)
        splitter.SplitVertically(self.tree, self.list, 200)

        # Set up the tree images
        self.image_list = wx.ImageList(15, 17)
        self.folder_index = self.image_list.Add(icons.folder.getBitmap())
        self.tree.SetImageList(self.image_list)

        # Set up the list columns
        for col, name in zip(range(len(self.headers)), self.headers):
            self.list.InsertColumn(col, name)
        self.list.SetColumnWidth(0, 200)
        self.list.SetColumnWidth(1, 175)
        self.list.SetColumnWidth(2, 100)
        self.list.SetColumnWidth(3, 200)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(splitter, 1, wx.EXPAND)
        self.SetAutoLayout(True)
        self.SetSizer(sizer)

        self.Center()

        try:
            self.bookmark = bookmark.BookmarkManager()
        except bookmark.BookmarkException, strerror:
            messages.displayErrorDialog(self, strerror)
        self.root = self.tree.AddRoot(self.bookmark.BOOKMARK_DIRECTORY, self.folder_index,
            self.folder_index)
        self.loadBookmarkTree(self.bookmark.getBookmarkDirectory(), self.root)

        # Bind tree events
        self.Bind(wx.EVT_TREE_SEL_CHANGED, self.onTreeSelect, self.tree)

        # Bind popup menus
        self.tree.Bind(wx.EVT_RIGHT_DOWN, self.onTreeRightClick)
        self.list.Bind(wx.EVT_RIGHT_DOWN, self.onListRightClick)

        # Register double click to connect to bookmark
        self.list.Bind(wx.EVT_LEFT_DCLICK, self.onConnect)

        # Display the root directory
        self.displayBookmarks()

    def makeMenu(self):
        """Constructs the main menu bar."""
        self.menu_bar = wx.MenuBar()
        self.menu_bar.Append(self.createSiteMenu(), _("&Site"))
        self.menu_bar.Append(self.createEditMenu(), _("&Edit"))
        self.SetMenuBar(self.menu_bar)

    def createSiteMenu(self):
        """Creates the site management menu."""
        site_menu = wx.Menu()
        site_menu.Append(self.idCONNECT, _("&Connect"), _("Connect to Bookmarked Site"))
        self.Bind(wx.EVT_MENU, self.onConnect, id=self.idCONNECT)
        return site_menu

    def createEditMenu(self):
        """Creates the bookmark edit menu."""
        edit_menu = wx.Menu()
        edit_menu.Append(self.idFOLDER_ADD, _("Add &Folder"), _("Add a Bookmark Folder"))
        edit_menu.Append(self.idFOLDER_RENAME, _("Rename Folder"),
            _("Rename a Bookmark Folder"))
        edit_menu.Append(self.idFOLDER_DELETE, _("Delete Folder"),
            _("Delete a Bookmark Folder"))
        edit_menu.AppendSeparator()
        edit_menu.Append(self.idBOOKMARK_ADD, _("Add &Bookmark"), _("Add a New Bookmark"))
        edit_menu.Append(self.idBOOKMARK_EDIT, _("&Edit Bookmark"),
            _("Edit an Existing Bookmark"))
        edit_menu.Append(self.idBOOKMARK_DELETE, _("Delete Bookmark"),
            _("Delete Selected Bookmark"))

        self.Bind(wx.EVT_MENU, self.onFolderAdd, id=self.idFOLDER_ADD)
        self.Bind(wx.EVT_MENU, self.onFolderRename, id=self.idFOLDER_RENAME)
        self.Bind(wx.EVT_MENU, self.onFolderDelete, id=self.idFOLDER_DELETE)
        self.Bind(wx.EVT_MENU, self.onBookmarkAdd, id=self.idBOOKMARK_ADD)
        self.Bind(wx.EVT_MENU, self.onBookmarkEdit, id=self.idBOOKMARK_EDIT)
        self.Bind(wx.EVT_MENU, self.onBookmarkRename, id=self.idBOOKMARK_RENAME)
        self.Bind(wx.EVT_MENU, self.onBookmarkDelete, id=self.idBOOKMARK_DELETE)

        return edit_menu

    def makeToolBar(self):
        """Creates the toolbar."""
        toolbar = self.CreateToolBar()
        toolbar.SetToolBitmapSize(wx.Size(32, 32))

        bitmap = icons.quick_connect.getBitmap()
        toolbar.AddSimpleTool(self.idTOOL_CONNECT, bitmap, shortHelpString=_("Connect"))
        utils.addLineSeparator(toolbar, 16)

        bitmap = icons.add_folder.getBitmap()
        toolbar.AddSimpleTool(self.idTOOL_ADDFOLDER, bitmap, shortHelpString=_("Add Folder"))
        bitmap = icons.add_bookmark.getBitmap()
        toolbar.AddSimpleTool(self.idTOOL_ADDBOOKMARK, bitmap,
            shortHelpString=_("Add Bookmark"))
        bitmap = icons.edit_bookmark.getBitmap()
        toolbar.AddSimpleTool(self.idTOOL_EDITBOOKMARK, bitmap,
            shortHelpString=_("Edit Bookmark"))

        self.Bind(wx.EVT_TOOL, self.onConnect, id=self.idTOOL_CONNECT)
        self.Bind(wx.EVT_TOOL, self.onFolderAdd, id=self.idTOOL_ADDFOLDER)
        self.Bind(wx.EVT_TOOL, self.onBookmarkAdd, id=self.idTOOL_ADDBOOKMARK)
        self.Bind(wx.EVT_TOOL, self.onBookmarkEdit, id=self.idTOOL_EDITBOOKMARK)

        toolbar.Realize()

    def onTreeRightClick(self, event):
        """Process a right click on the bookmark tree by displaying the tree popup
        menu."""
        menu = self.makeTreePopupMenu()
        self.tree.PopupMenu(menu, event.GetPosition())

    def makeTreePopupMenu(self):
        """Creates the right-click menu for operations on the bookmark folder tree."""
        menu = wx.Menu()
        menu.Append(self.idPOPUP_RENAMEBOOKMARK, _("Rename Folder"))
        menu.Append(self.idPOPUP_DELETEFOLDER, _("Delete Folder"))
        self.Bind(wx.EVT_MENU, self.onFolderRename, id=self.idPOPUP_RENAMEBOOKMARK)
        self.Bind(wx.EVT_MENU, self.onFolderDelete, id=self.idPOPUP_DELETEFOLDER)

    def onListRightClick(self, event):
        """Processes a right click on a list of bookmarks."""
        menu = self.makeListPopupMenu()
        self.list.PopupMenu(menu, event.GetPosition())

    def makeListPopupMenu(self):
        """Creates the right-click menu for a bookmark list."""
        menu = wx.Menu()
        menu.Append(self.idPOPUP_EDITBOOKMARK, _("Edit Bookmark"))
        menu.Append(self.idPOPUP_RENAMEBOOKMARK, _("Rename Bookmark"))
        menu.Append(self.idPOPUP_DELETEBOOKMARK, _("Delete Bookmark"))
        self.Bind(wx.EVT_MENU, self.onBookmarkEdit, id=self.idPOPUP_EDITBOOKMARK)
        self.Bind(wx.EVT_MENU, self.onBookmarkRename, id=self.idPOPUP_RENAMEBOOKMARK)
        self.Bind(wx.EVT_MENU, self.onBookmarkDelete, id=self.idPOPUP_DELETEBOOKMARK)

    def onConnect(self, event):
        """Processes a connect event for a bookmark.

        This initiates an FTP connect to the bookmark for which the event occurred.
        The bookmark is the selected bookmark within the list. This closes the
        bookmark window and brings the user back to the main window, where the
        connection to the bookmarked site is initiated."""
        path = self.getPathToCurrentNode()
        selected = utils.getSelected(self.list)
        if not selected:
            return
        selected = selected.pop(0)
        name = utils.getColumnText(self.list, selected, 0)
        book_file = os.path.join(path, name)
        try:
            book_opts = self.bookmark.loadBookmark(book_file)
        except bookmark.BookmarkException, strerror:
            messages.displayErrorDialog(self, _("Error loading bookmark: %(err)s")
                %{ 'err' : strerror })
            return

        # Disconnect if necessary
        thread_mgr = utils.getAppThreadManager()
        main_window = utils.getMainWindow()
        if thread_mgr.getMainThread():
            if not main_window.promptDisconnect():
                return
            main_window.onDisconnect(event)

        parent = self.GetParent()
        self.Destroy()
        connect = connectwin.ConnectionWindow(parent, book_opts)
        ret = connect.ShowModal()
        if ret == wx.ID_OK:
            connect_opts = connect.getOptions()
            if connect_opts['host'] and connect_opts['port']:
                utils.initiateConnection(connect_opts)
            else:
                messages.displayErrorDialog(utils.getMainWindow(),
                    _("A hostname and port must be supplied"))

    def onFolderAdd(self, event):
        """Processes an tree control event to add a new bookmark folder."""
        selected = self.tree.GetSelections()
        if not selected:
            node = None
            relative_path = ''
        else:
            node = selected.pop(0)
            relative_path = self.nodeToPath(node)

        folder = messages.displayInputDialog(self, _("Ftpcube - Add Bookmark Folder"),
            _("Folder name:"))

        if folder:
            relative_path = os.path.join(relative_path, folder)
            try:
                self.bookmark.addBookmarkFolder(relative_path)
            except bookmark.BookmarkException, strerror:
                messages.displayErrorDialog(self, _("Error creating bookmark folder: %(err)s")
                    %{ 'err' : strerror })
                return
            new_node = self.tree.AppendItem(node, folder, self.folder_index, self.folder_index)
            self.tree.Expand(node)

    def onFolderRename(self, event):
        """Processes a rename event for a bookmark folder within the tree control."""
        selected = self.tree.GetSelections()
        for node in selected:
            if node == self.root:
                continue
            relative_path = self.nodeToPath(node)
            new_folder = messages.displayInputDialog(self, _("Ftpcube - Rename Folder"),
                _("Rename %(file)s to:") %{ 'file' : os.path.basename(relative_path) })
            if not new_folder:
                continue
            new_relative_path = os.path.join(os.path.dirname(relative_path), new_folder)
            try:
                self.bookmark.renameBookmarkFolder(relative_path, new_relative_path)
            except bookmark.BookmarkException, strerror:
                messages.displayErrorDialog(self, _("Error renaming bookmark folder: %(err)s")
                    %{ 'err' : strerror })
                return
            parent = self.tree.GetItemParent(node)
            self.tree.Delete(node)
            new_node = self.tree.AppendItem(parent, new_folder, self.folder_index,
                self.folder_index)
            self.loadBookmarkTree(new_path, new_node)

    def onFolderDelete(self, event):
        """Processes a delete event for a bookmark folder within the tree control."""
        selected = self.tree.GetSelections()
        for node in selected:
            if node == self.root:
                continue
            relative_path = self.nodeToPath(node)
            try:
                self.bookmark.removeBookmarkFolder(relative_path)
            except bookmark.BookmarkException, strerror:
                messages.displayErrorDialog(self, _("Error deleting bookmark folder: %(err)s")
                    %{ 'err' : strerror })
                return
            self.tree.Delete(node)

    def onBookmarkAdd(self, event):
        """Processes an event to add a new bookmark.

        This brings up the connection window, whose fields can be filled up. When OK is
        clicked, the options are extracted and stored into the bookmark entry."""
        app_config = utils.getApplicationConfiguration()
        opts = app_config.getOptions()
        connect = connectwin.ConnectionWindow(self, opts, _("Ftpcube - Add Bookmark"))
        ret = connect.ShowModal()
        if ret == wx.ID_OK:
            book_opts = connect.getOptions()
            if book_opts['host']:
                relative_path = os.path.join(self.getPathToCurrentNode(),
                    "%s-%s" %(book_opts['host'], book_opts['port']))
                try:
                    self.bookmark.saveBookmark(relative_path, book_opts)
                except bookmark.BookmarkException, strerror:
                    messages.displayErrorDialog(self, _("Error adding bookmark: %(err)s")
                        %{ 'err' : strerror })
                    return
                self.displayBookmarks()

    def onBookmarkEdit(self, event):
        """Processes an event to edit an existing bookmark.

        This brings up a connection window with the options in the bookmark prepopulated.
        When the OK button is clicked, all the options are re-extracted from the connection
        window and saved to the bookmark file."""
        relative_path = self.getPathToCurrentNode()
        selected = utils.getSelected(self.list)
        if not selected:
            return
        selected = selected.pop(0)
        name = utils.getColumnText(self.list, selected, 0)
        book_file = os.path.join(relative_path, name)
        try:
            opts = self.bookmark.loadBookmark(book_file)
        except bookmark.BookmarkException, strerror:
            messages.displayErrorDialog(self, _("Error loading bookmark: %(err)s")
             %{ 'err' : strerror })
            return
        connect = connectwin.ConnectionWindow(self, opts, _("Ftpcube - Edit Bookmark"))
        ret = connect.ShowModal()
        if ret == wx.ID_OK:
            book_opts = connect.getOptions()
            try:
                self.bookmark.saveBookmark(book_file, book_opts)
            except bookmark.BookmarkException, strerror:
                messages.displayErrorDialog(self, _("Error saving bookmark: %(err)s")
                    %{ 'err' : strerror })
                return
            self.displayBookmarks()

    def onBookmarkRename(self, event):
        """Processes an event to rename an existing bookmark."""
        relative_path = self.getPathToCurrentNode()
        selected = utils.getSelected(self.list)
        if not selected:
            return
        selected = selected.pop(0)
        name = utils.getColumnText(self.list, selected, 0)

        new_name = messages.displayInputDialog(self, _("Ftpcube - Rename Bookmark"),
            _("Rename %(name)s to:") %{ 'name' : name })

        if not new_name:
            return
        try:
            self.bookmark.renameBookmark(os.path.join(relative_path, name),
                os.path.join(relative_path, new_name))
        except bookmark.BookmarkException, strerror:
            messages.displayErrorDialog(self, _("Error renaming bookmark: %(err)s")
                %{ 'err' : strerror })
            return
        self.displayBookmarks()

    def onBookmarkDelete(self, event):
        """Processes a bookmark entry delete event."""
        relative_path = self.getPathToCurrentNode()
        selected = utils.getSelected(self.list)
        if not selected:
            return
        selected = selected.pop(0)
        name = utils.getColumnText(self.list, selected, 0)

        relative_path = os.path.join(relative_path, name)
        try:
            self.bookmark.removeBookmark(relative_path)
        except bookmark.BookmarkException, strerror:
            messages.displayErrorDialog(self, _("Error deleting bookmark: %(err)s")
                %{ 'err' : strerror })
            return
        self.displayBookmarks()

    def onTreeSelect(self, event):
        """Expands an item in the tree."""
        node = event.GetItem()
        self.tree.Expand(node)
        self.displayBookmarks()

    def loadBookmarkTree(self, path, parent):
        """Performs a recursive traversal of the bookmark directory tree to load the
        bookmark tree into memory."""
        bookdir = self.bookmark.getBookmarkDirectory()
        bookdir = os.path.join(bookdir, path)
        self._loadBookmarkTree(bookdir, parent)

    def _loadBookmarkTree(self, path, parent):
        """Recursive loading of the bookmark tree."""
        try:
            files = os.listdir(path)
        except OSError, strerror:
            messages.displayErrorDialog(self, _("Error reading directory %(path)s: %(err)s")
                %{ 'path' : strerror, 'err' : strerror })
            return
        if files:
            for file in files:
                full_path = os.path.join(path, file)
                if os.path.isdir(full_path):
                    node = self.tree.AppendItem(parent, file, self.folder_index,
                        self.folder_index)
                    self._loadBookmarkTree(full_path, node)
            self.tree.Expand(parent)

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

    def getPathToCurrentNode(self):
        """Gets the relative path from the bookmark directory to the currently selected node
        within the bookmark tree."""
        node = self.root
        selected = self.tree.GetSelections()
        if selected:
            node = selected.pop(0)
        return self.nodeToPath(node)

    def displayBookmarks(self):
        """Displays the bookmark entries within a bookmark folder in the list control.

        The list widget is frozen until the update has been completed, at which point it
        is rendered to the user. If an error occurs while loading a bookmark from within
        the bookmark directory, then an error box is displayed to the user. This method
        will attempt to load as many bookmarks as possible, despite errors."""
        relative_path = self.getPathToCurrentNode()
        full_path = os.path.join(self.bookmark.getBookmarkDirectory(), relative_path)
        try:
            files = os.listdir(full_path)
        except OSError, strerror:
            messages.displayErrorDialog(self, _("Error reading directory %(path)s: %(err)s")
                %{ 'path' : full_path, 'err' : strerror })
            return

        self.list.Freeze()
        self.list.DeleteAllItems()

        index = 0
        for file in files:
            path = os.path.join(full_path, file)
            if os.path.isfile(path):
                try:
                    bookmark_entry = self.bookmark.loadBookmark(path)
                except bookmark.BookmarkException, strerror:
                    messages.displayErrorDialog(self, _("Error loading bookmark: %(err)s")
                        %{ 'err' : strerror })
                self.list.InsertStringItem(index, file)
                host = bookmark_entry['host']
                if not host:
                    host = ''
                port = bookmark_entry['port']
                if not port:
                    port = ''
                self.list.SetStringItem(index, 1, "%s:%s" %(host, port))
                username = bookmark_entry['username']
                if not username:
                    username = ''
                self.list.SetStringItem(index, 2, username)
                remotedir = bookmark_entry['remotedir']
                if not remotedir:
                    remotedir = ''
                self.list.SetStringItem(index, 3, remotedir)
                index = index + 1

        self.list.Thaw()
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.