Exemple #1
0
 def auto_start_state(self):
     if self.ui.autoStart.checkState() == Qt.Unchecked:
         try:
             os.unlink(self.startup_file)
         except OSError:
             pass
     else:
         shutil.copyfile(
             resource_filename('share/applications/everpad.desktop'),
             self.startup_file,
         )
Exemple #2
0
 def auto_start_state(self):
     if self.ui.autoStart.checkState() == Qt.Unchecked:
         try:
             os.unlink(self.startup_file)
         except OSError:
             pass
     else:
         shutil.copyfile(
             resource_filename('share/applications/everpad.desktop'),
             self.startup_file,
         )
Exemple #3
0
 def update_props(self):
     icon = Gio.ThemedIcon.new(resource_filename("share/icons/unity-icon-theme/places/svg/group-recent.svg"))
     tags = Unity.CheckOptionFilter.new('tags', _('Tags'), icon, True)
     for tag_struct in provider.list_tags():
         tag = Tag.from_tuple(tag_struct)
         tags.add_option(str(tag.id), tag.name, icon)
     notebooks = Unity.RadioOptionFilter.new('notebooks', _('Notebooks'), icon, True)
     for notebook_struct in provider.list_notebooks():
         notebook = Notebook.from_tuple(notebook_struct)
         notebooks.add_option(str(notebook.id), notebook.name, icon)
     places = Unity.RadioOptionFilter.new('places', _('Places'), icon, True)
     for place_struct in provider.list_places():
         place = Place.from_tuple(place_struct)
         places.add_option(str(place.id), place.name, icon)
     self._lens.props.filters = [notebooks, tags, places]
     self._lens.props.search_in_global = bool(int(provider.get_settings_value('search-on-home') or 1))
Exemple #4
0
def get_file_icon_path():
    """
    Get path of icon for file
    foe embedding in html.
    """
    paths = (
        os.path.join(
            os.path.dirname(__file__),
            '../../data/everpad-file.png',
        ),
        resource_filename('share/icons/hicolor/48x48/actions/everpad-file.png'),
        '/usr/local/share/icons/hicolor/48x48/actions/everpad-file.png',
        '/usr/share/icons/hicolor/48x48/actions/everpad-file.png',
    )
    for path in paths:
        if os.path.isfile(path):
            return 'file://%s' % path
Exemple #5
0
 def __init__(self, *args, **kwargs):
     QApplication.__init__(self, *args, **kwargs)
     self.settings = QSettings('everpad', 'everpad-pad')
     locale = QLocale.system().name()
     self.qtTranslator = QTranslator()
     self.qtTranslator.load("qt_" + locale, QLibraryInfo.location(QLibraryInfo.TranslationsPath))
     self.installTranslator(self.qtTranslator)
     self.appTranslator = QTranslator()
     if not self.appTranslator.load(locale, os.path.join(os.path.dirname(__file__), '../../i18n')):
         self.appTranslator.load(locale, resource_filename('share/everpad/i18n'))
     # This application string can be localized to 'RTL' to switch the application layout
     # direction. See for example i18n/ar_EG.ts
     QT_TRANSLATE_NOOP('QApplication', 'QT_LAYOUT_DIRECTION')
     self.installTranslator(self.appTranslator)
     QNetworkProxyFactory.setUseSystemConfiguration(True)
     self.indicator = Indicator()
     self.update_icon()
     self.indicator.show()
Exemple #6
0
def get_file_icon_path():
    """
    Get path of icon for file
    foe embedding in html.
    """
    paths = (
        os.path.join(
            os.path.dirname(__file__),
            '../../data/everpad-file.png',
        ),
        resource_filename(
            'share/icons/hicolor/48x48/actions/everpad-file.png'),
        '/usr/local/share/icons/hicolor/48x48/actions/everpad-file.png',
        '/usr/share/icons/hicolor/48x48/actions/everpad-file.png',
    )
    for path in paths:
        if os.path.isfile(path):
            return 'file://%s' % path
