browseweb.py :  » IDE » PIDA » pida-0.6beta3 » pida » services » browseweb » 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 » IDE » PIDA 
PIDA » pida 0.6beta3 » pida » services » browseweb » browseweb.py
# -*- coding: utf-8 -*-
"""
    :copyright: 2005-2008 by The PIDA Project
    :license: GPL 2 or later (see README/COPYING/LICENSE)
"""

import urlparse
import webbrowser

import gtk

webkit = None
gtkhtml2 = None

# PIDA Imports
from pida.core.service import Service
from pida.core.features import FeaturesConfig
from pida.core.commands import CommandsConfig
from pida.core.actions import ActionsConfig
from pida.core.actions import TYPE_NORMAL

from pida.utils.web import fetch_url

from pida.ui.views import PidaView

# locale
from pida.core.locale import Locale
locale = Locale('browseweb')
_ = locale.gettext

def get_url_mark(url):
    if '#' in url:
        url, mark = url.rsplit('#', 1)
    else:
        mark = None
    return url, mark


class GtkHtmlWidget(gtk.ScrolledWindow):

    def __init__(self, manager=None):
        gtk.ScrolledWindow.__init__(self)
        self.__view = gtkhtml2.View()
        self.add(self.__view)
        self.__document = gtkhtml2.Document()
        self.__view.set_document(self.__document)
        self.__document.connect('request-url', self.cb_request_url)
        self.__document.connect('link-clicked', self.cb_link_clicked)
        self.__current_url = None
        self.__current_mark = None
        self.__fetching_url = None
        self.__fetching_mark = None
        self.__manager = manager
        self.__urlqueue = []

    def load_url(self, url):
        url, mark = get_url_mark(url)
        self.__fetching_mark = mark
        self.__fetching_url = url
        if url != self.__current_url:
            self.__manager.stop_button.set_sensitive(True)
            self.__document.clear()
            self.__document.open_stream('text/html')
            fetch_url(url, self.fetch_complete)
        else:
            self.finished(url)

    def fetch_complete(self, url, data):
        self.__document.write_stream(data)
        self.__document.close_stream()
        self.finished(url)

    def cb_loader_data(self, data):
        self.__document.write_stream(data)

    def cb_loader_finished(self, url):
        self.__document.close_stream()
        self.finished(url)
    
    def stop(self):
        self.cb_loader_finished(self.__fetching_url)

    def back(self):
        if len(self.__urlqueue) > 1:
            self.__urlqueue.pop()
            url = self.__urlqueue.pop()
            self.load_url(url)

    def finished(self, url):
        self.__current_url = url
        self.__current_mark = self.__fetching_mark
        if self.__current_mark:
            self.__view.jump_to_anchor(self.__current_mark)
        else:
            self.__view.jump_to_anchor('')
        durl = url
        if self.__current_mark:
            durl = durl + '#' + self.__current_mark
        self.__manager.stop_button.set_sensitive(False)
        self.__manager.location.set_text(url)
        self.__urlqueue.append(url)
        self.__manager.back_button.set_sensitive(len(self.__urlqueue) > 1)

    def cb_request_url(self, doc, url, stream):
        def _data(url, data):
            stream.write(data)
            stream.close()
        url = urlparse.urljoin(self.__fetching_url, url)
        fetch_url(url, _data)

    def cb_link_clicked(self, doc, url):
        url = urlparse.urljoin(self.__current_url, url)
        self.load_url(url)


