Commits

Ronny Pfannschmidt  committed 4f395b9 Merge

merge action-cleanup

  • Participants
  • Parent commits 3a14107, 2ef3b99

Comments (0)

Files changed (148)

+
+import py
+import pytest
+
 import gtk
-import pytest
 from pygtkhelpers.utils import refresh_gui
 
+from tests.support import GladeFile, UidefFile
+
+from pida.core import environment
+
+
 collect_ignore = [
     'tools/skeleton',
     'tools/glade3-plugin',
     'deb_dist',
 ]
 
+@pytest.mark.tryfirst
+def pytest_runtest_setup(item):
+    settings_root = pytest.ensuretemp('homes')
+    home = py.path.local.make_numbered_dir(
+        prefix=item.name,
+        rootdir=settings_root,
+        lock_timeout=9,
+    )
+    environment.set_home(home)
+
+
+def pytest_collect_file(path, parent):
+    if path.check(ext='.glade'):
+        return GladeFile(path, parent)
+    if path.check(ext='.xml') and \
+       path.dirpath().basename == 'uidef':
+        return UidefFile(path, parent)
+
 @pytest.mark.last
 def pytest_runtest_teardown():
     for toplevel in gtk.window_list_toplevels():

File pida-plugins/bookmark/__init__.py

-# -*- coding: utf-8 -*- 
-
-# Copyright (c) 2007 The PIDA Project
-
-#Permission is hereby granted, free of charge, to any person obtaining a copy
-#of this software and associated documentation files (the "Software"), to deal
-#in the Software without restriction, including without limitation the rights
-#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-#copies of the Software, and to permit persons to whom the Software is
-#furnished to do so, subject to the following conditions:
-
-#The above copyright notice and this permission notice shall be included in
-#all copies or substantial portions of the Software.
-
-#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-#SOFTWARE.
-
-
-
-
-
-
-
-
-# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
+from .bookmark import Bookmark as Service

File pida-plugins/bookmark/bookmark.py

 # -*- coding: utf-8 -*- 
 
-# Copyright (c) 2007 The PIDA Project
-
-#Permission is hereby granted, free of charge, to any person obtaining a copy
-#of this software and associated documentation files (the "Software"), to deal
-#in the Software without restriction, including without limitation the rights
-#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-#copies of the Software, and to permit persons to whom the Software is
-#furnished to do so, subject to the following conditions:
-
-#The above copyright notice and this permission notice shall be included in
-#all copies or substantial portions of the Software.
-
-#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-#SOFTWARE.
-
 import gtk
 import os
 import cgi
 import pkgutil
 import json
 
-from kiwi.ui.objectlist import ObjectList, Column
+from pygtkhelpers.ui.objectlist import ObjectList, Column
 
 # PIDA Imports
 from pida.core.service import Service
 from pida.ui.actions import PidaRememberToggle
 from pida.core.editors import LineMarker, MarkerInterface
 
-from pida.ui.views import PidaView, WindowConfig
+from pida.ui.views import PidaView
 
 from pygtkhelpers.gthreads import gcall
-
+from pygtkhelpers.utils import eformat
 
 # locale
 from pida.core.locale import Locale
 
 class BookmarkItem(object):
     group = None
-    keys = 'data', 'group', 'title'
-    def __init__(self, title, data):
+
+    def __init__(self, title, data, line=None):
         self.title = title
         self.data = data
+        self.line = line
 
     def run(self, service):
         pass
 
     def _key(self):
-        return tuple(getattr(self, key) for key in self.keys)
+        return self.data, self.group, self.title, self.line
 
-    def __hash__(self):
-        return hash(self._key())
-
-    def __cmp__(self, other):
-        return cmp(hash(self),hash(other))
+    def __eq__(self, other):
+        return self._key() == other._key()
 
 
 class BookmarkItemFile(BookmarkItem, LineMarker):
     group = 'file'
-    keys = BookmarkItem.keys + ('line',)
     type = 'bookmark'
 
     def __init__(self, svc, data=None, line=1):
         #self.line = line
         self.svc = svc
-        BookmarkItem.__init__(self,  title='', data=data)
+        self._lineno = line
+        BookmarkItem.__init__(self,  title='', data=data, line=line)
         self.data = data
-        self._lineno = line
 
-    def _get_title(self):
+    @property
+    def title(self):
         try:
             color = self.svc._view._list['file'].style.lookup_color('pida-lineno').\
                     to_string()
             line = int(self.line)
         except ValueError:
             line = 1
-        return '%s:<span color="%s">%d</span>' % (
-                cgi.escape(os.path.basename(self.data)), color, line)
+        return eformat('{name:e}:<span color="{color}">{line}</span>',
+                           name=os.path.basename(self.filename),
+                           color=color,
+                           line=line,
+            )
 