Exemple #7
0
 def update_props(self):
     icon = Gio.ThemedIcon.new(
         resource_filename(
             "share/icons/unity-icon-theme/places/svg/group-recent.svg"))
     tags = Unity.CheckOptionFilter.new('tags', _('Tags'), icon, True)
     for tag_struct in provider.list_tags():
         tag = Tag.from_tuple(tag_struct)
         tags.add_option(str(tag.id), tag.name, icon)
     notebooks = Unity.RadioOptionFilter.new('notebooks', _('Notebooks'),
                                             icon, True)
     for notebook_struct in provider.list_notebooks():
         notebook = Notebook.from_tuple(notebook_struct)
         notebooks.add_option(str(notebook.id), notebook.name, icon)
     places = Unity.RadioOptionFilter.new('places', _('Places'), icon, True)
     for place_struct in provider.list_places():
         place = Place.from_tuple(place_struct)
         places.add_option(str(place.id), place.name, icon)
     self._lens.props.filters = [notebooks, tags, places]
     self._lens.props.search_in_global = bool(
         int(provider.get_settings_value('search-on-home') or 1))
Exemple #8
0
 def __init__(self, *args, **kwargs):
     QApplication.__init__(self, *args, **kwargs)
     self.settings = QSettings('everpad', 'everpad-pad')
     locale = QLocale.system().name()
     self.qtTranslator = QTranslator()
     self.qtTranslator.load(
         "qt_" + locale,
         QLibraryInfo.location(QLibraryInfo.TranslationsPath))
     self.installTranslator(self.qtTranslator)
     self.appTranslator = QTranslator()
     if not self.appTranslator.load(
             locale, os.path.join(os.path.dirname(__file__), '../../i18n')):
         self.appTranslator.load(locale,
                                 resource_filename('share/everpad/i18n'))
     # This application string can be localized to 'RTL' to switch the application layout
     # direction. See for example i18n/ar_EG.ts
     QT_TRANSLATE_NOOP('QApplication', 'QT_LAYOUT_DIRECTION')
     self.installTranslator(self.appTranslator)
     QNetworkProxyFactory.setUseSystemConfiguration(True)
     self.indicator = Indicator()
     self.update_icon()
     self.indicator.show()
Exemple #9
0
from everpad.tools import get_provider, get_pad, resource_filename
from everpad.basetypes import Note, Tag, Notebook, Place, Resource
from everpad.const import API_VERSION
from html2text import html2text
from datetime import datetime
import dbus
import dbus.mainloop.glib
import sys
import os
import gettext
import json


path = os.path.join(os.path.dirname(__file__), '../../../i18n')
if not os.path.isdir(path):
    path =  resource_filename('share/locale/')
gettext.bindtextdomain('everpad', path)
gettext.textdomain('everpad')
_ = gettext.gettext

dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
provider = get_provider()


class EverpadLens(SingleScopeLens):

    class Meta:
        name = 'everpad'
        description = _('Everpad Lens')
        search_hint = _('Search Everpad')
        icon = 'everpad-lens'
Exemple #10
0
from singlet.utils import run_lens
from everpad.tools import get_provider, get_pad, resource_filename
from everpad.basetypes import Note, Tag, Notebook, Place, Resource
from everpad.const import API_VERSION
from html2text import html2text
from datetime import datetime
import dbus
import dbus.mainloop.glib
import sys
import os
import gettext
import json

path = os.path.join(os.path.dirname(__file__), '../../../i18n')
if not os.path.isdir(path):
    path = resource_filename('share/locale/')
gettext.bindtextdomain('everpad', path)
gettext.textdomain('everpad')
_ = gettext.gettext

dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
provider = get_provider()


class EverpadLens(SingleScopeLens):
    class Meta:
        name = 'everpad'
        description = _('Everpad Lens')
        search_hint = _('Search Everpad')
        icon = 'everpad-lens'
        search_on_blank = True
Exemple #11
0
class ContentEdit(QObject):
    _editor_path = os.path.join(
        os.path.dirname(__file__),
        'editor.html',
    )
    if not os.path.exists(_editor_path):
        _editor_path = resource_filename('share/everpad/editor.html')

    _html = open(_editor_path).read()

    copy_available = Signal(bool)

    def __init__(self, parent, widget, on_change):
        QObject.__init__(self)
        self.parent = parent
        self.app = QApplication.instance()
        self.widget = widget
        self.page = Page(self)
        self._on_change = on_change
        self._title = None
        self._content = None
        self._hovered_url = None
        self.widget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.widget.customContextMenuRequested.connect(self.context_menu)
        self._init_actions()
        self._init_shortcuts()
        self._last_table_num = 0

    def _init_actions(self):
        self.check_action = QAction(self.tr('Insert Checkbox'), self)
        self.check_action.triggered.connect(self._insert_check)
        self.link_action = QAction(self.tr('Insert Link'), self)
        self.link_action.triggered.connect(self._insert_link)
        self.table_action = QAction(self.tr('Insert Table'), self)
        self.table_action.triggered.connect(self._insert_table)
        self.image_action = QAction(self.tr('Insert Image'), self)
        self.image_action.triggered.connect(self._insert_image)
        self.change_link = QAction(self.tr('Change link'), self)
        self.change_link.triggered.connect(Slot()(partial(
            self._change_link, self.page.active_link)))
        self.remove_link = QAction(self.tr('Remove link'), self)
        self.remove_link.triggered.connect(self._remove_link)

    def _init_shortcuts(self):
        for key, action in (
            ('Ctrl+b', QWebPage.ToggleBold),
            ('Ctrl+i', QWebPage.ToggleItalic),
            ('Ctrl+u', QWebPage.ToggleUnderline),
            ('Ctrl+Shift+b', QWebPage.InsertUnorderedList),
            ('Ctrl+Shift+o', QWebPage.InsertOrderedList),
            ('Ctrl+Shift+v', QWebPage.PasteAndMatchStyle),
            ('Ctrl+k', self.link_action),
            ('Ctrl+Shift+k', self.change_link),
            ('Ctrl+l', QWebPage.AlignLeft),
            ('Ctrl+r', QWebPage.AlignRight),
            ('Ctrl+e', QWebPage.AlignCenter),
            ('Ctrl+j', QWebPage.AlignJustified),
            ('Ctrl+t', QWebPage.ToggleStrikethrough),
            ('Ctrl+Space', QWebPage.RemoveFormat),
            ('Ctrl+Shift+c', self.check_action),
        ):
            QShortcut(
                QKeySequence(self.app.tr(key)),
                self.widget,
            ).activated.connect(Slot()(partial(self._action_for_key,
                                               action)), )

    @property
    def title(self):
        """Cache title and return"""
        soup = BeautifulSoup(self.page.mainFrame().toHtml())
        self._title = soup.find(id='title').text
        return clean(html_unescape(self._title))

    @title.setter
    def title(self, val):
        """Set title"""
        self._title = val
        self.apply()

    @property
    def content(self):
        """Cache content and return"""
        soup = BeautifulSoup(self.page.mainFrame().toHtml())
        for todo in soup.findAll('input', {'type': 'checkbox'}):
            todo.name = 'en-todo'
            if todo.get('checked') == 'false':
                del todo['checked']
            del todo['type']
        for media in soup.findAll('img'):
            if media.get('class') == 'tab':
                media.replaceWith(' ' * 5)
            if media.get('hash'):
                media.name = 'en-media'
                del media['src']
                del media['title']
        # remove tables id's before save
        for table in soup.findAll('table'):
            del table['id']
        self._content = sanitize(soup=soup.find(id='content'), ).replace(
            '  ', u'\xa0\xa0').replace(u'\xa0 ', u'\xa0\xa0')
        return self._content

    @content.setter
    def content(self, val):
        """Set content"""
        soup = BeautifulSoup(val)
        for todo in soup.findAll('en-todo'):
            todo.name = 'input'
            todo['type'] = 'checkbox'
            if todo.get('checked') == 'false':
                del todo['checked']
            self.changed_by_default = True
        for media in soup.findAll('en-media'):
            if media.get('hash'):  # evernote android app error
                media.name = 'img'
                res = self.parent.resource_edit.get_by_hash(
                    media['hash'])  # shit!
                if res:
                    if media['type'].find('image') == 0:
                        media['src'] = 'file://%s' % res.file_path
                    else:
                        media['src'] = file_icon_path
                    media['title'] = res.file_name
                    res.in_content = True
                    # wrap in link to make clickable
                    tag = Tag(soup, "a",
                              [("href", 'file://%s' % res.file_path)])
                    media.replaceWith(tag)
                    tag.insert(0, media)
                else:
                    media['src'] = ''
                    media['title'] = ''
            else:
                media.hidden = True
        # set tables id's for identifing on hover
        for num, table in enumerate(soup.findAll('table')):
            table['id'] = 'table_%d' % num
            self._last_table_num = num
        self._content = re.sub(
            r'( | ){5}',
            '<img class="tab" />',
            unicode(soup).replace(u'\xa0', ' '),
        )  # shit!
        self.apply()

    def apply(self):
        """Apply title and content when filled"""
        if None not in (self._title, self._content):
            html = self._html.replace(
                '{{ title }}',
                cgi.escape(self._title),
            ).replace(
                '{{ content }}',
                self._content,
            )
            self.page.mainFrame().setHtml(html)
            self.widget.setPage(self.page)
            self.page.selectionChanged.connect(self.selection_changed)
            self.page.setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
            self.page.linkClicked.connect(self.link_clicked)
            self.page.linkHovered.connect(self.link_hovered)
            self.page.contentsChanged.connect(self.page_changed)

    @Slot()
    def selection_changed(self):
        self.copy_available.emit(self.page.current == 'body')

    @Slot(QUrl)
    def link_clicked(self, url):
        if url.scheme() == 'evernote':
            note_guid = url.toString().split('/')[6]
            note = Note.from_tuple(
                self.app.provider.get_note_by_guid(note_guid), )
            self.app.open(note)
        else:
            webbrowser.open(url.toString())

    @Slot(QPoint)
    def context_menu(self, pos, image_hash=None):
        """Show custom context menu"""
        menu = self.page.createStandardContextMenu()
        menu.clear()
        menu.addAction(self.page.action(QWebPage.Cut))
        menu.addAction(self.page.action(QWebPage.Copy))
        menu.addAction(self.page.action(QWebPage.Paste))
        paste_wo = self.page.action(QWebPage.PasteAndMatchStyle)
        paste_wo.setText(self.tr('Paste as Plain Text'))
        menu.addAction(paste_wo)
        if self._hovered_url:
            menu.addAction(self.page.action(QWebPage.CopyLinkToClipboard))
            menu.addAction(self.change_link)
            menu.addAction(self.remove_link)
            self.page.active_link = None
        if self.page.active_image:
            res = self.parent.resource_edit.get_by_hash(self.page.active_image)
            self.page.active_image = None
            menu.addAction(
                self.tr('Image Preferences'),
                Slot()(partial(self._show_image_dialog, res)),
            )
        if self.page.active_table:
            menu.addAction(
                self.tr('Change table'),
                Slot()(partial(self._update_table, self.page.active_table)),
            )
            self.page.active_table = None
        menu.addSeparator()
        menu.addAction(self.page.action(QWebPage.RemoveFormat))
        menu.addAction(self.page.action(QWebPage.SelectAll))
        menu.exec_(self.widget.mapToGlobal(pos))

    @Slot(unicode, unicode, unicode)
    def link_hovered(self, link, title, text):
        self._hovered_url = link

    @Slot()
    def page_changed(self):
        self._on_change()

    def _action_with_icon(self, action_type, icon_names, is_action=False):
        if is_action:
            action = action_type
        else:
            action = self.page.action(action_type)
        for icon_name in icon_names:
            if QIcon.hasThemeIcon(icon_name):
                action.setIcon(QIcon.fromTheme(icon_name))
                break

        self.copy_available.connect(action.setEnabled)
        return action

    def _action_for_key(self, action):
        if self.page.current == 'body':
            if isinstance(action, QWebPage.WebAction):
                action = self.page.action(action)
            action.trigger()

    @Slot()
    def _insert_link(self):
        url, ok = QInputDialog.getText(
            self.parent,
            self.tr('Everpad / Insert link'),
            self.tr('Press link address'),
        )
        if ok and url:
            self.page.mainFrame().evaluateJavaScript(
                'insertLink(%s);' % json.dumps(url), )
            self.page_changed()

    def _change_link(self, url):
        url, ok = QInputDialog.getText(
            self.parent,
            self.tr('Everpad / Change link'),
            self.tr('Press new link address'),
            text=url,
        )
        if ok and url:
            self.page.mainFrame().evaluateJavaScript(
                'changeLink(%s);' % json.dumps(url), )
            self.page_changed()

    @Slot()
    def _remove_link(self):
        self.page.mainFrame().evaluateJavaScript('removeLink();', )
        self.page_changed()

    @Slot()
    def _insert_table(self):
        dialog = TableWidget(self.parent)
        self._last_table_num += 1
        if dialog.exec_():
            self.page.mainFrame().evaluateJavaScript(
                'insertTable(%s, %s, "%s", "table_%d");' % (
                    dialog.ui.rows.text(),
                    dialog.ui.columns.text(),
                    dialog.get_width(),
                    self._last_table_num,
                ))

    def _update_table(self, id):
        rows = self.page.mainFrame().evaluateJavaScript(
            'getTableRows("%s")' % id, )
        cells = self.page.mainFrame().evaluateJavaScript(
            'getTableCells("%s")' % id, )
        dialog = TableWidget(self.parent, rows, cells)
        self._last_table_num += 1
        if dialog.exec_():
            self.page.mainFrame().evaluateJavaScript(
                'updateTable(%s, %s, "%s", "%s");' % (
                    dialog.ui.rows.text(),
                    dialog.ui.columns.text(),
                    dialog.get_width(),
                    id,
                ))

    @Slot()
    def _insert_check(self):
        self.page.mainFrame().evaluateJavaScript('insertCheck();', )
        self.page_changed()

    @Slot()
    def _insert_image(self):
        name = QFileDialog.getOpenFileName(
            filter=self.tr("Image Files (*.png *.jpg *.bmp *.gif)"), )[0]
        if name:
            self._insert_image_from_path(name)

    def _insert_image_from_path(self, path):
        res = self.parent.resource_edit.add_attach(path)
        self.paste_res(res)

    def get_format_actions(self):
        actions = [
            (QWebPage.ToggleBold, ['format-text-bold', 'everpad-text-bold']),
            (QWebPage.ToggleItalic,
             ['format-text-italic', 'everpad-text-italic']),
            (QWebPage.ToggleUnderline,
             ['format-text-underline', 'everpad-text-underline']),
            (QWebPage.ToggleStrikethrough,
             ['format-text-strikethrough', 'everpad-text-strikethrough']),
            (QWebPage.AlignCenter,
             ['format-justify-center', 'everpad-justify-center']),
            (QWebPage.AlignJustified,
             ['format-justify-fill', 'everpad-justify-fill']),
            (QWebPage.AlignLeft,
             ['format-justify-left', 'everpad-justify-left']),
            (QWebPage.AlignRight,
             ['format-justify-right', 'everpad-justify-right']),
        ]
        if self._enable_text_direction_support():
            actions += [
                (QWebPage.SetTextDirectionLeftToRight,
                 ['format-text-direction-ltr', 'everpad-text-direction-ltr']),
                (QWebPage.SetTextDirectionRightToLeft,
                 ['format-text-direction-rtl', 'everpad-text-direction-rtl']),
            ]
        actions += [
            (QWebPage.InsertUnorderedList,
             ['format-list-unordered', 'everpad-list-unordered']),
            (QWebPage.InsertOrderedList,
             ['format-list-ordered', 'everpad-list-ordered']),
            # Don't include 'checkbox' since it looks bad in some default themes
            (self.check_action, ['everpad-checkbox'], True),
            (self.table_action, ['insert-table',
                                 'everpad-insert-table'], True),
            (self.link_action, ['insert-link'], True),
            (self.image_action, ['insert-image'], True),
        ]
        return map(lambda action: self._action_with_icon(*action), actions)

    def paste_res(self, res):
        if res.mime.find('image') == 0:
            preview = 'file://%s' % res.file_path
        else:
            preview = file_icon_path
        self.page.mainFrame().evaluateJavaScript(
            'insertRes("%s", "%s", "%s");' % (
                preview,
                res.hash,
                res.mime,
            ), )
        self.page_changed()

    def _show_image_dialog(self, res):
        res.w = int(self.page.active_width)
        res.h = int(self.page.active_height)
        dialog = ImagePrefs(res, self.parent)
        if dialog.exec_():
            w, h = dialog.get_size()
            self.page.mainFrame().evaluateJavaScript(
                'changeRes("%s", %d, %d);' % (
                    res.hash,
                    w,
                    h,
                ), )
            self.page_changed()

    def in_content(self, res):
        return self.page.mainFrame().evaluateJavaScript(
            'resExist("%s");' % (res.hash, ), )

    def _enable_text_direction_support(self):
        def is_rtl_language(language_code):
            if not language_code:
                return False
            rtl_languages = ['ar', 'fa', 'he', 'ur']
            for lang in rtl_languages:
                if language_code.startswith(lang):
                    return True
            return False

        import locale
        default_language = locale.getdefaultlocale()[0]
        if is_rtl_language(default_language):
            return True
        # If the default language is not a RTL language, go through the preferred list
        # of languages to see if one of them is RTL. Unfortunately, this is platform-specific
        # logic, and I couldn't find a portable way of doing it.
        preferred_languages = os.getenv('LANGUAGE', '').split(':')
        for language in preferred_languages:
            if is_rtl_language(language):
                return True

        return False

    def print_(self):
        """Print note with preview"""
        printer = QPrinter()
        dialog = QPrintPreviewDialog(printer)
        dialog.paintRequested.connect(self.page.view().print_)
        dialog.exec_()

    def email_note(self):
        body = self.page.mainFrame().toPlainText()[len(self.title):].strip()
        url = QUrl("mailto:")
        url.addQueryItem("subject", self.title)
        url.addQueryItem("body", body)
        QDesktopServices.openUrl(url)

    def insert_files(self, urls, pos):
        """Not only images"""
        image_extensions = ['.png', '.jpg', '.bmp', '.gif']
        for url in urls:
            if url.scheme() == 'file':
                path = url.path()
                ext = os.path.splitext(path)[1]
                if os.path.exists(path) and ext in image_extensions:
                    self._insert_image_from_path(path)
                else:
                    self.parent.resource_edit.add_attach(path)
# Coop version 0.1, Copyright (C) 2013  Juan Manuel Schillaci
#   Coop comes with ABSOLUTELY NO WARRANTY.
#   This is free software, and you are welcome to redistribute it
#   under certain conditions;


import os
from subprocess import Popen, PIPE, STDOUT, call

import dbus
import dbus.mainloop.glib
import gettext
from everpad.basetypes import Note
from everpad.tools import get_provider, resource_filename

path = resource_filename("share/locale/")
gettext.bindtextdomain("everpad", path)
gettext.textdomain("everpad")
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
provider = get_provider()


SPLIT_CHARACTER = " >>> "


def search_all(search, results):
    for note_struct in provider.find_notes(
        search, dbus.Array([], signature="i"), dbus.Array([], signature="i"), 0, 100, Note.ORDER_TITLE, -1
    ):
        note = Note.from_tuple(note_struct)
        # TODO: Fix so it can return system lang encoding