class SearchBar(gtk.HBox):

    def __init__(self, html, label='Find:'):
        gtk.HBox.__init__(self)
        self.html = html
        self.set_border_width(3)
        self.set_spacing(3)

        self.label = gtk.Label(label)
        self.label.show()
        self.pack_start(self.label, expand=False)

        self.text = gtk.Entry()
        self.text.connect('activate', self.on_text__activate)
        self.text.show()
        self.pack_start(self.text)

        self.find_button = gtk.ToolButton(gtk.STOCK_FIND)
        self.find_button.connect('clicked', self.on_find_button__clicked)
        self.find_button.set_tooltip_text(_('Find'))

        self.close_button = gtk.ToolButton(gtk.STOCK_CLOSE)
        self.close_button.set_tooltip_text(_('Close'))
        self.close_button.connect('clicked', self.on_close_button__clicked)

        self.pack_start(self.find_button, expand=False)
        self.find_button.show()

        if html.has_highlight:
            self.highlight_button = gtk.ToggleToolButton(gtk.STOCK_BOLD)
            self.highlight_button.set_tooltip_text(_('Highlight'))
            self.highlight_button.connect('toggled', 
                                          self.on_highlight_button__toggled)
            self.highlight_button.set_active(True)

            self.pack_start(self.highlight_button, expand=False)
            self.highlight_button.show()

        self.pack_start(self.close_button, expand=False)
        self.close_button.show()

        self.set_no_show_all(True)

    def on_text__activate(self, entry):
        self.perform_search()

    def perform_search(self):
        search = self.text.get_text()
        self.html.search_text(search, False, True, True)

    def start_search(self):
        self.show()
        self.text.grab_focus()

    def end_search(self):
        self.hide()

    def on_find_button__clicked(self, button):
        self.perform_search()

    def on_close_button__clicked(self, button):
        self.end_search()

    def on_highlight_button__toggled(self, button):
        self.html.set_highlight(button.get_active())

class WebkitHtmlWidget(gtk.VBox):

    def __init__(self, manager=None):
        self.url = ''
        self.manager = manager
        gtk.VBox.__init__(self)
        self.create_ui()

    def create_ui(self):
        self.html = webkit.WebView()
        self.html.connect('navigation-requested',
                          self.on_html__navigation_requested)

        self.html.connect('load-started',
                          self.on_html__load_started)
        self.html.connect('load-progress-changed',
                          self.on_html__load_progress_changed)
        self.html.connect('load-finished',
                          self.on_html__load_finished)

        self.html.connect('key-press-event', self.on_key_press)

        self.sw = gtk.ScrolledWindow()
        self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.sw.add(self.html)
        self.progress = gtk.ProgressBar()
        self.progress.set_no_show_all(True)

        self.searchbar = SearchBar(self)

        self.pack_start(self.sw)
        self.pack_start(self.searchbar, expand=False)
        self.pack_start(self.progress, expand=False)
        self.show_all()

    def search_text(self, search, sensetive=False, forward=True, wrap=True):
        self.html.search_text(search, sensetive, forward, wrap)
        if hasattr(self.html, 'unmark_text_matches'):
            self.html.unmark_text_matches()
            self.html.mark_text_matches(search, sensetive, 0)
            self.html.set_highlight_text_matches(True)


    def load_url(self, url):
        self.url = url
        self.title = url
        self.html.open(url)

    def on_html__navigation_requested(self, html, frame, request):
        return 0

    def on_html__load_started(self, page, frame):
        self.progress.show()
        self.manager.stop_button.set_sensitive(True)


    def on_html__load_finished(self, page, frame):
        self.title = frame.get_title()
        self.progress.hide()
        self.finished(self.url)

    def on_html__load_progress_changed(self, page, progress):
        self.progress.set_fraction(progress / 100.0)
        self.progress.set_text('%s%%' % progress)

    def stop(self):
        self.html.stop_loading()

    def back(self):
        self.html.go_back()

    def finished(self, url):
        self.manager.stop_button.set_sensitive(False)
        self.manager.location.set_text(url)
        self.manager.back_button.set_sensitive(self.html.can_go_back())

    def on_key_press(self, html, event):
        if event.keyval in (47, 102):
            self.searchbar.start_search()

    @property
    def has_highlight(self):
        return hasattr(self.html, 'unmark_text_matches')

    def set_highlight(self, active):
        self.html.set_highlight_text_matches(active)

HtmlWidget = None

def set_html_widget():
    global webkit, gtkhtml2, HtmlWidget
    #import traceback
    #traceback.print_stack()

    if HtmlWidget:
        return

    try:
        import webkit
    except:
        try:
            import gtkhtml2
        except:
            pass


    if webkit is not None:
        HtmlWidget = WebkitHtmlWidget
    elif gtkhtml2 is not None:
        HtmlWidget = GtkHtmlWidget
    else:
        HtmlWidget = None


class BrowserView(PidaView):
    ICON_NAME = 'gtk-library' 
    SHORT_TITLE = _('Browser')

    HAS_TITLE = False

    def create_ui(self):
        set_html_widget()
        self.__browser = HtmlWidget(self)
        bar = gtk.HBox()
        self.back_button = gtk.ToolButton(stock_id=gtk.STOCK_GO_BACK)
        self.stop_button = gtk.ToolButton(stock_id=gtk.STOCK_STOP)
        bar.pack_start(self.back_button, expand=False)
        bar.pack_start(self.stop_button, expand=False)
        if hasattr(self.__browser, 'searchbar'):
            self.find_button = gtk.ToolButton(stock_id=gtk.STOCK_FIND)
            self.find_button.connect('clicked', self.cb_toolbar_clicked, 'find')
            bar.pack_start(self.find_button, expand=False)

        self.back_button.connect('clicked', self.cb_toolbar_clicked, 'back')
        self.stop_button.connect('clicked', self.cb_toolbar_clicked, 'stop')
        self.add_main_widget(bar, expand=False)
        self.location = gtk.Entry()
        bar.pack_start(self.location)
        self.location.connect('activate', self.cb_url_entered)
        self.add_main_widget(self.__browser)
        self.get_toplevel().show_all()
        self._close_callback=None

    def connect_closed(self, callback):
        self._close_callback = callback

    def cb_url_entered(self, entry):
        url = self.location.get_text()
        self.fetch(url)

    def fetch(self, url):
        self.__browser.load_url(url)

    def cb_toolbar_clicked(self, button, name):
        if name == 'back':
            self.__browser.back()
        elif name == 'stop':
            self.__browser.stop()
        elif name == 'find':
            self.__browser.searchbar.start_search()

    def can_be_closed(self):
        if self._close_callback is not None:
            self._close_callback(self)
        else:
            self.svc.boss.cmd('window', 'remove_view', view=self)


class WebCommands(CommandsConfig):

    def browse(self, url):
        self.svc.browse(url)

    def get_web_browser(self):
        return BrowserView

class WebFeatures(FeaturesConfig):

    def subscribe_all_foreign(self):
        from pida.services.openwith import OpenWithItem
        
        internal = OpenWithItem({'name': "Open in Browser",
                                 'command': self.open_web_file,
                                 'glob': '*'})
        external = OpenWithItem({'name': "Open in External Browser",
                                 'command': self.open_web_external_file,
                                 'glob': '*'})

        self.subscribe_foreign('contexts', 'url-menu',
            (self.svc.get_action_group(), 'webbrowser-url-menu.xml'))

        self.subscribe_foreign('openwith', 'file-menu',
            internal)
        self.subscribe_foreign('openwith', 'file-menu',
            external)

    def open_web_file(self, file_name):
        self.svc.browse("file://%s" %file_name)

    def open_web_external_file(self, file_name):
        webbrowser.open("file://%s" %file_name)

class WebActions(ActionsConfig):
    
    def create_actions(self):
        self.create_action(
            'open_url_for_url',
            TYPE_NORMAL,
            _('Open URL'),
            _('Open a url in the builtin browser'),
            gtk.STOCK_OPEN,
            self.on_open_url_for_url,
        )

        self.create_action(
            'copy_clipboard_for_url',
            TYPE_NORMAL,
            _('Copy URL to clipboard'),
            _('Copy this URL to the clipboard'),
            gtk.STOCK_COPY,
            self.on_copy_url_for_url,
        )

        self.create_action(
            'open_url_external_for_url',
            TYPE_NORMAL,
            _('Open URL in external web browser'),
            _('Open the selected URL in an external web browser'),
            'internet',
            self.on_open_url_external_for_url,
        )

    def on_open_url_for_url(self, action):
        url = action.contexts_kw['url']
        self.svc.browse(url)

    def on_copy_url_for_url(self, action):
        url = action.contexts_kw['url']
        for clipboard_type in ['PRIMARY', 'CLIPBOARD']:
            gtk.Clipboard(selection=clipboard_type).set_text(url)

    def on_open_url_external_for_url(self, action):
        url = action.contexts_kw['url']
        webbrowser.open(url)

# Service class
class Webbrowser(Service):
    """Describe your Service Here""" 

    commands_config = WebCommands
    features_config = WebFeatures
    actions_config = WebActions

    def pre_start(self):
        self._views = []

    def browse(self, url):
        set_html_widget()
        if HtmlWidget is None:
            webbrowser.open(url)
        else:
            view = BrowserView(self)
            view.fetch(url)
            self.boss.cmd('window', 'add_view', paned='Terminal', view=view)

# Required Service attribute for service loading
Service = Webbrowser



# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.