-    def _set_title(self, value): pass
-
-    title = property(_get_title, _set_title)
+    @title.setter
+    def title(self, value):
+        pass  # ignore
 
     def run(self, service):
         service.boss.cmd('buffer', 'open_file', 
     filename = property(_get_filename, _set_filename)
 
     def _do_set_line(self, newlineno):
-        self._lineno = min(1, int(newlineno))
+        self._lineno = int(newlineno)
         self.svc._view._list['file'].update(self)
 
     def update(self, newlineno):
     label_text = _('Bookmarks')
 
     def create_ui(self):
-        self._vbox = gtk.VBox()
         self.create_toolbar()
         self.create_ui_list()
-        self.add_main_widget(self._vbox)
-        self._vbox.show_all()
 
     def create_tab_label(self, icon_name, text):
-        if None in [icon_name, text]:
-            return None
         label = gtk.Label(text)
-        b_factory = gtk.HBox
-        b = b_factory(spacing=2)
         icon = gtk.image_new_from_stock(icon_name, gtk.ICON_SIZE_MENU)
-        b.pack_start(icon)
-        b.pack_start(label)
-        b.show_all()
-        return b
+        box = gtk.HBox(spacing=2)
+        box.pack_start(icon)
+        box.pack_start(label)
+        box.show_all()
+        return box
 
     def create_objectlist(self, icon_name, text):
-            l = ObjectList([Column('title', use_markup=True)])
-            l.connect('row-activated', self._on_item_activated)
-            l.connect('selection-changed', self._on_item_selected)
-            l.set_headers_visible(False)
-            l.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-            self._books.append_page(l,
-                    tab_label=self.create_tab_label(icon_name, text))
-            return l
+        l = ObjectList([Column('title', use_markup=True)])
+        l.connect('item-activated', self._on_item_activated)
+        l.connect('selection-changed', self._on_item_selected)
+        l.set_headers_visible(False)
+        sc = gtk.ScrolledWindow()
+        sc.add(l)
+        sc.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        self._books.append_page(sc,
+                tab_label=self.create_tab_label(icon_name, text))
+        return l
 
     def create_ui_list(self):
         self._books = gtk.Notebook()
         self._list_url.set_headers_visible(False)
         self._books.add(self._list_url)
         """
-        self._vbox.add(self._books)
+        self.widget.add(self._books)
         self._books.show_all()
 
     def create_toolbar(self):
         self._toolbar = self._uim.get_toplevels('toolbar')[0]
         self._toolbar.set_style(gtk.TOOLBAR_ICONS)
         self._toolbar.set_icon_size(gtk.ICON_SIZE_SMALL_TOOLBAR)
-        self._vbox.pack_start(self._toolbar, expand=False)
+        self.widget.pack_start(self._toolbar, expand=False)
         self._toolbar.show_all()
 
     def add_item(self, item):
     def can_be_closed(self):
         self.svc.get_action('show_bookmark').set_active(False)
 
-    def _on_item_selected(self, olist, item):
-        self.svc.set_current(item)
+    def _on_item_selected(self, olist):
+        self.svc.set_current(olist.selected_item)
 
     def _on_item_activated(self, olist, item):
         item.run(self.svc)
 
 class BookmarkActions(ActionsConfig):
 
-    def create_actions(self):
-        BookmarkWindowConfig.action = self.create_action(
-            'show_bookmark',
-            PidaRememberToggle,
+
+    actions = [
+        PidaRememberToggle('show_bookmark',
             _('Bookmark Viewer'),
             _('Show bookmarks'),
-            '',
-            self.on_show_bookmark,
-            '',
-        )
-
-        self.create_action(
-            'bookmark_curfile',
-            gtk.Action,
+            ''),
+        gtk.Action('bookmark_curfile',
             _('Bookmark current file'),
             _('Bookmark current file'),
-            'text-x-generic',
-            self.on_bookmark_curfile,
-            ''
-        )
-
-        self.create_action(
-            'bookmark_togglefile',
-            gtk.Action,
+            'text-x-generic'),
+        gtk.Action('bookmark_togglefile',
             _('Toggle Bookmark on current file'),
             _('Toggle Bookmark on current file'),
-            'text-x-generic',
-            self.on_bookmark_togglefile,
-            ''
-        )
-
-
-        self.create_action(
-            'bookmark_curdir',
-            gtk.Action,
+            'text-x-generic'),
+        gtk.Action('bookmark_curdir',
             _('Bookmark current directory'),
             _('Bookmark current directory'),
-            'stock_folder',
-            self.on_bookmark_curdir,
-            ''
-        )
-
-        self.create_action(
-            'bookmark_delsel',
-            gtk.Action,
+            'stock_folder'),
+        gtk.Action('bookmark_delsel',
             _('Delete selected item'),
             _('Delete selected item'),
-            gtk.STOCK_DELETE,
-            self.on_bookmark_delsel,
-            ''
-        )
-
-        self.create_action(
-            'bookmark_go_prev',
-            gtk.Action,
+            gtk.STOCK_DELETE),
+        gtk.Action('bookmark_go_prev',
             _('Goto previous bookmark'),
             _('Goto previous bookmark'),
-            gtk.STOCK_GO_UP,
-            self.on_bookmark_go_prev,
-            ''
-        )
-
-        self.create_action(
-            'bookmark_go_next',
-            gtk.Action,
+            gtk.STOCK_GO_UP),
+        gtk.Action('bookmark_go_next',
             _('Goto next bookmark'),
             _('Goto next bookmark'),
-            gtk.STOCK_GO_DOWN,
-            self.on_bookmark_go_next,
-            ''
-        )
-
-        self.create_action(
-            'bookmark-for-dir',
-            gtk.Action,
+            gtk.STOCK_GO_DOWN),
+        gtk.Action('bookmark_for_dir',
             _('Add as bookmark'),
             _('Add selected directory as bookmark'),
-            gtk.STOCK_ADD,
-            self.on_bookmark_for_dir,
-        )
-
-        self.create_action(
-            'bookmark-for-file',
-            gtk.Action,
+            gtk.STOCK_ADD),
+        gtk.Action('bookmark_for_file',
             _('Add as bookmark'),
             _('Add selected file as bookmark'),
-            gtk.STOCK_ADD,
-            self.on_bookmark_for_file,
-        )
+            gtk.STOCK_ADD),
+    ]
 
+    accels = {
+        'show_bookmark': '',
+        'bookmark_curfile': '',
+        'bookmark_togglefile': '',
+        'bookmark_curdir': '',
+        'bookmark_delsel': '',
+        'bookmark_go_prev': '',
+        'bookmark_go_next': '',
+    }
 
     def on_show_bookmark(self, action):
         if action.get_active():
     def on_bookmark_for_dir(self, action):
         self.svc.bookmark_dir(path=action.contexts_kw['dir_name'])
 
-class BookmarkWindowConfig(WindowConfig):
-    key = BookmarkView.key
-    label_text = BookmarkView.label_text
-
 class BookmarkFeatures(FeaturesConfig):
 
     def subscribe_all_foreign(self):
             (self.svc, 'bookmark-file-menu.xml'))
         self.subscribe_foreign('contexts', 'dir-menu',
             (self.svc, 'bookmark-dir-menu.xml'))
-        self.subscribe_foreign('window', 'window-config',
-            BookmarkWindowConfig)
 
 class BookmarkEvents(EventsConfig):
 
                     path = os.path.sep.join(path)
                 else:
                     path = t.data
-                data[t.group].append((path, 
-                    int(t.line)))
+                data[t.group].append('%s#%d' %( path, int(t.line)))
             else:
                 data[t.group].append(t.data)
         return data
             items = data[key]
             for item in items:
                 if key == 'file':
+                    try:
+                        item = item.rsplit('#', 1)
+                    except AttributeError:
+                        pass  # old format
                     path = os.path.join(self._project.source_directory,  item[0])
-                    self.bookmark_file(filename=path, line=item[1])
+                    self.bookmark_file(filename=path, line=int(item[1]))
                 elif key == 'path':
                     self.bookmark_dir(path=item)
 
             fp = open(datafile, "w")
             json.dump(data, fp, indent=1)
         except Exception, e:
+            print e
             self.log.exception(e)
             
         #FIXME: reimplement !!!
         for i in self._list['file']:
             if i.data == filename:
                 yield i
-        
-
-# Required Service attribute for service loading
-Service = Bookmark
-
-
 
 # vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:

File pida-plugins/bookmark/test_bookmark.py

 # -*- coding: utf-8 -*- 
+import gtk
+from pygtkhelpers.utils import refresh_gui
+from .bookmark import BookmarkView, Bookmark, BookmarkItemFile
+from pida.core.projects import Project
+import mock
 
-# Copyright (c) 2007 The PIDA Project
+def pytest_funcarg__boss(request):
+    boss = mock.Mock(name='boss')
+    return boss
 
-#Permission is hereby granted, free of charge, to any person obtaining a copy
-#of this software and associated documentation files (the "Software"), to deal
-#in the Software without restriction, including without limitation the rights
-#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-#copies of the Software, and to permit persons to whom the Software is
-#furnished to do so, subject to the following conditions:
+def test_view(tmpdir, boss):
+    Project.create_blank_project_file('test', str(tmpdir))
+    project = Project(str(tmpdir))
 
-#The above copyright notice and this permission notice shall be included in
-#all copies or substantial portions of the Software.
+    boss.cmd.return_value = project
 
-#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-#SOFTWARE.
+    s = Bookmark(boss)
+    s.create_all()
+    view = BookmarkView(s)
+    s._view = view
 
+    s.load()
 
+    myfile = BookmarkItemFile(s, __file__)
+    s.add_item(myfile)
+    s.add_item(myfile)
+    w = gtk.Window()
+    w.add(view.widget)
+    w.show_all()
+    refresh_gui()
+    myfile._do_set_line(3)
+    assert myfile.line == 3
+    refresh_gui()
+    s.save()
 
+    s.list_files().selected_item = myfile
+    assert s._current is myfile
 
+    boss.cmd.reset_mock()
+    view._on_item_activated(s.list_files, myfile)
+    assert boss.cmd.called_with('buffer', 'open_file',
+                                filename='/home/ronny/Projects/pissoff/pida/pida-plugins/bookmark/test_bookmark.py',
+                                line=3)
+
+
+    print tmpdir.join('.pida-metadata/bookmark/bookmark.json').read()
 
 
 

File pida-plugins/checklist/__init__.py

-# -*- coding: utf-8 -*- 
-
-# Copyright (c) 2007 The PIDA Project
-
-#Permission is hereby granted, free of charge, to any person obtaining a copy
-#of this software and associated documentation files (the "Software"), to deal
-#in the Software without restriction, including without limitation the rights
-#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-#copies of the Software, and to permit persons to whom the Software is
-#furnished to do so, subject to the following conditions:
-
-#The above copyright notice and this permission notice shall be included in
-#all copies or substantial portions of the Software.
-
-#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-#SOFTWARE.
-
-
-
-
-
-
-
-
-# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
+from .checklist import Checklist as Service

File pida-plugins/checklist/checklist.py

 # -*- coding: utf-8 -*- 
 
-# Copyright (c) 2007 The PIDA Project
-
-#Permission is hereby granted, free of charge, to any person obtaining a copy
-#of this software and associated documentation files (the "Software"), to deal
-#in the Software without restriction, including without limitation the rights
-#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-#copies of the Software, and to permit persons to whom the Software is
-#furnished to do so, subject to the following conditions:
-
-#The above copyright notice and this permission notice shall be included in
-#all copies or substantial portions of the Software.
-
-#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-#SOFTWARE.
-
-from __future__ import with_statement
-
 import gtk
 import os
+import hashlib
 import pkgutil
+from datetime import datetime
 
 from pygtkhelpers.ui.widgets import AttrSortCombo
-from kiwi.ui.objectlist import ObjectList, Column
-from kiwi.python import enum
+from pygtkhelpers.ui.objectlist import ObjectList, Column
 
 # PIDA Imports
 from pida.core.service import Service
 from pida.core.features import FeaturesConfig
 from pida.core.events import EventsConfig
 from pida.core.actions import ActionsConfig
-from pida.ui.views import PidaView, WindowConfig
-from pida.utils.unique import create_unique_id
+from pida.ui.views import PidaView
+import json  #XXX py.path one
 
 from pida.ui.actions import PidaRememberToggle
 
 locale = Locale('checklist')
 _ = locale.gettext
 
-#Critical, Major, Minor, Warning, Normal
-class ChecklistStatus(enum):
-    (LOW,
-     NORMAL,
-     HIGH) = range(3)
 
-    def __new__(cls, value, name):
-        self = enum.__new__(cls, value, name)
-        self.value = value
-        return self
+def pseudounique_key(title):
+    return "%s %s" %(
+        datetime.now(),
+        hashlib.sha1(title).hexdigest(),
+    )
 
 
 class ChecklistItem(object):
 
-    def __init__(self, title, priority=ChecklistStatus.NORMAL, done=False, key=None):
+    def __init__(self, title, priority='normal', done=False, key=None):
         self.title = title
         self.priority = priority
         self.done = done
-        if key is not None:
-            self.key = key
-        else:
-            self.key = str(create_unique_id())
+        self.key = key or pseudounique_key(title)
 
 
 class ChecklistView(PidaView):
         self._vbox.show_all()
 
     def create_tab_label(self, icon_name, text):
-        if None in [icon_name, text]:
-            return None
         label = gtk.Label(text)
         b_factory = gtk.HBox
         b = b_factory(spacing=2)
 
     def create_list(self):
         self._list = ObjectList([
-                Column('done', title=_('Done'), data_type=bool, editable=True),
-                Column('title', title=_('Title'), data_type=str,
+                Column('done', title=_('Done'), use_checkbox=True, editable=True),
+                Column('title', title=_('Title'),
                     editable=True, expand=True),
-                Column('priority', title=_('Priority'),
-                    data_type=ChecklistStatus, editable=True)
+                Column('priority',title=_('Priority'),
+                    choices=('low', 'normal', 'high'), editable=True)
                 ])
-        self._list.connect('cell-edited', self._on_item_edit)
+        self._list.connect('item-changed', self._on_item_edit)
         self._list.connect('selection-changed', self._on_item_selected)
-        self._list.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-        self._vbox.add(self._list)
+        self._scroll = gtk.ScrolledWindow()
+        self._scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        self._scroll.add(self._list)
+        self._vbox.add(self._scroll)
 
         self._sort_combo = AttrSortCombo(self._list,
             [
     def clear(self):
         self._list.clear()
 
-    def _on_item_selected(self, olist, item):
-        self.svc.get_action('checklist_del').set_sensitive(item is not None)
-        self.svc.set_current(item)
+    def _on_item_selected(self, olist):
+        self.svc.get_action('checklist_del').set_sensitive(olist.selected_item is not None)
+        self.svc.set_current(olist.selected_item)
 
-    def _on_item_edit(self, olist, item, value):
+    def _on_item_edit(self, olist, item, attr, value):
         self.svc.save()
 
     def _on_item_add(self, w):
 
 class ChecklistActions(ActionsConfig):
 
-    def create_actions(self):
-        ChecklistWindowConfig.action = self.create_action(
-            'show_checklist',
-            PidaRememberToggle,
+
+    actions = [
+        PidaRememberToggle('show_checklist',
             _('Checklist Viewer'),
             _('Show checklists'),
-            '',
-            self.on_show_checklist,
-            '',
-        )
+            ''),
+        gtk.Action('checklist_add',
+            _('Add something in checklist'),
+            _('Add something in checklist'),
+            gtk.STOCK_ADD),
+        gtk.Action('checklist_del',
+            _('Delete selected item'),
+            _('Delete selected item'),
+            gtk.STOCK_DELETE),
+    ]
 
-        self.create_action(
-            'checklist_add',
-            gtk.Action,
-            _('Add something in checklist'),
-            _('Add something in checklist'),
-            gtk.STOCK_ADD,
-            self.on_checklist_add,
-              
-        )
-
-        self.create_action(
-            'checklist_del',
-            gtk.Action,
-            _('Delete selected item'),
-            _('Delete selected item'),
-            gtk.STOCK_DELETE,
-            self.on_checklist_del,
-        )
-
-
+    accels = {
+        'show_checklist': '',
+        'checklist_add': '',
+    }
 
     def on_show_checklist(self, action):
         if action.get_active():
                                self.svc.on_project_switched)
 
 
-class ChecklistWindowConfig(WindowConfig):
-    key = ChecklistView.key
-    label_text = ChecklistView.label_text
-
-class ChecklistFeaturesConfig(FeaturesConfig):
-    def subscribe_all_foreign(self):
-        self.subscribe_foreign('window', 'window-config',
-            ChecklistWindowConfig)
-
-
 # Service class
 class Checklist(Service):
     """Manage checklists"""
         self._has_loaded = False
         self._items = {}
         self._current = None
-        self._project = None
 
     def show_checklist(self):
         self.boss.cmd('window', 'add_view', paned='Plugin', view=self._view)
         self.save()
 
     def on_project_switched(self, project):
-        if project != self._project:
-            self._project = project
-            self.load()
+        self.load()
 
     def _serialize(self):
         data = {}
         for key in self._items:
             item = self._items[key]
-            data[key] = dict(done=item.done, 
-                             prio=item.priority.value, 
+            data[key] = dict(done=item.done,
+                             prio=item.priority,
                              title=item.title)
         return data
 
             return
         self._items = {}
         self._view.clear()
-        fname = self._project.get_meta_dir('checklist', filename="data.json")
+        project = self.boss.cmd('project', 'get_current_project')
+        fname = project.get_meta_dir('checklist', filename="data.json")
         if not os.path.exists(fname):
             return
         with open(fname, "r") as fp:
                 self._unserialize(data)
 
     def save(self):
-        fname = self._project.get_meta_dir('checklist', filename="data.json")
+        project = self.boss.cmd('project', 'get_current_project')
+        fname = project.get_meta_dir('checklist', filename="data.json")
         with open(fname, "w") as fp:
             data = self._serialize()
             if data:
         if self.get_action('show_checklist').get_active():
             self.hide_checklist()
 
-
-# Required Service attribute for service loading
-Service = Checklist
-
-
-
 # vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:

File pida-plugins/checklist/test_checklist.py

 # -*- coding: utf-8 -*- 
 
-# Copyright (c) 2007 The PIDA Project
+from .checklist import Checklist, ChecklistView, ChecklistItem
+from pida.core.projects import Project
+import mock
 
-#Permission is hereby granted, free of charge, to any person obtaining a copy
-#of this software and associated documentation files (the "Software"), to deal
-#in the Software without restriction, including without limitation the rights
-#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-#copies of the Software, and to permit persons to whom the Software is
-#furnished to do so, subject to the following conditions:
 
-#The above copyright notice and this permission notice shall be included in
-#all copies or substantial portions of the Software.
-
-#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-#SOFTWARE.
-
-
-
-
-
-
+def test_checklist(tmpdir):
+    Project.create_blank_project_file('test', str(tmpdir))
+    boss = mock.Mock()
+    service = Checklist(boss)
+    boss.cmd.return_value = Project(str(tmpdir))
+    service.create_all()
+    service.start()
+    item = ChecklistItem('test')
+    service.add_item(item)
+    item.done = True
+    service.update_item(item, None)
 
 
 # vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:

File pida-plugins/ctags/__init__.py

-# -*- coding: utf-8 -*- 
-
-# Copyright (c) 2007 The PIDA Project
-
-#Permission is hereby granted, free of charge, to any person obtaining a copy
-#of this software and associated documentation files (the "Software"), to deal
-#in the Software without restriction, including without limitation the rights
-#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-#copies of the Software, and to permit persons to whom the Software is
-#furnished to do so, subject to the following conditions:
-
-#The above copyright notice and this permission notice shall be included in
-#all copies or substantial portions of the Software.
-
-#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-#SOFTWARE.
-
-
-
-
-
-
-
-
-# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
+from .ctags import Ctags as Service

File pida-plugins/ctags/ctags.py

 # -*- coding: utf-8 -*- 
 
-# Copyright (c) 2007 The PIDA Project
-
-#Permission is hereby granted, free of charge, to any person obtaining a copy
-#of this software and associated documentation files (the "Software"), to deal
-#in the Software without restriction, including without limitation the rights
-#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-#copies of the Software, and to permit persons to whom the Software is
-#furnished to do so, subject to the following conditions:
-
-#The above copyright notice and this permission notice shall be included in
-#all copies or substantial portions of the Software.
-
-#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-#SOFTWARE.
-
 # stdlib
-import sys, compiler, os.path, keyword, re
+import os
 import tempfile
 import subprocess
-# gtk
-import gtk
 
 # PIDA Imports
 
 # core
-from pida.core.service import Service
-from pida.core.events import EventsConfig
-from pida.core.actions import ActionsConfig
-from pida.core.options import OptionsConfig
-from pida.core.languages import (LanguageService, Outliner, Validator,
-    Completer, LanguageServiceFeaturesConfig, LanguageInfo, Definer, Documentator)
+from pida.core.languages import LanguageService, Outliner
 
 from pida.utils.languages import LANG_PRIO, OutlineItem
-
-# locale
-from pida.core.locale import Locale
-locale = Locale('python')
-_ = locale.gettext
 from subprocess import Popen, PIPE
 
 
 from pida.services.language import DOCTYPES
 
 SUPPORTED_LANGS = build_language_list(DOCTYPES)
-# class PythonActionsConfig(ActionsConfig):
-#
-#     def create_actions(self):
-#         self.create_action(
-#             'execute_python',
-#             TYPE_NORMAL,
-#             _('Execute Python Module'),
-#             _('Execute the current Python module in a shell'),
-#             gtk.STOCK_EXECUTE,
-#             self.on_python_execute,
-#         )
-#
-#     def on_python_execute(self, action):
-#         self.svc.execute_current_document()
-#
 
 class CtagsTokenList(object):
     def __init__(self, *args, **kwargs):
     priority = LANG_PRIO.GOOD
     name = "ctags"
     plugin = "ctags"
-    description = _("A very fast but only shallow outliner")
+    description = "A very fast but only shallow outliner"
 
     def run(self):
         if not self.document.filename:
 
     language_name = [x.internal for x in SUPPORTED_LANGS]
     outliner_factory = CtagsOutliner
-
-
-
-
-# Required Service attribute for service loading
-Service = Ctags
-
-
-
-# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:

File pida-plugins/filesearch/__init__.py

-# -*- coding: utf-8 -*- 
-#XXX: needed for the glade file
-from kiwi.ui.widgets.combo import ProxyComboBox
-

File pida-plugins/filesearch/filesearch.py

-# -*- coding: utf-8 -*- 
-"""
-    filesearch.filesearch
-    ~~~~~~~~~~~~~~~~~~~~~
-
-    This file contains the UI- and service-related functions of the file
-    search plugin.
-
-    The search functions itself are inside ``search.py``, the search filters
-    inside ``filters.py``.
-
-    :copyright: 2007 by Benjamin Wiegand.
-    :license: GNU GPL, see LICENSE for more details.
-"""
-import gtk
-
-from os import path
-from kiwi.ui.objectlist import Column
-
-from pida.core.locale import Locale
-from pida.ui.views import PidaView, WindowConfig
-from pida.core.service import Service
-from pida.core.events import EventsConfig
-from pida.core.actions import ActionsConfig
-from pida.core.features import FeaturesConfig
-from pida.core.options import OptionsConfig
-from pygtkhelpers.gthreads import GeneratorTask
-
-from filters import ValidationError, FileNameMatchesFilter
-from search import get_filters, do_search, SearchMatch
-from pida.ui.actions import PidaRememberToggle
-
-
-locale = Locale('filesearch')
-_ = locale.gettext
-
-
-class SearchView(PidaView):
-
-    key = 'filesearch.form'
-
-    gladefile = 'search'
-    locale = locale
-    label_text = _('File Search')
-    icon_name = 'search'
-    filters = []
-    running = False
-    entries = {}
-
-    def create_ui(self):
-        # filter select
-        self.filter_select.prefill(get_filters())
-
-        self.match_list.set_columns([
-            Column('icon_stock_id', use_stock=True, title=' '),
-            #Column('state_markup', use_markup=True, title=' '),
-            Column('markup', use_markup=True, title=_('Name')),
-            Column('path', title=_('Path'))
-        ])
-
-        # add standard filter
-        self.new_filter(FileNameMatchesFilter)
-
-        # task for asynchrounus searching
-        # ``append_to_match_list`` is called if a match was found
-        # ``search_finished`` is called at the end of search
-        self.task = GeneratorTask(do_search, self.append_to_match_list,
-                                  self.search_finished)
-
-
-    def on_add_button__clicked(self, btn):
-        # get selected filter
-        f = self.filter_select.read()
-        self.new_filter(f)
-
-    def on_search_button__clicked(self, btn):
-        if not self.running:
-            if self.validate():
-                self.start()
-        else:
-            self.stop()
-
-    def on_match_list__row_activated(self, rowitem, search_match):
-        self.svc.boss.cmd('buffer', 'open_file',
-                          file_name=path.join(search_match.path,
-                                              search_match.name))
-        self.svc.boss.editor.cmd('grab_focus')
-
-    def can_be_closed(self):
-        self.stop()
-        return True
-
-    def start(self):
-        """
-        Start the asynchrounus search task.
-        """
-        self.running = True
-        self.match_list.clear()
-        self.entries = {}
-        self.update_match_count(0)
-        self.search_button.set_label(gtk.STOCK_STOP)
-        self.task.start(self.get_search_folder(), self.filters)
-
-    def stop(self):
-        """
-        Stop the abort task.
-        """
-        self.task.stop()
-        self.search_finished()
-
-    def new_filter(self, f):
-        """
-        This function adds a new filter to the GUI and registers it in
-        `self.filters``.
-        """
-        entries = f.get_entries()
-        new_filter = f(**entries)
-
-        box = gtk.HBox(False, 5)
-        box.pack_start(gtk.Label(f.description), expand=False)
-
-        # filter entry objects
-        for name, entry in entries.iteritems():
-            box.pack_start(entry)
-            entry.connect('activate', self.on_search_button__clicked)
-
-        # remove button
-        def remove_btn_clicked(btn):
-            btn.parent.destroy()
-            self.filters.remove(new_filter)
-
-        btn = gtk.Button()
-        btn.connect('clicked', remove_btn_clicked)
-        img = gtk.image_new_from_stock(gtk.STOCK_REMOVE, gtk.ICON_SIZE_MENU)
-        btn.set_image(img)
-
-        box.pack_start(btn, expand=False)
-
-        self.filter_box.pack_start(box)
-        box.show_all()
-
-        self.filters.append(new_filter)
-
-    def set_search_folder(self, folder):
-        self.select_folder.set_current_folder(folder)
-
-    def get_search_folder(self):
-        """
-        Returns the last folder opened in the filemanager.
-        If it's not available, it returns the path to the project root instead.
-        """
-        folder = self.select_folder.get_current_folder()
-        # XXX: Windows?
-        if folder == '/':
-            folder = self.svc.current_project.source_directory
-        return folder
-
-    def validate(self):
-        """
-        Tell all filters to validate their input fields. If a filter raises a
-        ``ValidationError`` the user is shown an error message.
-        """
-        for f in self.filters:
-            try:
-                f.validate()
-            except ValidationError, e:
-                self.svc.error_dlg(e)
-                return False
-
-        return True
-
-    def update_match_count(self, count=None):
-        if count is None:
-            self.match_count += 1
-        else:
-            self.match_count = 0
-        self.count_label.set_text('%s files' % self.match_count)
-
-    def append_to_match_list(self, dirpath, filename):
-        #for lister in self.file_listers:
-        #    # XXX: this loads all files inside the directory and filters the
-        #    #      file later --> dirty hack
-        #    #      find a better way only to load the needed file
-        #    def _f(*args, **kwargs):
-        #        self.add_or_update_file(
-        #            path.join(dirpath, filename),
-        #            *args,
-        #            **kwargs
-        #        )
-        #    GeneratorTask(lister, _f).start(dirpath)
-        self.add_or_update_file(filename, dirpath, 'normal')
-
-    def add_or_update_file(self, name, basepath, state):
-        entry = self.entries.setdefault(path.join(basepath, name),
-                                            SearchMatch(basepath, name, 
-                                                        manager=self))
-        entry.state = state
-
-        if entry.visible:
-            # update file
-            self.match_list.update(entry)
-        else:
-            # add file
-            self.match_list.append(entry)
-            entry.visible = True
-            self.update_match_count()
-
-    def search_finished(self):
-        self.running = False
-        self.search_button.set_label(gtk.STOCK_FIND)
-
-
-class SearchEvents(EventsConfig):
-
-    def subscribe_all_foreign(self):
-        self.subscribe_foreign('filemanager', 'browsed_path_changed',
-                               self.svc.change_search_folder)
-        self.subscribe_foreign('project', 'project_switched',
-                               self.svc.on_project_switched)
-
-
-class SearchActions(ActionsConfig):
-
-    def create_actions(self):
-        SearchWindowConfig.action = self.create_action(
-            'show_search',
-            PidaRememberToggle,
-            _('File Search'),
-            _('Show the File Search'),
-            gtk.STOCK_INFO,
-            self.on_show_search,
-            '<Shift><Control>f',
-        )
-
-    def on_show_search(self, action):
-        if action.get_active():
-            self.svc.show_search()
-        else:
-            self.svc.hide_search()
-
-
-class FileManagerOptionsConfig(OptionsConfig):
-    def create_options(self):
-        self.create_option(
-            'exclude_hidden',
-            _('Don\'t search in hidden directories'),
-            bool,
-            True,
-            _('Excludes hidden directories from search')
-        )
-
-        self.create_option(
-            'exclude_vcs',
-            _('Don\'t search in data directories of version control systems'),
-            bool,
-            True,
-            _('Excludes the data directories of version control systems '
-              'from search')
-        )
-
-class SearchWindowConfig(WindowConfig):
-    key = SearchView.key
-    label_text = SearchView.label_text
-
-class SearchFeaturesConfig(FeaturesConfig):
-    def subscribe_all_foreign(self):
-        self.subscribe_foreign('window', 'window-config',
-            SearchWindowConfig)
-
-
-class Search(Service):
-    """Search service"""
-
-    actions_config = SearchActions
-    events_config = SearchEvents
-    options_config = FileManagerOptionsConfig
-
-    def pre_start(self):
-        self._view = SearchView(self)
-
-    def change_search_folder(self, path):
-        self._view.set_search_folder(path)
-
-    def show_search(self):
-        self.boss.cmd('window', 'add_view', paned='Plugin', view=self._view)
-
-    def hide_search(self):
-        self.boss.cmd('window', 'remove_view', view=self._view)
-
-    def ensure_view_visible(self):
-        action = self.get_action('show_search')
-        if not action.get_active():
-            action.set_active(True)
-        self.boss.cmd('window', 'presnet_view', view=self._view)
-
-    def stop(self):
-        # abort search task
-        self._view.stop()
-        if self.get_action('show_search').get_active():
-            self.hide_search()
-
-    def on_project_switched(self, project):
-        self.current_project = project
-
-
-# Required Service attribute for service loading
-Service = Search

File pida-plugins/filesearch/filters.py

-# -*- coding: utf-8 -*- 
-"""
-    filesearch.filters
-    ~~~~~~~~~~~~~~~~~~
-
-    :copyright: 2007 by Benjamin Wiegand.
-    :license: GNU GPL, see LICENSE for more details.
-"""
-
-import re
-import gtk
-import sre_constants
-
-from glob import fnmatch
-from os.path import basename
-
-from pida.core.locale import Locale
-locale = Locale('filesearch')
-_ = locale.gettext
-
-BINARY_RE = re.compile(r'[\000-\010\013\014\016-\037\200-\377]|\\x00')
-
-
-class ValidationError(Exception):
-    """
-    An exception that is raised if the user entered invalid data into a
-    filter's field.
-    The search catches it and informs the user.
-    """
-
-
-class Filter(object):
-    """
-    A search filter that lowers the search result.
-    """
-
-    #: The description of the filter
-    filter_desc = ''
-
-    @staticmethod
-    def get_entries():
-        """
-        This method should return a dictionary containing all input elements
-        the filter needs.
-        Example::
-
-            return {
-                'entry': gtk.Entry()
-            }
-        """
-
-    def __init__(self):
-        """
-        The init function is called if the user added a new filter.
-        It get's all input elements defined in ``get_entries`` as keyword
-        arguments.
-        """
-
-    def validate(self):
-        """
-        This function is called before the search process starts.
-        It should validate all input elements and raise a ``ValidationError``
-        on error.
-        """
-
-    def check(self, path):
-        """
-        This function should return ``True`` if ``path`` matches the filter,
-        else ``False``.
-        """
-
-
-class FileNameMatchesFilter(Filter):
-    """
-    Checks whether the file name matches a given regular expression.
-    """
-    description = _('Name matches')
-
-    def __init__(self, entry):
-        self.entry = entry
-
-    def validate(self):
-        pattern = self.entry.get_text()
-        pattern = fnmatch.translate(pattern).rstrip('$')
-        try:
-            self.regex = re.compile(pattern, re.IGNORECASE)
-        except sre_constants.error, e:
-            raise ValidationError(_('Invalid Regex'))
-
-    @staticmethod
-    def get_entries():
-        return {
-            'entry': gtk.Entry()
-        }
-
-    def check(self, path):
-        return bool(self.regex.search(basename(path)))
-
-
-class ContentMatchesFilter(Filter):
-    """
-    Checks whether the file content matches a given regular expression.
-    """
-    description = _('Content matches')
-
-    def __init__(self, entry):
-        self.entry = entry
-
-    def validate(self):
-        pattern = self.entry.get_text()
-        pattern = fnmatch.translate(pattern).rstrip('$')
-        try:
-            self.regex = re.compile(pattern, re.IGNORECASE)
-        except sre_constants.error, e:
-            raise ValidationError(_('Invalid Regex'))
-
-    @staticmethod
-    def get_entries():
-        return {
-            'entry': gtk.Entry()
-        }
-
-    def check(self, path):
-        f = file(path)
-        found = False
-
-        for line in f.readlines():
-            if BINARY_RE.search(line):
-                # binary file, abort
-                break
-
-            if self.regex.search(line):
-                found = True
-                break
-
-        f.close()
-        return found
-
-
-filter_list = [FileNameMatchesFilter, ContentMatchesFilter]

File pida-plugins/filesearch/glade/search.glade

-<?xml version="1.0"?>
-<!--Generated with glade3 3.2.0 on Sat Sep 15 22:28:16 2007 by benjamin@Moritz-->
-<interface>
-  <object class="GtkWindow" id="search">
-    <property name="width_request">450</property>
-    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-    <child>
-      <object class="GtkVBox" id="vbox1">
-        <property name="visible">True</property>
-        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-        <property name="border_width">5</property>
-        <property name="spacing">10</property>
-        <child>
-          <object class="GtkVBox" id="filter_box">
-            <property name="visible">True</property>
-            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-            <property name="spacing">5</property>
-            <child>
-              <object class="GtkHBox" id="hbox2">
-                <property name="visible">True</property>
-                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="spacing">5</property>
-                <child>
-                  <object class="ProxyComboBox" id="filter_select">
-                    <property name="visible">True</property>
-                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                  </object>
-                </child>
-                <child>
-                  <object class="GtkButton" id="add_button">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                    <property name="label" translatable="yes">gtk-add</property>
-                    <property name="use_stock">True</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </object>
-              <packing>
-                <property name="pack_type">GTK_PACK_END</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkHBox" id="hbox1">
-            <property name="visible">True</property>
-            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-            <property name="spacing">5</property>
-            <child>
-              <object class="GtkLabel" id="count_label">
-                <property name="visible">True</property>
-                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="label" translatable="yes">0 files</property>
-                <property name="width_chars">10</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkFileChooserButton" id="select_folder">
-                <property name="visible">True</property>
-                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="action">GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER</property>
-                <property name="title" translatable="yes">Select search folder</property>
-              </object>
-              <packing>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="search_button">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                <property name="label" translatable="yes">gtk-find</property>
-                <property name="use_stock">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="position">2</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
-          <object class="ObjectList" id="match_list">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-            <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-            <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-            <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-          </object>
-          <packing>
-            <property name="position">2</property>
-          </packing>
-        </child>
-      </object>
-    </child>
-  </object>
-</interface>

File pida-plugins/filesearch/pixmaps/search.png

Removed
Old image

File pida-plugins/filesearch/search.py

-# -*- coding: utf-8 -*- 
-"""
-    filesearch.search
-    ~~~~~~~~~~~~~~~~~
-
-    :copyright: 2007 by Benjamin Wiegand.
-    :license: GNU GPL, see LICENSE for more details.
-"""
-
-import cgi
-
-from os import walk, path
-
-from pida.services.filemanager.filemanager import state_style, state_text
-from pida.core.environment import on_windows
-
-from filters import filter_list
-
-
-class SearchMatch(object):
-    """
-    Symbolizes a file that matched all search filters.
-    You can add it directly to a ``kiwi.ObjectList`` object.
-    """
-    def __init__(self, dirpath, name, manager=None):
-        self.state = 'normal'
-        self.name = name
-        self.path = dirpath
-        self.manager = manager
-        self.visible = False
-        self.extension = path.splitext(self.name)[-1]
-        self.icon_stock_id = self.get_icon_stock_id()
-
-    def __repr__(self):
-        return '<SearchMatch "%s">' % path.join(self.path, self.name)
-
-    @property
-    def markup(self):
-        return self.format(cgi.escape(self.name))
-
-    def get_icon_stock_id(self):
-        #TODO: get a real mimetype icon
-        return 'text-x-generic'
-
-    @property
-    def state_markup(self):
-        text = state_text.get(self.state, ' ')
-        wrap = '<span weight="ultrabold"><tt>%s</tt></span>'
-        return wrap % self.format(text)
-
-    def format(self, text):
-        color, b, i = state_style.get(self.state, (None, False, False))
-        if self.manager and color:
-            #FIXME to_string is missing on win32
-            color = self.manager.match_list.style.lookup_color(color)
-            if not on_windows:
-                color = color.to_string()
-            else:
-                color = '#%s%s%s' % (color.red,color.green,color.blue)
-        else:
-            color = "black"
-        if b:
-            text = '<b>%s</b>' % text
-        if i:
-            text = '<i>%s</i>' % text
-        return '<span color="%s">%s</span>' % (color, text)
-
-
-def get_filters():
-    """
-    Returns the a tuple of the filter's description and the filters itself.
-    """
-    return [(f.description, f) for f in filter_list]
-
-def do_search(folder, filters, exclude_hidden=True, exclude_vcs=True):
-    """
-    Test all ``filters`` on ``folder``'s content recursively.
-    If a file matches all filters a ``SearchMatch`` object is yielded.
-    """
-    for dirpath, dirnames, filenames in walk(folder):
-        def _get_hidden(dirnames):
-            """
-            Return the directories that shouldn't be shown.
-            """
-            hidden = []
-            for dirname in dirnames:
-                if dirname.startswith('.'):
-                    hidden.append(dirname)
-            return hidden
-
-        if exclude_hidden:
-            # remove the hidden folders of ``dirnames`` that they don't get
-            # crawled
-            for dirname in _get_hidden(dirnames):
-                # XXX: Check whether removing using .pop with index is faster
-                dirnames.remove(dirname)
-
-        for file_name in filenames:
-            fpath = path.join(dirpath, file_name)
-            errors = False
-
-            if not path.exists(fpath):
-                # this may happen if there's a invalid symlink
-                continue
-
-            for f in filters:
-                if not f.check(fpath):
-                    # file doesn't matches filter
-                    errors = True
-                    break
-
-            if not errors:
-                # file did match all filters
-                yield dirpath, file_name

File pida-plugins/filesearch/service.pida

-Name: File Search
-Version: 0.5
-Author: Benjamin Wiegand <beewee91@gmail.com>
-Depends: pida>=0.6
-Category: code
-
-Search files inside PIDA

File pida-plugins/filesearch/test_filesearch.py

-# -*- coding: utf-8 -*- 
-
-# Copyright (c) 2007 The PIDA Project
-
-#Permission is hereby granted, free of charge, to any person obtaining a copy
-#of this software and associated documentation files (the "Software"), to deal
-#in the Software without restriction, including without limitation the rights
-#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-#copies of the Software, and to permit persons to whom the Software is
-#furnished to do so, subject to the following conditions:
-
-#The above copyright notice and this permission notice shall be included in
-#all copies or substantial portions of the Software.
-
-#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-#SOFTWARE.
-
-
-
-
-
-
-
-
-# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:

File pida-plugins/filesearch/uidef/filesearch.xml

-<ui>
-    <menubar>
-
-        <menu name="FileMenu" action="FileMenu">
-        </menu>
-    
-        <menu name="EditMenu" action="EditMenu">
-        </menu>
-        
-        <menu name="ProjectMenu" action="ProjectMenu">
-        </menu>
-        
-        <menu name="LanguageMenu" action="LanguageMenu">
-        </menu>
-        
-        <menu name="ToolsMenu" action="ToolsMenu">
-        </menu>
-        
-        <menu name="ViewMenu" action="ViewMenu">
-            <placeholder name="tools">
-            <menuitem action="show_search" name="show_search" />
-            </placeholder>
-            <separator />
-            <placeholder name="panes"/>
-        </menu>
-        
-        <menu name="HelpMenu" action="HelpMenu">
-        </menu>
-    
-    </menubar>
-    
-    <toolbar>
-        <placeholder name="OpenFileToolbar">
-        </placeholder>
-        <separator/>
-        <placeholder name="SaveFileToolbar">
-        <separator/>
-        <separator/>
-        </placeholder>
-        <placeholder name="EditToolbar">
-        </placeholder>
-        <separator/>
-        <placeholder name="ProjectToolbar">
-        </placeholder>
-        <separator/>
-        <placeholder name="VcToolbar">
-        </placeholder>
-        <separator/>
-        <placeholder name="ToolsToolbar">
-        </placeholder>
-
-    </toolbar>
-
-</ui>

File pida-plugins/gtags/__init__.py

-# -*- coding: utf-8 -*- 
-
-# Copyright (c) 2007 The PIDA Project
-
-#Permission is hereby granted, free of charge, to any person obtaining a copy
-#of this software and associated documentation files (the "Software"), to deal
-#in the Software without restriction, including without limitation the rights
-#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-#copies of the Software, and to permit persons to whom the Software is
-#furnished to do so, subject to the following conditions:
-
-#The above copyright notice and this permission notice shall be included in
-#all copies or substantial portions of the Software.
-
-#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER