Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGonzalo Odiard <godiard@gmail.com>2014-02-13 12:10:10 (GMT)
committer Gonzalo Odiard <godiard@gmail.com>2014-02-13 12:10:10 (GMT)
commit5397867451324eccbdfe19f1ca5c53b28e95769f (patch)
tree46ed90fdca813c554210962166b68e59cfc5ef0c
parent9b9317fc7b626905867e38ee7893534e9b1ff258 (diff)
parent96517d4b167a9f5775c883f243f66d4f8a4b4a28 (diff)
Merge branch 'gtk3'
-rw-r--r--develop-activity/activity_model.py275
-rw-r--r--develop-activity/develop_app.py405
-rw-r--r--develop-activity/logviewer.py275
-rw-r--r--develop-activity/new_activity.py2
-rwxr-xr-xdevelop-activity/setup.py2
-rw-r--r--develop-activity/sourceview_editor.py118
-rw-r--r--develop-activity/symbols_tree.py45
-rw-r--r--develop-activity/widgets.py22
8 files changed, 514 insertions, 630 deletions
diff --git a/develop-activity/activity_model.py b/develop-activity/activity_model.py
deleted file mode 100644
index d20690a..0000000
--- a/develop-activity/activity_model.py
+++ /dev/null
@@ -1,275 +0,0 @@
-# Copyright 2008 Paul Swartz
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-import gtk
-import gobject
-import os
-import os.path
-import logging
-from gettext import gettext as _
-import fnmatch
-
-unwantedPaths = [
- '.*', # hidden files
- '*~', # emacs backups
- '*.pyc', # compiled python
- '*.bak', # SPE backup file
- '.git', # git repository info
- 'CVS', ] # CVS repository info
-
-
-def _nodefilter(node):
- notmatched = True
- for path in unwantedPaths:
- if fnmatch.fnmatch(node.filename, path):
- notmatched = False
- break
- return notmatched
-
-
-def inmanifestfn(bundle):
- activity_path = bundle.get_path()
- logging.error('activity path = %s', activity_path)
-
- allfiles = []
-
- def walk_callback(allfiles, directory, files):
- for file_name in files:
- notmatched = True
- for path in unwantedPaths:
- if fnmatch.fnmatch(file_name, path):
- notmatched = False
- break
- if notmatched:
- allfiles.append(os.path.join(directory, file_name))
-
- os.path.walk(activity_path, walk_callback, allfiles)
-
- #logging.error('allfiles %s', allfiles)
-
- #allfiles = bundle.get_files()
- def nodefilterfn(node):
- if os.path.isdir(node.path):
- return True
- for innerpath in allfiles[:-1]: # truncate MANIFEST
- if os.path.join(node.model.root, innerpath) == node.path:
- return True
- return False
- return nodefilterfn
-
-
-def get_selected_file(treeview):
- selection = treeview.get_selection()
- model, _iter = selection.get_selected()
- if not _iter:
- return
- value = model.get_value(_iter, 0)
- return value
-
-
-def get_selected_file_path(treeview):
- value = get_selected_file(treeview)
- if value:
- return value['path']
-
-
-class DirectoryAndExtraModel(gtk.GenericTreeModel):
-
- columns = (gobject.TYPE_PYOBJECT, gobject.TYPE_STRING)
-
- def __init__(self, root, extra_paths=None, nodefilter=_nodefilter):
- self.root = root
- self.extra_paths = extra_paths
- self.nodefilter = nodefilter
- self.refresh()
- gtk.GenericTreeModel.__init__(self)
-
- def refresh(self):
- self.files = list(
- n for n in
- (ActivityNode(filename, self, None, self.nodefilter)
- for filename in sorted(os.listdir(self.root)))
- if self.nodefilter(n))
-
- if self.extra_paths:
- self.files.extend(ActivityNode(
- filename, self, None,
- self.nodefilter) for filename in self.extra_paths)
-
- def get_iter_from_filepath(self, filepath):
- if filepath.startswith(self.root):
- inpath = os.path.split(filepath[len(self.root):])[1:]
- #os.path.split gives empty first element
- else:
- inpath = os.path.split(filepath)
- files = self.files
- outpath = []
- try:
- for node in inpath:
- nodeindex = files.index(node)
- files = files[nodeindex]._files
- outpath.append(nodeindex)
- except ValueError:
- print files
- print filepath, inpath, outpath
- tree_iter = self.get_iter(tuple(outpath))
- return tree_iter
-
- def on_get_flags(self):
- return 0
-
- def on_get_n_columns(self):
- return len(self.columns)
-
- def on_get_column_type(self, n):
- return self.columns[n]
-
- def on_get_iter(self, path):
- x = self.files
- for part in path:
- x = x[part]
- return x
-
- def on_get_path(self, rowref):
- return rowref.getTreePath()
-
- def on_get_value(self, rowref, n):
- if n == 0:
- return {'name': rowref.filename,
- 'path': rowref.path}
- else:
- return rowref.filename
-
- def on_iter_next(self, rowref):
- if rowref.parent is not None:
- files = rowref.parent
- else:
- files = self.files
- index = files.index(rowref) + 1
- if index < len(files):
- return files[index]
-
- def on_iter_has_child(self, rowref):
- if rowref is not None:
- return rowref.isDirectory
- else:
- return bool(len(self.files))
-
- def on_iter_n_chilren(self, rowref):
- logging.critical('n children: %s' % rowref)
- if rowref is not None:
- if rowref.isDirectory:
- logging.critical('res: %i' % len(rowref))
- return len(rowref)
- else:
- return
- else:
- return len(self.files)
-
- def on_iter_nth_child(self, rowref, n):
- if rowref is not None:
- if not rowref.isDirectory:
- return
- files = rowref
- else:
- files = self.files
- if n < len(files):
- return files[n]
-
- def on_iter_parent(self, child):
- return child.parent
-
- def on_iter_children(self, rowref):
- if rowref is not None:
- if rowref.isDirectory and len(rowref):
- return rowref[0]
- else:
- return
- else:
- return self.files[0]
-
-
-class ActivityNode(object):
-
- def __init__(self, filename, model, parent, nodefilter):
- self.filename = filename
- self.model = model
- self.nodefilter = nodefilter
- if parent is not None:
- self.path = os.path.join(parent.path, filename)
- else:
- self.path = os.path.join(model.root, filename)
- self.parent = parent
- self.isDirectory = os.path.isdir(self.path)
- self._files = None
-
- def _get_files(self):
- if not self.isDirectory:
- return None
- if self._files is None:
- files = sorted(os.listdir(self.path))
- self._files = filter(
- self.nodefilter,
- (ActivityNode(filename, self.model, self, self.nodefilter)
- for filename in files))
- if not self._files:
- self._files = (DummyActivityNode(self),)
- return self._files
- files = property(_get_files) # TODO: use a decorator
-
- def __eq__(self, other):
- if not isinstance(other, ActivityNode):
- if isinstance(other, str):
- return self.filename == other
- else:
- return False
- return self.path == other.path
-
- def __len__(self):
- return len(self.files)
-
- def index(self, item):
- return self.files.index(item)
-
- def __getitem__(self, n):
- return self.files[n]
-
- def getTreePath(self):
- if self.parent is None:
- return (self.model.files.index(self),)
- parentPath = self.parent.getTreePath()
- return parentPath + (self.parent.files.index(self),)
-
- def __hash__(self):
- return hash(self.path)
-
- def __str__(self):
- return '<ActivityNode %s>' % self.path
-
- __repr__ = __str__
-
- def __eq__(self, other):
- return other == self.path or other == self.filename
-
-
-class DummyActivityNode(ActivityNode):
- files = ()
- filename = _("<No visible files>")
- path = ""
- isDirectory = False
-
- def __init__(self, parent):
- self.parent = parent
diff --git a/develop-activity/develop_app.py b/develop-activity/develop_app.py
index 4d0d430..ef7f8b5 100644
--- a/develop-activity/develop_app.py
+++ b/develop-activity/develop_app.py
@@ -13,39 +13,39 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""Develop Activity: A programming activity."""
-import gtk
import logging
import os
import os.path
-import gobject
import simplejson
-
from gettext import gettext as _
-from sugar import profile
-from sugar.graphics.toolbarbox import ToolbarBox
-from sugar.activity.widgets import ActivityToolbarButton
-from sugar.graphics.toolbarbox import ToolbarButton
-from sugar.graphics.radiotoolbutton import RadioToolButton
-from sugar.activity.widgets import StopButton
-from sugar.activity.bundlebuilder import XOPackager, Config, Builder
-from sugar.activity import activity
-from sugar.graphics.toolbutton import ToolButton
-from sugar.graphics.combobox import ComboBox
-from sugar.graphics.alert import ConfirmationAlert
-from sugar.graphics.alert import Alert
-from sugar.graphics import iconentry, notebook
-from sugar.graphics.icon import Icon
-from sugar.graphics import style
-from sugar.datastore import datastore
-from sugar.bundle.activitybundle import ActivityBundle
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import GObject
+
+from sugar3 import profile
+from sugar3.graphics.toolbarbox import ToolbarBox
+from sugar3.graphics.toolbarbox import ToolbarButton
+from sugar3.graphics.radiotoolbutton import RadioToolButton
+from sugar3.activity.widgets import ActivityToolbarButton
+from sugar3.activity.widgets import EditToolbar
+from sugar3.activity.widgets import StopButton
+from sugar3.activity.bundlebuilder import XOPackager, Config, Builder
+from sugar3.activity import activity
+from sugar3.graphics.toolbutton import ToolButton
+from sugar3.graphics.combobox import ComboBox
+from sugar3.graphics.alert import ConfirmationAlert
+from sugar3.graphics.alert import Alert
+from sugar3.graphics import iconentry, notebook
+from sugar3.graphics.icon import Icon
+from sugar3.graphics import style
+from sugar3.datastore import datastore
+from sugar3.bundle.activitybundle import ActivityBundle
import logviewer
import sourceview_editor
S_WHERE = sourceview_editor.S_WHERE
-import activity_model
import new_activity
-
from symbols_tree import SymbolsTree
DEBUG_FILTER_LEVEL = 1
@@ -68,7 +68,9 @@ REPLACE_ICONS = {False: "replace-and-find", True: "multi-replace"}
TOOLBAR_SEARCH = 2
-OPENFILE_SEPARATOR = u"@ @"
+_EXCLUDE_EXTENSIONS = ('.pyc', '.pyo', '.so', '.o', '.a', '.la', '.mo', '~',
+ '.xo', '.tar', '.bz2', '.zip', '.gz')
+_EXCLUDE_NAMES = ['.deps', '.libs']
class Options:
@@ -91,14 +93,16 @@ class DevelopActivity(activity.Activity):
def __init__(self, handle):
"""Set up the Develop activity."""
- self.dirty = False
+ self._dirty = False
super(DevelopActivity, self).__init__(handle)
self.max_participants = 1
logging.info(repr(handle.get_dict()))
# Source buffer
- self.editor = sourceview_editor.GtkSourceview2Editor(self)
+ self.editor = sourceview_editor.GtkSourceview2Editor()
+ self.editor.connect('tab-changed', self.__editor_tab_changed_cb)
+ self.editor.connect('changed', self.__editor_changed_cb)
toolbarbox = ToolbarBox()
activity_button = ActivityToolbarButton(self)
@@ -117,7 +121,7 @@ class DevelopActivity(activity.Activity):
search_btn.props.label = _('Search')
toolbarbox.toolbar.insert(search_btn, -1)
- toolbarbox.toolbar.insert(gtk.SeparatorToolItem(), -1)
+ toolbarbox.toolbar.insert(Gtk.SeparatorToolItem(), -1)
show_files_btn = RadioToolButton()
show_files_btn.props.icon_name = 'sources'
@@ -133,7 +137,7 @@ class DevelopActivity(activity.Activity):
show_symbols_btn.set_active(False)
show_symbols_btn.set_tooltip(_('Show file symbols'))
toolbarbox.toolbar.insert(show_symbols_btn, -1)
- show_symbols_btn.connect('clicked', self.explore_code)
+ show_symbols_btn.connect('clicked', self._explore_code)
show_log_btn = RadioToolButton()
show_log_btn.props.icon_name = 'logs'
@@ -143,7 +147,7 @@ class DevelopActivity(activity.Activity):
toolbarbox.toolbar.insert(show_log_btn, -1)
show_log_btn.connect('clicked', self._change_treenotebook_page, 2)
- toolbarbox.toolbar.insert(gtk.SeparatorToolItem(), -1)
+ toolbarbox.toolbar.insert(Gtk.SeparatorToolItem(), -1)
create_file_btn = ToolButton('text-x-generic')
create_file_btn.set_tooltip(_('Create empty file'))
@@ -157,7 +161,7 @@ class DevelopActivity(activity.Activity):
erase_btn.show()
erase_btn.connect('clicked', self.__remove_file_cb)
- separator = gtk.SeparatorToolItem()
+ separator = Gtk.SeparatorToolItem()
separator.set_draw(False)
separator.set_expand(True)
toolbarbox.toolbar.insert(separator, -1)
@@ -174,8 +178,8 @@ class DevelopActivity(activity.Activity):
toolbarbox.show_all()
# Main layout.
- hbox = gtk.HPaned()
- vbox = gtk.VBox()
+ hbox = Gtk.HPaned()
+ vbox = Gtk.VBox()
#The treeview and selected pane reflect each other.
self.numb = False
@@ -185,39 +189,30 @@ class DevelopActivity(activity.Activity):
self.save_unchanged = False
# The sidebar
- sidebar = gtk.VBox()
+ sidebar = Gtk.VBox()
self.treenotebook = notebook.Notebook(can_close_tabs=False)
self.treenotebook.set_show_tabs(False)
- sidebar.pack_start(self.treenotebook)
-
- self.model = gtk.TreeStore(gobject.TYPE_PYOBJECT, gobject.TYPE_STRING)
- self.treeview = gtk.TreeView(self.model)
- cellrenderer = gtk.CellRendererText()
- self.treecolumn = gtk.TreeViewColumn(_("Activities"), cellrenderer,
- text=1)
- self.treeview.append_column(self.treecolumn)
- self.treeview.set_size_request(gtk.gdk.screen_width() / 4, -1)
-
- # Create scrollbars around the tree view.
- scrolled = gtk.ScrolledWindow()
- scrolled.add(self.treeview)
- scrolled.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- self.treenotebook.add_page(_("Activity"), scrolled)
+ sidebar.pack_start(self.treenotebook, True, True, 0)
+
+ self.activity_tree_view = FileViewer()
+ #self.activity_tree_view = ActivityTreeView()
+ self.treenotebook.add_page(_("Activity"), self.activity_tree_view)
+ self.treenotebook.set_size_request(Gdk.Screen.width() / 5, -1)
# Symbols tree
self._symbolstree = SymbolsTree()
self._symbolstree.connect('symbol-selected',
self.editor.symbol_selected_cb)
- scrolled = gtk.ScrolledWindow()
+ scrolled = Gtk.ScrolledWindow()
scrolled.add(self._symbolstree)
- scrolled.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+ scrolled.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
self.treenotebook.add_page(_('Symbols Tree'), scrolled)
- hbox.pack1(sidebar, resize=True, shrink=True)
+ hbox.pack1(sidebar, resize=True, shrink=False)
sidebar.show()
logging.info('finished check')
- vbox.pack_start(self.editor)
+ vbox.pack_start(self.editor, True, True, 0)
self.editor.show()
hbox.pack2(vbox, resize=True, shrink=True)
vbox.show()
@@ -228,15 +223,16 @@ class DevelopActivity(activity.Activity):
self.show()
if not handle.object_id or not self.metadata.get('source'):
- gobject.timeout_add(10, self._show_welcome)
+ GObject.timeout_add(10, self._show_welcome)
def _change_treenotebook_page(self, button, page):
self.treenotebook.set_current_page(page)
- def explore_code(self, btn, switch_page=True):
+ def _explore_code(self, btn, switch_page=True):
from ninja import introspection
text = self.editor.get_text()
path = self.editor.get_file_path()
+ logging.error('Analyzing %s', path)
symbols = introspection.obtain_symbols(text, filename=path)
self._symbolstree.load_symbols(symbols)
if switch_page:
@@ -266,9 +262,9 @@ class DevelopActivity(activity.Activity):
def _show_welcome(self):
"""_show_welcome: when opened without a bundle, ask open/new/cancel
"""
- vbox = gtk.VBox()
+ vbox = Gtk.VBox()
- edit_label = gtk.Label(
+ edit_label = Gtk.Label(
_('<span weight="bold" size="larger">'
'Edit a installed activity</span>\n\n'
'You can modify a activity, and if there are errors the '
@@ -278,23 +274,23 @@ class DevelopActivity(activity.Activity):
edit_label.set_line_wrap(True)
vbox.pack_start(edit_label, expand=False, fill=True, padding=10)
- hbox_edit = gtk.HBox()
- hbox_edit.pack_start(gtk.Label('Select the activity'), expand=False,
- fill=False, padding=10)
+ hbox_edit = Gtk.HBox()
+ hbox_edit.pack_start(Gtk.Label(_('Select the activity')), True,
+ True, 10)
activity_name_combo = ComboBox()
self._load_activities_installed_combo(activity_name_combo)
hbox_edit.pack_start(activity_name_combo, expand=False, fill=False,
padding=10)
- edit_btn = gtk.Button(_('Start'))
+ edit_btn = Gtk.Button(_('Start'))
edit_btn.connect('clicked', self._pick_existing_activity,
activity_name_combo)
hbox_edit.pack_start(edit_btn, expand=False, fill=False,
padding=10)
- align = gtk.Alignment(xalign=0.5, yalign=0.5)
+ align = Gtk.Alignment.new(0.5, 0.5, 0, 0)
align.add(hbox_edit)
vbox.pack_start(align, expand=False, fill=False, padding=10)
- new_project_label = gtk.Label(
+ new_project_label = Gtk.Label(
_('<span weight="bold" size="larger">'
'Create a new activity</span>\n\n'
'You can create something new, '
@@ -303,34 +299,34 @@ class DevelopActivity(activity.Activity):
new_project_label.set_line_wrap(True)
vbox.pack_start(new_project_label, expand=False, fill=True, padding=10)
- hbox_create = gtk.HBox()
- hbox_create.pack_start(gtk.Label('Select the type'),
+ hbox_create = Gtk.HBox()
+ hbox_create.pack_start(Gtk.Label(_('Select the type')),
expand=False, fill=False, padding=10)
project_type_combo = ComboBox()
self._load_skeletons_combo(project_type_combo)
hbox_create.pack_start(project_type_combo, expand=False, fill=False,
padding=10)
- align = gtk.Alignment(xalign=0.5, yalign=0.5)
+ align = Gtk.Alignment.new(0.5, 0.5, 0, 0)
align.add(hbox_create)
vbox.pack_start(align, expand=False, fill=False, padding=10)
- hbox_name = gtk.HBox()
- hbox_name.pack_start(gtk.Label(_('Name the activity')))
- activity_name_entry = gtk.Entry()
+ hbox_name = Gtk.HBox()
+ hbox_name.pack_start(Gtk.Label(_('Name the activity')), True, True, 0)
+ activity_name_entry = Gtk.Entry()
hbox_name.pack_start(activity_name_entry, expand=True, fill=True,
padding=10)
- create_btn = gtk.Button(_('Start'))
+ create_btn = Gtk.Button(_('Start'))
create_btn.connect('clicked', self._create_new_activity,
activity_name_entry, project_type_combo)
hbox_name.pack_start(create_btn, expand=True, fill=True,
padding=10)
- align = gtk.Alignment(xalign=0.5, yalign=0.5)
+ align = Gtk.Alignment.new(0.5, 0.5, 0, 0)
align.add(hbox_name)
vbox.pack_start(align, expand=False, fill=False, padding=10)
vbox.show_all()
- self.editor.append_page(vbox, gtk.Label(_('Start')))
+ self.editor.append_page(vbox, Gtk.Label(label=_('Start')))
return False
def _load_activities_installed_combo(self, activities_combo):
@@ -392,7 +388,7 @@ class DevelopActivity(activity.Activity):
title = _('Atention')
alert.props.title = title
alert.props.msg = message
- alert.add_button(gtk.RESPONSE_OK, _('Ok'))
+ alert.add_button(Gtk.ResponseType.OK, _('Ok'))
self.add_alert(alert)
alert.connect('response', self._alert_response_cb)
@@ -420,10 +416,12 @@ class DevelopActivity(activity.Activity):
activity_dir = activity_dir + '/'
self.activity_dir = activity_dir
name = os.path.basename(activity_dir)
- self.treecolumn.set_title(name)
+ self.activity_tree_view.set_title(name)
self.metadata['title'] = 'Develop %s' % name
self.refresh_files()
- self.treeview.get_selection().connect("changed", self.selection_cb)
+
+ self.activity_tree_view.connect('file_selected',
+ self.__file_selected_cb)
return name
def first_open_activity(self, activity_dir):
@@ -432,17 +430,18 @@ class DevelopActivity(activity.Activity):
"""
self.open_activity(activity_dir)
namefilter = ActivityBundle(activity_dir).get_bundle_id()
- self.logview = logviewer.LogMinder(self, namefilter)
- self.set_dirty(False)
+ self._log_files_viewer = logviewer.LogFilesViewer(namefilter)
+ self._log_files_viewer.connect('file-selected',
+ self.__log_file_selected_cb)
+ self.treenotebook.add_page(_("Log"), self._log_files_viewer)
+
+ self._set_dirty(False)
def refresh_files(self):
"""Refresh the treeview of activity files.
"""
self.bundle = ActivityBundle(self.activity_dir)
- self.model = activity_model.DirectoryAndExtraModel(
- self.activity_dir,
- nodefilter=activity_model.inmanifestfn(self.bundle))
- self.treeview.set_model(self.model)
+ self.activity_tree_view.load_activity(self.activity_dir, self.bundle)
def load_file(self, full_path):
"""Load one activity subfile into the editor view.
@@ -458,19 +457,32 @@ class DevelopActivity(activity.Activity):
logging.error('load_file filename %s', filename)
self.editor.load_object(full_path, filename)
- def selection_cb(self, column):
+ def __file_selected_cb(self, file_viewer, path):
"""User selected an item in the treeview. Load it.
"""
if self.numb:
#Choosing in the notebook selects in the list, and vice versa.
#Avoid infinite recursion.
return
- path = activity_model.get_selected_file_path(self.treeview)
if path and not os.path.isdir(path):
self.numb = True
self.load_file(path)
self.numb = False
+ def __log_file_selected_cb(self, log_files_viewer, path):
+ if not path:
+ return
+
+ if os.path.isdir(path):
+ #do not try to open folders
+ return
+
+ # Set buffer and scroll down
+ if self.editor.set_to_page_like(path):
+ return
+
+ self.editor.load_log_file(path, log_files_viewer)
+
def save_bundle(self, btn):
#create bundle
builder = XOPackager(Builder(Config(self.activity_dir, '/tmp')))
@@ -544,17 +556,19 @@ class DevelopActivity(activity.Activity):
def write_file(self, file_path):
"""Wrap up the activity as a bundle and save it to journal.
"""
+ logging.error('WRITE_FILE')
if self.activity_dir is None:
return
- if not self.save_unchanged:
+ if self.save_unchanged:
self.editor.save_all()
- filenames = OPENFILE_SEPARATOR.join(self.editor.get_all_filenames())
+ filenames = self.editor.get_all_filenames()
logging.debug('activity_dir %s, file_path %s, filenames %s' %
- (self.activity_dir, file_path, len(filenames)))
+ (self.activity_dir, file_path, filenames))
self._jobject = self.save_source_jobject(
self.activity_dir, file_path, filenames)
self.metadata['source'] = self.activity_dir
- self.set_dirty(False)
+ self._set_dirty(False)
+ self.save_unchanged = False
def read_file(self, file_path):
self.activity_dir = self.metadata['source']
@@ -564,45 +578,39 @@ class DevelopActivity(activity.Activity):
f = open(file_path, 'r')
try:
session_data = simplejson.load(f)
- for filename in \
- session_data['open_filenames'].split(OPENFILE_SEPARATOR):
+ logging.error('read_file session_data %s', session_data)
+ for filename in session_data['open_filenames']:
if filename:
logging.info('opening : %s', filename)
self.load_file(filename)
finally:
f.close()
- self.set_dirty(False)
-
- def is_dirty(self):
- return self.dirty
+ self._set_dirty(False)
- def set_dirty(self, dirty):
+ def _set_dirty(self, dirty):
logging.debug("Setting dirty to %s; activity_dir is %s" %
(str(dirty), str(self.activity_dir)))
- self.dirty = dirty
+ self._dirty = dirty
if dirty:
self.save_unchanged = True
- try:
- logging.debug("Saving a pristine copy for safety")
- self.save()
- finally:
- self.save_unchanged = False
- self.dirty = dirty
- def update_sidebar_to_page(self, page):
+ def __editor_tab_changed_cb(self, editor, new_full_path):
if self.numb:
#avoid infinite recursion
return
- if isinstance(page, sourceview_editor.GtkSourceview2Page):
- source = page.full_path
- tree_iter = self.model.get_iter_from_filepath(source)
- if tree_iter:
- tree_selection = self.treeview.get_selection()
- tree_selection.unselect_all()
- self.numb = True
- tree_selection.select_iter(tree_iter)
- self.numb = False
+ self.numb = True
+ self.activity_tree_view.select_by_file_path(new_full_path)
+ logging.error('new tab %s', new_full_path)
+ self.numb = False
+
+ # TODO: change by a constant
+ if self.treenotebook.get_current_page() == 1: # symbols
+ GObject.idle_add(self._explore_code, None)
+
+ def __editor_changed_cb(self, editor):
+ logging.error('Editor text changed')
+ self._set_dirty(True)
def __create_empty_file_cb(self, button):
alert = Alert()
@@ -611,19 +619,19 @@ class DevelopActivity(activity.Activity):
#HACK
alert._hbox.remove(alert._buttons_box)
- alert.entry = gtk.Entry()
- alert._hbox.pack_start(alert.entry)
+ alert.entry = Gtk.Entry()
+ alert._hbox.pack_start(alert.entry, True, True, 0)
- alert._buttons_box = gtk.HButtonBox()
- alert._buttons_box.set_layout(gtk.BUTTONBOX_END)
+ alert._buttons_box = Gtk.HButtonBox()
+ alert._buttons_box.set_layout(Gtk.ButtonBoxStyle.END)
alert._buttons_box.set_spacing(style.DEFAULT_SPACING)
- alert._hbox.pack_start(alert._buttons_box)
+ alert._hbox.pack_start(alert._buttons_box, True, True, 0)
icon = Icon(icon_name='dialog-cancel')
- alert.add_button(gtk.RESPONSE_CANCEL, _('Cancel'), icon)
+ alert.add_button(Gtk.ResponseType.CANCEL, _('Cancel'), icon)
icon = Icon(icon_name='dialog-ok')
- alert.add_button(gtk.RESPONSE_OK, _('Ok'), icon)
+ alert.add_button(Gtk.ResponseType.OK, _('Ok'), icon)
alert.show_all()
#
@@ -631,31 +639,32 @@ class DevelopActivity(activity.Activity):
alert.connect('response', self.__create_file_alert_cb)
def __create_file_alert_cb(self, alert, response_id):
- file_name = alert.entry.get_text()
- try:
- path = os.path.dirname(self.editor.get_file_path())
- except:
- path = self.activity_dir
+ if response_id is Gtk.ResponseType.OK:
+ file_name = alert.entry.get_text()
+ try:
+ path = os.path.dirname(self.editor.get_file_path())
+ except:
+ path = self.activity_dir
- file_path = os.path.join(path, file_name)
- with open(file_path, 'w') as new_file:
- new_file.write('')
+ file_path = os.path.join(path, file_name)
+ with open(file_path, 'w') as new_file:
+ new_file.write('')
- self.refresh_files()
- self.editor.load_object(file_path, file_name)
+ self.refresh_files()
+ self.editor.load_object(file_path, file_name)
self.remove_alert(alert)
def __remove_file_cb(self, button):
file_path = self.editor.get_file_path()
- msg = _('The action you will do can not be revereted.\n'
- 'Do you want remove the file %s?') % file_path
- alert = self.create_confirmation_alert(msg, _('WARNING'))
+ title = _('WARNING: The action you will do can not be reverted.')
+ msg = _('Do you want remove the file %s?') % file_path
+ alert = self.create_confirmation_alert(msg, title)
alert.show()
alert.connect('response', self.__remove_file_alert_cb, file_path)
def __remove_file_alert_cb(self, alert, response_id, file_path):
- if response_id is gtk.RESPONSE_OK:
+ if response_id is Gtk.ResponseType.OK:
if os.path.isfile(file_path):
os.unlink(file_path)
self.refresh_files()
@@ -663,10 +672,123 @@ class DevelopActivity(activity.Activity):
self.remove_alert(alert)
-class DevelopEditToolbar(activity.EditToolbar):
+class FileViewer(Gtk.ScrolledWindow):
+ __gtype_name__ = 'ActivityFileViewer'
+
+ __gsignals__ = {
+ 'file-selected': (GObject.SignalFlags.RUN_FIRST,
+ None,
+ ([str])),
+ }
+
+ def __init__(self):
+ Gtk.ScrolledWindow.__init__(self)
+
+ self.props.hscrollbar_policy = Gtk.PolicyType.AUTOMATIC
+ self.props.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC
+ self.set_size_request(style.GRID_CELL_SIZE * 3, -1)
+
+ self._path = None
+ self._initial_filename = None
+
+ self._tree_view = Gtk.TreeView()
+ self._tree_view.connect('cursor-changed', self.__cursor_changed_cb)
+ self.add(self._tree_view)
+ self._tree_view.show()
+
+ self._tree_view.props.headers_visible = False
+ selection = self._tree_view.get_selection()
+ selection.connect('changed', self.__selection_changed_cb)
+
+ cell = Gtk.CellRendererText()
+ self._column = Gtk.TreeViewColumn()
+ self._column.pack_start(cell, True)
+ self._column.add_attribute(cell, 'text', 0)
+ self._tree_view.append_column(self._column)
+ self._tree_view.set_search_column(0)
+ # map between file_path and iter
+ self._opened_files = {}
+
+ def load_activity(self, path, bundle):
+ self._search_initial_filename(path, bundle)
+ self._path = path
+
+ self._tree_view.set_model(Gtk.TreeStore(str, str))
+ self._model = self._tree_view.get_model()
+ self._add_dir_to_model(path)
+
+ def _add_dir_to_model(self, dir_path, parent=None):
+ for f in os.listdir(dir_path):
+ if f.endswith(_EXCLUDE_EXTENSIONS) or f in _EXCLUDE_NAMES:
+ continue
+
+ full_path = os.path.join(dir_path, f)
+ if os.path.isdir(full_path):
+ new_iter = self._model.append(parent, [f, full_path])
+ self._add_dir_to_model(full_path, new_iter)
+ else:
+ current_iter = self._model.append(parent, [f, full_path])
+ self._opened_files[full_path] = current_iter
+ if full_path == self._initial_filename:
+ selection = self._tree_view.get_selection()
+ selection.select_iter(current_iter)
+
+ def __selection_changed_cb(self, selection):
+ model, tree_iter = selection.get_selected()
+ if tree_iter is None:
+ file_path = None
+ else:
+ file_path = model.get_value(tree_iter, 1)
+ self.emit('file-selected', file_path)
+
+ def __cursor_changed_cb(self, tree_view):
+ selection = tree_view.get_selection()
+ store, iter_ = selection.get_selected()
+ if iter_ is None:
+ # Nothing selected. This happens at startup
+ return
+ if store.iter_has_child(iter_):
+ path = store.get_path(iter_)
+ if tree_view.row_expanded(path):
+ tree_view.collapse_row(path)
+ else:
+ tree_view.expand_row(path, False)
+
+ def select_by_file_path(self, file_path):
+ if file_path in self._opened_files:
+ tree_iter = self._opened_files[file_path]
+ tree_selection = self._tree_view.get_selection()
+ tree_selection.unselect_all()
+ tree_selection.select_iter(tree_iter)
+
+ def _search_initial_filename(self, activity_path, bundle):
+ command = bundle.get_command()
+
+ if self._is_web_activity(bundle):
+ file_name = 'index.html'
+
+ elif len(command.split(' ')) > 1:
+ name = command.split(' ')[1].split('.')[-1]
+ tmppath = command.split(' ')[1].replace('.', '/')
+ file_name = tmppath[0:-(len(name) + 1)] + '.py'
+
+ if file_name:
+ path = os.path.join(activity_path, file_name)
+ if os.path.exists(path):
+ logging.error('INITIAL_FILENAME %s', path)
+ self._initial_filename = path
+
+ def set_title(self, title):
+ self._column.set_title(title)
+
+ def _is_web_activity(self, activity_bundle):
+ return activity_bundle.get_command() == 'sugar-activity-web'
+
+
+class DevelopEditToolbar(EditToolbar):
def __init__(self, _activity):
- activity.EditToolbar.__init__(self)
+ EditToolbar.__init__(self)
self._activity = _activity
self._activity.editor.connect('changed', self._changed_cb)
@@ -679,7 +801,7 @@ class DevelopEditToolbar(activity.EditToolbar):
# make expanded non-drawn visible separator to make
#the search stuff right-align
- separator = gtk.SeparatorToolItem()
+ separator = Gtk.SeparatorToolItem()
separator.props.draw = False
separator.set_expand(True)
self.insert(separator, -1)
@@ -706,7 +828,7 @@ class DevelopEditToolbar(activity.EditToolbar):
# bad paul! this function was copied from sugar's activity.py via Write
def _add_widget(self, widget, expand=False):
- tool_item = gtk.ToolItem()
+ tool_item = Gtk.ToolItem()
tool_item.set_expand(expand)
tool_item.add(widget)
@@ -716,10 +838,10 @@ class DevelopEditToolbar(activity.EditToolbar):
tool_item.show()
-class DevelopSearchToolbar(gtk.Toolbar):
+class DevelopSearchToolbar(Gtk.Toolbar):
def __init__(self, _activity):
- gtk.Toolbar.__init__(self)
+ GObject.GObject.__init__(self)
self._activity = _activity
@@ -790,7 +912,7 @@ class DevelopSearchToolbar(gtk.Toolbar):
(_('Advanced search'), ssho, True, "regex"),
):
if not name:
- menuitem = gtk.SeparatorMenuItem()
+ menuitem = Gtk.SeparatorMenuItem()
else:
menuitem = MenuItem(name, icon)
menuitem.connect('activate', function, options)
@@ -799,7 +921,7 @@ class DevelopSearchToolbar(gtk.Toolbar):
# make expanded non-drawn visible separator to make the replace
#stuff right-align
- separator = gtk.SeparatorToolItem()
+ separator = Gtk.SeparatorToolItem()
separator.props.draw = False
separator.set_expand(True)
self.insert(separator, -1)
@@ -829,7 +951,7 @@ class DevelopSearchToolbar(gtk.Toolbar):
(_('Replace all'), ssro, True, "multi-replace"),
):
if not name:
- menuitem = gtk.SeparatorMenuItem()
+ menuitem = Gtk.SeparatorMenuItem()
else:
menuitem = MenuItem(name, icon)
menuitem.connect('activate', function, options)
@@ -842,7 +964,7 @@ class DevelopSearchToolbar(gtk.Toolbar):
self._activity.connect('key_press_event', self._on_key_press_event)
def _on_key_press_event(self, widget, event):
- keyname = gtk.gdk.keyval_name(event.keyval)
+ keyname = Gdk.keyval_name(event.keyval)
if "F5" <= keyname and keyname <= "F8":
if keyname == "F5":
self._go_to_search_entry_cb()
@@ -959,7 +1081,6 @@ class DevelopSearchToolbar(gtk.Toolbar):
pass
#self._replace_button.set_sensitive(True)
-
def _findnext_cb(self, button=None):
ftext = self._search_entry.props.text
if ftext:
@@ -969,7 +1090,7 @@ class DevelopSearchToolbar(gtk.Toolbar):
# bad paul! this function was copied from sugar's activity.py via Write
def _add_widget(self, widget, expand=False):
- tool_item = gtk.ToolItem()
+ tool_item = Gtk.ToolItem()
tool_item.set_expand(expand)
tool_item.add(widget)
diff --git a/develop-activity/logviewer.py b/develop-activity/logviewer.py
index 73d3007..d4e30f8 100644
--- a/develop-activity/logviewer.py
+++ b/develop-activity/logviewer.py
@@ -22,155 +22,154 @@ import os.path
import logging
from gettext import gettext as _
-import gtk
-import gio
+from gi.repository import Gdk
+from gi.repository import Gtk
+from gi.repository import Gio
+from gi.repository import GObject
-import activity_model
-from sourceview_editor import TabLabel
+from sugar3.graphics import style
+from sugar3 import env
-#does not import develop_app, but references internals from the activity,
-# as passed to init.
-#In other words, needs refactoring.
+from sourceview_editor import TabLabel
def _get_filename_from_path(path):
return os.path.split(path)[-1]
-class LogMinder(gtk.VBox):
- def __init__(self, activity, namefilter, path=None, extra_files=None):
- self.activity = activity
+class LogFilesViewer(Gtk.ScrolledWindow):
+ __gtype_name__ = 'LogFileViewer'
+
+ __gsignals__ = {
+ 'file-selected': (GObject.SignalFlags.RUN_FIRST,
+ None,
+ ([str])),
+ }
+
+ def __init__(self, namefilter):
+
self._openlogs = []
- logging.info('creating MultiLogView')
- if not path:
- # Main path to watch: ~/.sugar/someuser/logs...
- path = os.path.join(os.path.expanduser("~"), ".sugar", "default",
- "logs")
-
- if not extra_files:
- # extra files to watch in logviewer
- extra_files = []
- extra_files.append("/var/log/Xorg.0.log")
- extra_files.append("/var/log/syslog")
- extra_files.append("/var/log/messages")
-
- self._logs_path = path + '/'
- self._active_log = None
- self._extra_files = extra_files
+ logging.info('creating LogFilesViewer namefilter %s', namefilter)
+ self._path = env.get_logs_path()
+ logging.error('LOGS PATH %s', self._path)
+
+ self._extra_files = [os.path.join(self._path, 'shell.log')]
self._namefilter = namefilter
- # Creating Main treeview with Actitivities list
- self._tv_menu = gtk.TreeView()
- self._tv_menu.connect('cursor-changed', self._load_log)
- self._tv_menu.set_rules_hint(True)
- cellrenderer = gtk.CellRendererText()
- self.treecolumn = gtk.TreeViewColumn(_("Sugar logs"), cellrenderer,
- text=1)
- self._tv_menu.append_column(self.treecolumn)
- self._tv_menu.set_size_request(220, 900)
+ Gtk.ScrolledWindow.__init__(self)
- # Create scrollbars around the tree view.
- scrolled = gtk.ScrolledWindow()
- scrolled.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- scrolled.add(self._tv_menu)
+ self.props.hscrollbar_policy = Gtk.PolicyType.AUTOMATIC
+ self.props.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC
+ self.set_size_request(style.GRID_CELL_SIZE * 3, -1)
- # the internals of the treeview
- self._model = activity_model.DirectoryAndExtraModel(
- path, extra_files, self._filter_by_name)
+ self._tree_view = Gtk.TreeView()
+ self._tree_view.connect('cursor-changed', self.__cursor_changed_cb)
+ self.add(self._tree_view)
+ self._tree_view.show()
- self._tv_menu.set_model(self._model)
+ self._tree_view.props.headers_visible = False
+ selection = self._tree_view.get_selection()
+ selection.connect('changed', self.__selection_changed_cb)
- self._logs = {}
- self._monitors = []
+ cell = Gtk.CellRendererText()
+ self._column = Gtk.TreeViewColumn()
+ self._column.pack_start(cell, True)
+ self._column.add_attribute(cell, 'text', 0)
+ self._tree_view.append_column(self._column)
+ self._tree_view.set_search_column(0)
- # Activities menu
- self.activity.treenotebook.add_page(_("Log"), scrolled)
+ # Configuration
+ self.set_title(_("Sugar logs"))
+ self.init_logs(self._filter_by_name)
+ self._monitors = []
self._configure_watcher()
def _configure_watcher(self):
- logging.error('Monitor directory %s', self._logs_path)
- dir_monitor = gio.File(self._logs_path).monitor_directory()
+ logging.error('Monitor directory %s', self._path)
+ directory = Gio.File.new_for_path(self._path)
+ dir_monitor = directory.monitor_directory(
+ flags=Gio.FileMonitorFlags.NONE, cancellable=None)
dir_monitor.set_rate_limit(2000)
dir_monitor.connect('changed', self._log_file_changed_cb)
self._monitors.append(dir_monitor)
-
for f in self._extra_files:
logging.error('Monitor file %s', f)
- file_monitor = gio.File(f).monitor_file()
+ gio_file = Gio.File.new_for_path(f)
+ file_monitor = gio_file.monitor_file(
+ Gio.FileMonitorFlags.NONE, None)
file_monitor.set_rate_limit(2000)
file_monitor.connect('changed', self._log_file_changed_cb)
self._monitors.append(file_monitor)
def _log_file_changed_cb(self, monitor, path1, path2, event):
- _directory, logfile = os.path.split(str(path1))
-
- if event == gio.FILE_MONITOR_EVENT_CHANGED:
+ if event == Gio.FileMonitorEvent.CHANGED:
for log in self._openlogs:
- if logfile in log.full_path:
+ if path1.get_path() == log.full_path:
+ logging.debug('updating logfile %s', path1.get_path())
log.update()
- elif (event == gio.FILE_MONITOR_EVENT_DELETED
- or event == gio.FILE_MONITOR_EVENT_CREATED):
- self._model.refresh()
- #If the log is open, just leave it that way
-
- # Load the log information in View (text_view)
- def _load_log(self, treeview):
- node = activity_model.get_selected_file(self._tv_menu)
- print node
- path = node["path"]
-
- if os.path.isdir(path):
- #do not try to open folders
- logging.debug("Cannot open a folder as text :)")
+ elif (event == Gio.FileMonitorEvent.DELETED
+ or event == Gio.FileMonitorEvent.CREATED):
+ self.load_model()
+
+ def _filter_by_name(self, filename):
+ return self._namefilter in filename or filename in self._extra_files
+
+ def init_logs(self, filter_function):
+ self._filter_function = filter_function
+ self.load_model()
+
+ def load_model(self):
+ self._tree_view.set_model(Gtk.TreeStore(str, str))
+ self._model = self._tree_view.get_model()
+ self._add_dir_to_model(self._path, self._filter_function)
+
+ def _add_dir_to_model(self, dir_path, filter_function, parent=None):
+ for f in os.listdir(dir_path):
+ full_path = os.path.join(dir_path, f)
+ if os.path.isdir(full_path):
+ new_iter = self._model.append(parent, [f, full_path])
+ self._add_dir_to_model(full_path, filter_function, new_iter)
+ else:
+ if filter_function(full_path):
+ self._model.append(parent, [f, full_path])
+
+ def __selection_changed_cb(self, selection):
+ model, tree_iter = selection.get_selected()
+ if tree_iter is None:
+ file_path = None
+ else:
+ file_path = model.get_value(tree_iter, 1)
+ self.emit('file-selected', file_path)
+
+ def __cursor_changed_cb(self, treeview):
+ selection = treeview.get_selection()
+ store, iter_ = selection.get_selected()
+ if iter_ is None:
+ # Nothing selected. This happens at startup
return
+ if store.iter_has_child(iter_):
+ path = store.get_path(iter_)
+ if treeview.row_expanded(path):
+ treeview.collapse_row(path)
+ else:
+ treeview.expand_row(path, False)
- if not path:
- #DummyActivityNode
- return
+ def set_title(self, title):
+ self._column.set_title(title)
- # Set buffer and scroll down
- if self.activity.editor.set_to_page_like(path):
- return
- newlogview = LogView(path, self)
-
- scrollwnd = gtk.ScrolledWindow()
- scrollwnd.set_policy(gtk.POLICY_AUTOMATIC,
- gtk.POLICY_AUTOMATIC)
- scrollwnd.add(newlogview)
- scrollwnd.page = newlogview
- tablabel = TabLabel(newlogview, label=node["name"])
- tablabel.connect(
- 'tab-close',
- lambda widget, child: self.activity.editor.remove_page(
- self.activity.editor.page_num(child)))
- self.activity.editor.append_page(scrollwnd, tablabel)
- self._active_log = newlogview
- self.activity.editor.show_all()
- self.activity.editor.set_current_page(-1)
-
- def _filter_by_name(self, node):
- return (self._namefilter in node.filename) or node.isDirectory
-
- # Insert a Row in our TreeView
- def _insert_row(self, store, parent, name):
- iter = store.insert_before(parent, None)
- index = 0
- store.set_value(iter, index, name)
-
- return iter
-
- def _remove_logview(self, logview):
+ def remove_logview(self, logview):
try:
self._openlogs.remove(logview)
except ValueError:
logging.debug("_remove_logview failed")
-class LogBuffer(gtk.TextBuffer):
- def __init__(self, logfile, tagtable):
- gtk.TextBuffer.__init__(self, table=tagtable)
+class LogBuffer(Gtk.TextBuffer):
+
+ def __init__(self, logfile):
+ Gtk.TextBuffer.__init__(self)
self._logfile = logfile
self._pos = 0
@@ -193,62 +192,62 @@ class LogBuffer(gtk.TextBuffer):
self._written = 0
-class LogView(gtk.TextView):
+class LogView(Gtk.TextView):
- def __init__(self, full_path, logminder):
- gtk.TextView.__init__(self)
+ def __init__(self, full_path, log_file_viewer):
+ GObject.GObject.__init__(self)
- self.logminder = logminder
+ self._log_file_viewer = log_file_viewer
self.full_path = full_path
- self.logminder._openlogs.append(self)
+ self._log_file_viewer._openlogs.append(self)
- self.set_wrap_mode(gtk.WRAP_WORD)
-
- # Tags for search
- tagtable = gtk.TextTagTable()
- hilite_tag = gtk.TextTag('search-hilite')
- hilite_tag.props.background = '#FFFFB0'
- tagtable.add(hilite_tag)
- select_tag = gtk.TextTag('search-select')
- select_tag.props.background = '#B0B0FF'
- tagtable.add(select_tag)
+ self.set_wrap_mode(Gtk.WrapMode.WORD)
- newbuffer = self._create_log_buffer(full_path, tagtable)
+ newbuffer = self._create_log_buffer(full_path)
if newbuffer:
self.set_buffer(newbuffer)
self.text_buffer = newbuffer
# Set background color
- bgcolor = gtk.gdk.color_parse("#EEEEEE")
- self.modify_base(gtk.STATE_NORMAL, bgcolor)
+ bgcolor = Gdk.color_parse("#EEEEEE")
+ self.modify_base(Gtk.StateType.NORMAL, bgcolor)
self.set_editable(False)
self.show()
def remove(self):
- self.logminder._remove_logview(self)
+ self._log_file_viewer.remove_logview(self)
- def _create_log_buffer(self, path, tagtable):
+ def _create_log_buffer(self, path):
self._written = False
if os.path.isdir(path):
return False
if not os.path.exists(path):
- logging.error("ERROR: %s don't exists", path)
+ logging.error("_create_log_buffer: %s don't exists", path)
return False
if not os.access(path, os.R_OK):
- logging.error("ERROR: I can't read '%s' file", path)
+ logging.error("_create_log_buffer: I can't read '%s' file", path)
return False
self.filename = _get_filename_from_path(path)
- self._logbuffer = logbuffer = LogBuffer(path, tagtable)
+ self._logbuffer = LogBuffer(path)
+
+ # Tags for search
+ tagtable = self._logbuffer.get_tag_table()
+ hilite_tag = Gtk.TextTag.new('search-hilite')
+ hilite_tag.props.background = '#FFFFB0'
+ tagtable.add(hilite_tag)
+ select_tag = Gtk.TextTag.new('search-select')
+ select_tag.props.background = '#B0B0FF'
+ tagtable.add(select_tag)
- self._written = logbuffer._written
+ self._written = self._logbuffer._written
- return logbuffer
+ return self._logbuffer
def replace(self, *args, **kw):
return (False, False)
@@ -267,7 +266,8 @@ class LogView(gtk.TextView):
text_iter = _buffer.get_start_iter()
while True:
- next_found = text_iter.forward_search(text, 0)
+ next_found = text_iter.forward_search(
+ text, Gtk.TextSearchFlags.CASE_INSENSITIVE, None)
if next_found is None:
break
start, end = next_found
@@ -291,9 +291,11 @@ class LogView(gtk.TextView):
text_iter = _buffer.get_iter_at_mark(_buffer.get_insert())
if direction == 'backward':
- return text_iter.backward_search(self.search_text, 0)
+ return text_iter.backward_search(
+ self.search_text, Gtk.TextSearchFlags.CASE_INSENSITIVE, None)
else:
- return text_iter.forward_search(self.search_text, 0)
+ return text_iter.forward_search(
+ self.search_text, Gtk.TextSearchFlags.CASE_INSENSITIVE, None)
def search_next(self, direction):
next_found = self.get_next_result(direction)
@@ -306,5 +308,4 @@ class LogView(gtk.TextView):
_buffer.apply_tag_by_name('search-select', start, end)
_buffer.place_cursor(start)
- self.scroll_to_iter(start, 0.1)
- self.scroll_to_iter(end, 0.1)
+ self.scroll_to_iter(start, 0.1, False, 0, 0)
diff --git a/develop-activity/new_activity.py b/develop-activity/new_activity.py
index e939005..24f8a29 100644
--- a/develop-activity/new_activity.py
+++ b/develop-activity/new_activity.py
@@ -17,7 +17,7 @@ import os
import shutil
import logging
-from sugar.activity import activity
+from sugar3.activity import activity
def class_template(name):
diff --git a/develop-activity/setup.py b/develop-activity/setup.py
index 530f97c..c60f4d0 100755
--- a/develop-activity/setup.py
+++ b/develop-activity/setup.py
@@ -16,6 +16,6 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-from sugar.activity import bundlebuilder
+from sugar3.activity import bundlebuilder
bundlebuilder.start()
diff --git a/develop-activity/sourceview_editor.py b/develop-activity/sourceview_editor.py
index e29caed..e1278c7 100644
--- a/develop-activity/sourceview_editor.py
+++ b/develop-activity/sourceview_editor.py
@@ -15,40 +15,48 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import logging
-import gtk
-import gobject
-import pango
-import gtksourceview2
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import GObject
+from gi.repository import Pango
+from gi.repository import GtkSource
import os.path
import re
import mimetypes
from exceptions import ValueError, TypeError, IOError, OSError
+from sugar3 import profile
+from sugar3.graphics.icon import Icon
+
from widgets import TabLabel
+import logviewer
class S_WHERE:
selection, file, multifile = range(3) # an enum
-class GtkSourceview2Editor(gtk.Notebook):
+class GtkSourceview2Editor(Gtk.Notebook):
__gsignals__ = {
- 'changed': (gobject.SIGNAL_RUN_FIRST, None, [])
+ 'changed': (GObject.SignalFlags.RUN_FIRST, None, []),
+ 'tab-changed': (GObject.SignalFlags.RUN_FIRST, None, [str])
}
- def __init__(self, activity):
- gtk.Notebook.__init__(self)
- self.activity = activity
- self.set_size_request(gtk.gdk.screen_width(), -1)
+ def __init__(self):
+ GObject.GObject.__init__(self)
+ self.set_size_request(Gdk.Screen.width(), -1)
self.connect('page-removed', self._page_removed_cb)
self.connect('switch-page', self._switch_page_cb)
def _page_removed_cb(self, __notebook, page, n):
- page.page.remove()
+ try:
+ page.page.remove()
+ except:
+ pass
+ # the welcome page do not have a page property
def _switch_page_cb(self, __notebook, page_gptr, page_num):
- self.activity.update_sidebar_to_page(self._get_page(page_num))
- self.activity.explore_code(None, switch_page=False)
+ self.emit('tab-changed', self._get_page(page_num).full_path)
def set_to_page_like(self, full_path):
for n in range(self.get_n_pages()):
@@ -61,15 +69,23 @@ class GtkSourceview2Editor(gtk.Notebook):
def load_object(self, full_path, filename):
if self.set_to_page_like(full_path):
return
- scrollwnd = gtk.ScrolledWindow()
- scrollwnd.set_policy(gtk.POLICY_AUTOMATIC,
- gtk.POLICY_AUTOMATIC)
+ scrollwnd = Gtk.ScrolledWindow()
+ scrollwnd.set_policy(Gtk.PolicyType.AUTOMATIC,
+ Gtk.PolicyType.AUTOMATIC)
page = GtkSourceview2Page(full_path)
+
+ vbox = Gtk.VBox()
+ if full_path.endswith('.svg'):
+ icon = Icon(file=full_path, pixel_size=100,
+ xo_color=profile.get_color())
+ vbox.pack_start(icon, False, False, 0)
+
+ vbox.pack_start(scrollwnd, True, True, 0)
scrollwnd.add(page)
- scrollwnd.page = page
+ vbox.page = page
label = filename
- page.text_buffer.connect('changed', self._changed_cb)
+ page.text_buffer.connect('changed', self.__text_changed_cb)
tablabel = TabLabel(scrollwnd, label)
tablabel.connect(
@@ -77,17 +93,30 @@ class GtkSourceview2Editor(gtk.Notebook):
lambda widget, child: self.remove_page(self.page_num(child)))
tablabel.page = page
- self.append_page(scrollwnd, tablabel)
+ self.append_page(vbox, tablabel)
+
+ self.__text_changed_cb(page.text_buffer)
+ self.show_all()
+ self.set_current_page(-1)
- self._changed_cb(page.text_buffer)
+ def load_log_file(self, full_path, log_files_viewer):
+ logview = logviewer.LogView(full_path, log_files_viewer)
+ scrollwnd = Gtk.ScrolledWindow()
+ scrollwnd.set_policy(Gtk.PolicyType.AUTOMATIC,
+ Gtk.PolicyType.AUTOMATIC)
+ scrollwnd.add(logview)
+ scrollwnd.page = logview
+ tablabel = TabLabel(logview, os.path.basename(full_path))
+ tablabel.connect(
+ 'tab-close', lambda widget, child:
+ self.remove_page(self.page_num(child)))
+ self.append_page(scrollwnd, tablabel)
self.show_all()
self.set_current_page(-1)
- def _changed_cb(self, buffer):
+ def __text_changed_cb(self, buffer):
if not buffer.can_undo():
buffer.set_modified(False)
- elif not self.activity.dirty:
- self.activity.set_dirty(True)
self.emit('changed')
def _get_page(self, order=-1):
@@ -96,7 +125,7 @@ class GtkSourceview2Editor(gtk.Notebook):
else:
n = order
if self.get_nth_page(n) is not None:
- return self.get_nth_page(n).get_children()[0]
+ return self.get_nth_page(n).page
else:
return None
@@ -120,13 +149,13 @@ class GtkSourceview2Editor(gtk.Notebook):
def copy(self):
page = self._get_page()
if page:
- clip = gtk.Clipboard()
+ clip = Gtk.Clipboard()
page.get_buffer().copy_clipboard(clip)
def paste(self):
page = self._get_page()
if page:
- clip = gtk.Clipboard()
+ clip = Gtk.Clipboard()
text = clip.wait_for_text()
page.get_buffer().insert_at_cursor(text)
@@ -201,7 +230,8 @@ class GtkSourceview2Editor(gtk.Notebook):
def get_text(self):
buff = self._get_page().text_buffer
- return buff.get_text(buff.get_start_iter(), buff.get_end_iter())
+ return buff.get_text(buff.get_start_iter(), buff.get_end_iter(),
+ False)
def get_file_path(self):
return self._get_page().full_path
@@ -213,16 +243,16 @@ class GtkSourceview2Editor(gtk.Notebook):
page = self._get_page()
_buffer = page.get_buffer()
_iter = _buffer.get_iter_at_line(line - 1)
- page.scroll_to_iter(_iter, 0.0)
+ page.scroll_to_iter(_iter, 0.1, False, 0, 0)
-class GtkSourceview2Page(gtksourceview2.View):
+class GtkSourceview2Page(GtkSource.View):
def __init__(self, full_path):
'''
Do any initialization here.
'''
- gtksourceview2.View.__init__(self)
+ GtkSource.View.__init__(self)
self.full_path = full_path
@@ -232,22 +262,23 @@ class GtkSourceview2Page(gtksourceview2.View):
self.set_show_line_numbers(True)
self.set_insert_spaces_instead_of_tabs(True)
+ self.text_buffer = GtkSource.Buffer()
+
# Tags for search
- tagtable = gtk.TextTagTable()
- hilite_tag = gtk.TextTag('search-hilite')
+ tagtable = self.text_buffer.get_tag_table()
+ hilite_tag = Gtk.TextTag.new('search-hilite')
hilite_tag.props.background = '#FFFFB0'
tagtable.add(hilite_tag)
- select_tag = gtk.TextTag('search-select')
+ select_tag = Gtk.TextTag.new('search-select')
select_tag.props.background = '#B0B0FF'
tagtable.add(select_tag)
- self.text_buffer = gtksourceview2.Buffer(tag_table=tagtable)
self.set_buffer(self.text_buffer)
self.set_tab_width(4)
self.set_auto_indent(True)
- self.modify_font(pango.FontDescription('Monospace 10'))
+ self.modify_font(Pango.FontDescription('Monospace 10'))
self.load_text()
self.show()
@@ -266,7 +297,7 @@ class GtkSourceview2Page(gtksourceview2.View):
self.text_buffer.set_highlight_syntax(False)
mime_type = mimetypes.guess_type(self.full_path)[0]
if mime_type:
- lang_manager = gtksourceview2.language_manager_get_default()
+ lang_manager = GtkSource.LanguageManager.get_default()
lang_ids = lang_manager.get_language_ids()
langs = [lang_manager.get_language(i) for i in lang_ids]
for lang in langs:
@@ -284,7 +315,8 @@ class GtkSourceview2Page(gtksourceview2.View):
def save(self):
if self.text_buffer.can_undo(): # only save if there's something to
buff = self.text_buffer
- text = buff.get_text(buff.get_start_iter(), buff.get_end_iter())
+ text = buff.get_text(buff.get_start_iter(), buff.get_end_iter(),
+ False)
_file = file(self.full_path, 'w')
try:
_file.write(text)
@@ -384,7 +416,8 @@ class GtkSourceview2Page(gtksourceview2.View):
text_iter = _buffer.get_start_iter()
while True:
- next_found = text_iter.forward_search(text, 0)
+ next_found = text_iter.forward_search(
+ text, Gtk.TextSearchFlags.CASE_INSENSITIVE, None)
if next_found is None:
break
start, end = next_found
@@ -408,9 +441,11 @@ class GtkSourceview2Page(gtksourceview2.View):
text_iter = _buffer.get_iter_at_mark(_buffer.get_insert())
if direction == 'backward':
- return text_iter.backward_search(self.search_text, 0)
+ return text_iter.backward_search(
+ self.search_text, Gtk.TextSearchFlags.CASE_INSENSITIVE, None)
else:
- return text_iter.forward_search(self.search_text, 0)
+ return text_iter.forward_search(
+ self.search_text, Gtk.TextSearchFlags.CASE_INSENSITIVE, None)
def search_next(self, direction):
next_found = self.get_next_result(direction)
@@ -423,5 +458,4 @@ class GtkSourceview2Page(gtksourceview2.View):
_buffer.apply_tag_by_name('search-select', start, end)
_buffer.place_cursor(start)
- self.scroll_to_iter(start, 0.1)
- self.scroll_to_iter(end, 0.1)
+ self.scroll_to_iter(start, 0.1, False, 0, 0)
diff --git a/develop-activity/symbols_tree.py b/develop-activity/symbols_tree.py
index 939debf..eb234d3 100644
--- a/develop-activity/symbols_tree.py
+++ b/develop-activity/symbols_tree.py
@@ -14,30 +14,32 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-import gtk
-import gobject
+from gi.repository import Gtk
+from gi.repository import GdkPixbuf
+from gi.repository import GObject
-class SymbolsTree(gtk.TreeView):
+class SymbolsTree(Gtk.TreeView):
- __gsignals__ = {'symbol-selected': (gobject.SIGNAL_RUN_FIRST, None, [int])}
+ __gsignals__ = {'symbol-selected': (GObject.SignalFlags.RUN_FIRST, None,
+ [int])}
def __init__(self):
- gtk.TreeView.__init__(self)
+ GObject.GObject.__init__(self)
- self._model = gtk.TreeStore(gtk.gdk.Pixbuf, str, str)
+ self._model = Gtk.TreeStore(GdkPixbuf.Pixbuf, str, int)
self.set_model(self._model)
- column = gtk.TreeViewColumn('Symbols')
- icon_cell = gtk.CellRendererPixbuf()
+ column = Gtk.TreeViewColumn('Symbols')
+ icon_cell = Gtk.CellRendererPixbuf()
column.pack_start(icon_cell, False)
column.add_attribute(icon_cell, 'pixbuf', 0)
- name_cell = gtk.CellRendererText()
+ name_cell = Gtk.CellRendererText()
column.pack_start(name_cell, True)
column.add_attribute(name_cell, 'text', 1)
- line_cell = gtk.CellRendererText()
+ line_cell = Gtk.CellRendererText()
line_cell.props.visible = False
column.pack_start(line_cell, False)
column.add_attribute(line_cell, 'text', 2)
@@ -46,28 +48,29 @@ class SymbolsTree(gtk.TreeView):
self.connect('cursor-changed', self._symbol_selected_cb)
def _add_class(self, name, line):
- pixbuf = gtk.gdk.pixbuf_new_from_file_at_size('icons/class.png', 24,
- 24)
+ pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size('icons/class.png', 24,
+ 24)
parent = self._model.append(None, (pixbuf, name, line))
return parent
def _add_method(self, name, line, parent=None):
- pixbuf = gtk.gdk.pixbuf_new_from_file_at_size('icons/function.png',
- 24, 24)
+ pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size('icons/function.png',
+ 24, 24)
self._model.append(parent, (pixbuf, name, line))
def _add_attribute(self, name, line, parent=None):
- pixbuf = gtk.gdk.pixbuf_new_from_file_at_size('icons/attribute.png',
- 24, 24)
+ pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size('icons/attribute.png',
+ 24, 24)
self._model.append(parent, (pixbuf, name, line))
def _symbol_selected_cb(self, widget):
selection = self.get_selection()
- model, _iter = selection.get_selected()
- line = int(model.get_value(_iter, 2))
- if line is 0:
- return
- self.emit('symbol-selected', line)
+ model, iter = selection.get_selected()
+ if iter is not None:
+ line = model.get_value(iter, 2)
+ if line is 0:
+ return
+ self.emit('symbol-selected', line)
def load_symbols(self, data):
self._model.clear()
diff --git a/develop-activity/widgets.py b/develop-activity/widgets.py
index 4e7da2e..27382c4 100644
--- a/develop-activity/widgets.py
+++ b/develop-activity/widgets.py
@@ -17,37 +17,37 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-import gtk
-import gobject
+from gi.repository import Gtk
+from gi.repository import GObject
-from sugar.graphics.icon import Icon
+from sugar3.graphics.icon import Icon
-class TabLabel(gtk.HBox):
+class TabLabel(Gtk.HBox):
__gtype_name__ = 'BrowseTabLabel'
__gsignals__ = {
- 'tab-close': (gobject.SIGNAL_RUN_FIRST,
+ 'tab-close': (GObject.SignalFlags.RUN_FIRST,
None,
([object])),
}
def __init__(self, child, label=""):
- gtk.HBox.__init__(self)
+ GObject.GObject.__init__(self)
self._child = child
- self._label = gtk.Label(label)
+ self._label = Gtk.Label(label=label)
self._label.set_alignment(0, 0.5)
self.pack_start(self._label, True, True, 0)
self._label.show()
- self.modify_base(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0, 0, 1))
+ #self.modify_base(Gtk.StateType.NORMAL, Gdk.Color(0, 0, 0, 1))
close_tab_icon = Icon(icon_name='close-tab')
- button = gtk.Button()
- button.props.relief = gtk.RELIEF_NONE
+ button = Gtk.Button()
+ button.props.relief = Gtk.ReliefStyle.NONE
button.props.focus_on_click = False
- icon_box = gtk.HBox()
+ icon_box = Gtk.HBox()
icon_box.pack_start(close_tab_icon, True, False, 0)
button.add(icon_box)
button.connect('clicked', self.__button_clicked_cb)