diff --git a/extensions/deviceicon/display.py b/extensions/deviceicon/display.py
index e9a851a137..ca11c850ee 100644
--- a/extensions/deviceicon/display.py
+++ b/extensions/deviceicon/display.py
@@ -32,7 +32,7 @@
from jarabe.frame.frameinvoker import FrameWidgetInvoker
from jarabe.model import brightness
-from jarabe.model.screenshot import take_screenshot
+from jarabe.view.screenshotpopup import ScreenshotPanel
from jarabe import frame
@@ -90,7 +90,7 @@ def __init__(self, text, icon_name):
icon = Icon(pixel_size=style.SMALL_ICON_SIZE)
icon.props.icon_name = icon_name
icon.props.xo_color = XoColor('%s,%s' % (style.COLOR_WHITE.get_svg(),
- style.COLOR_BUTTON_GREY.get_svg()))
+ style.COLOR_BUTTON_GREY.get_svg()))
icon.show()
label = Gtk.Label(text)
@@ -228,7 +228,7 @@ def __screenshot_cb(self, palette):
def __take_screenshot_cb(self, frame_):
if frame_.is_visible():
return True
- take_screenshot()
+ panel = ScreenshotPanel()
frame_.show()
return False
diff --git a/extensions/globalkey/screenshot.py b/extensions/globalkey/screenshot.py
index ee84dfad0b..20dbe2d8f3 100644
--- a/extensions/globalkey/screenshot.py
+++ b/extensions/globalkey/screenshot.py
@@ -14,10 +14,10 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-from jarabe.model.screenshot import take_screenshot
+from jarabe.view.screenshotpopup import ScreenshotPanel
BOUND_KEYS = ['1', 'Print']
def handle_key_press(key):
- take_screenshot()
+ panel = ScreenshotPanel()
diff --git a/src/jarabe/desktop/activitychooser.py b/src/jarabe/desktop/activitychooser.py
index cfb30da0f1..b6c42f8b7b 100644
--- a/src/jarabe/desktop/activitychooser.py
+++ b/src/jarabe/desktop/activitychooser.py
@@ -33,6 +33,14 @@
class TitleBox(Gtk.Toolbar):
+ '''
+ Title box at the top of the pop-up window.
+ Title and close button are added to the box and as needed
+ more widgets can be added using self.add_widget method.
+ This box is optional as the inherited class can remove this
+ block by setting the self._set_title_box to False.
+ '''
+
def __init__(self):
Gtk.Toolbar.__init__(self)
@@ -52,9 +60,16 @@ def __init__(self):
tool_item.show()
def set_title(self, title):
+ '''
+ setter function for 'title' property.
+ Args:
+ title (str): title for pop-up window
+ '''
self._label.set_markup('%s' % title)
self._label.show()
+ title = GObject.Property(type=str, setter=set_title)
+
_AUTOSEARCH_TIMEOUT = 1000
@@ -149,6 +164,17 @@ def __init__(self):
self.show()
+ def get_title_box(self):
+ '''
+ Getter method for title-box
+
+ Returns:
+ self._title_box (): Title or Tool Box
+ '''
+ return self._title_box
+
+ title_box = GObject.Property(type=str, getter=get_title_box)
+
def __close_button_clicked_cb(self, button):
self.destroy()
diff --git a/src/jarabe/view/Makefile.am b/src/jarabe/view/Makefile.am
index da7fe1d8a0..c055d002eb 100644
--- a/src/jarabe/view/Makefile.am
+++ b/src/jarabe/view/Makefile.am
@@ -11,6 +11,7 @@ sugar_PYTHON = \
launcher.py \
palettes.py \
pulsingicon.py \
+ screenshotpopup.py \
service.py \
tabbinghandler.py \
viewsource.py \
diff --git a/src/jarabe/view/screenshotpopup.py b/src/jarabe/view/screenshotpopup.py
new file mode 100644
index 0000000000..82d0ff414d
--- /dev/null
+++ b/src/jarabe/view/screenshotpopup.py
@@ -0,0 +1,331 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2016 Utkarsh Tiwari
+# Copyright (C) 2019 Ibiam Chihurumnaya
+#
+# 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 3 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, see .
+#
+# Contact information:
+# Utkarsh Tiwari iamutkarshtiwari@gmail.com
+
+import os
+import dbus
+import cairo
+import logging
+import StringIO
+import tempfile
+from gettext import gettext as _
+
+from gi.repository import GObject
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import Gio
+
+from sugar3 import env
+
+from sugar3.datastore import datastore
+from sugar3.graphics.icon import Icon
+from sugar3.graphics import style
+from sugar3.graphics.alert import Alert, TimeoutAlert
+from sugar3.graphics import iconentry
+from sugar3.graphics.toolbutton import ToolButton
+
+
+from jarabe.model.session import get_session_manager
+from jarabe import config
+from jarabe.model import shell
+from jarabe.desktop.activitychooser import ActivityChooser
+
+
+_logger = logging.getLogger('ScreenshotPanel')
+
+THUMBNAIL_SIZE = style.zoom(
+ Gdk.Screen.height() / 3), style.zoom(Gdk.Screen.height() / 4.5)
+
+
+class ScreenshotPanel(ActivityChooser):
+ '''
+ Generates a pop papel to allow user to save the
+ screenshot by the name of his choice
+ '''
+
+ __gtype_name__ = 'ScreenshotPanel'
+
+ def __init__(self):
+ ActivityChooser.__init__(self)
+
+ self._set_screensize()
+ # self.props.size = ((height / 6),
+ # (width / 5))
+ self.get_title_box().props.title = _('Save Screenshot')
+ self._title_box.close_button.connect('clicked', self._close_cb)
+ self.set_keep_above(True)
+
+ self.modify_bg(Gtk.StateType.NORMAL,
+ style.COLOR_BLACK.get_gdk_color())
+ self.set_border_width(style.LINE_WIDTH)
+ self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
+ self.set_decorated(False)
+ self.set_resizable(False)
+
+ self.connect('key-press-event', self.__key_press_event_cb)
+
+ self._toolbar = None
+ self._canvas = None
+ self._table = None
+ self._scrolledwindow = None
+ self._separator = None
+ self._section_view = None
+ self._section_toolbar = None
+ self._main_toolbar = None
+
+ self._hbox = Gtk.HBox()
+ self._vbox.pack_start(self._hbox, True, True, 0)
+ self._hbox.show()
+
+ self._main_view = Gtk.EventBox()
+ self._hbox.pack_start(self._main_view, True, True, 0)
+ self._main_view.modify_bg(Gtk.StateType.NORMAL,
+ style.COLOR_BLACK.get_gdk_color())
+ self._main_view.show()
+
+ # Generates the thumbnail
+ self.screenshot_surface, self.file_path = take_screenshot()
+ preview_image, activity_title = generate_thumbnail(
+ self.screenshot_surface)
+ self._main_view.add(preview_image)
+ preview_image.show()
+
+ self._vbox = Gtk.VBox()
+ self._hbox.pack_start(self._vbox, True, True, 0)
+ self._vbox.show()
+
+ self._hbox = Gtk.HBox()
+ self._hbox.show()
+
+ # Name entry box
+ self._name_view = Gtk.EventBox.new()
+ self._name_view.modify_bg(Gtk.StateType.NORMAL,
+ style.COLOR_BLACK.get_gdk_color())
+ self._name_view.show()
+
+ # Entry box
+ self._search_entry = Gtk.Entry()
+ halign = Gtk.Alignment.new(0, 1, 0, 0)
+ halign.add(self._name_view)
+ halign.show()
+
+ self._hbox.pack_start(halign, True, True, 0)
+ self._name_view.add(self._search_entry)
+ self._search_entry.show()
+ self._search_entry.set_text(_(activity_title))
+
+ self._vbox.pack_start(self._hbox, True, True, 0)
+
+ self._buttons_box = Gtk.HButtonBox()
+ self._buttons_box.set_layout(Gtk.ButtonBoxStyle.CENTER)
+ self._buttons_box.set_spacing(style.DEFAULT_SPACING)
+
+ _ok = Gtk.Button()
+ _ok.set_image(Icon(icon_name='dialog-ok'))
+ _ok.set_label(_('Yes'))
+ _ok.connect('clicked', self.__ok_clicked_cb)
+ self._buttons_box.pack_start(_ok, True, True, 0)
+ _ok.show()
+
+ _cancel = Gtk.Button()
+ _cancel.set_image(Icon(icon_name='dialog-cancel'))
+ _cancel.set_label(_('No'))
+ _cancel.connect('clicked', self.__cancel_clicked_cb)
+ self._buttons_box.pack_start(_cancel, True, True, 0)
+ _cancel.show()
+
+ self._vbox.pack_start(self._buttons_box, True, True, 0)
+ self._buttons_box.show()
+ self._search_entry.grab_focus()
+ self.show()
+
+ def _close_cb(self):
+ self.destroy()
+
+ def __cancel_clicked_cb(self, widget):
+ self.destroy()
+
+ def __ok_clicked_cb(self, widget):
+ self.save_screenshot(self._search_entry.get_text())
+ self.destroy()
+
+ def _set_cursor(self, cursor):
+ self.get_window().set_cursor(cursor)
+ Gdk.flush()
+
+ def _set_screensize(self):
+ '''
+ Sets the size of the popup based on
+ the screen resolution.
+ '''
+ width = Gdk.Screen.width() / 4
+ height = Gdk.Screen.height() / 5
+ self.set_size_request(width, height)
+
+ def __key_press_event_cb(self, window, event):
+ # if the user clicked out of the window - fix SL #3188
+ keyname = Gdk.keyval_name(event.keyval)
+ if keyname == 'Escape':
+ self.destroy()
+
+ if keyname == 'Return':
+ self.save_screenshot(self._search_entry.get_text())
+ self.destroy()
+
+ if not self.is_active():
+ self.present()
+ return False
+
+ def save_screenshot(self, title):
+ settings = Gio.Settings('org.sugarlabs.user')
+ color = settings.get_string('color')
+
+ jobject = datastore.create()
+ try:
+ jobject.metadata['title'] = title
+ jobject.metadata['keep'] = '0'
+ jobject.metadata['buddies'] = ''
+ jobject.metadata['preview'] = _get_preview_data(
+ self.screenshot_surface)
+ jobject.metadata['icon-color'] = color
+ jobject.metadata['mime_type'] = 'image/png'
+ jobject.file_path = self.file_path
+ datastore.write(jobject, transfer_ownership=True)
+ finally:
+ jobject.destroy()
+ del jobject
+
+
+def generate_thumbnail(screenshot_surface):
+ '''
+ Generates the thumbnail to be displayed
+ on the screenshot alert popup
+ '''
+
+ window = Gdk.get_default_root_window()
+ width, height = window.get_width(), window.get_height()
+ thumb_width, thumb_height = THUMBNAIL_SIZE
+
+ cairo_context = cairo.Context(screenshot_surface)
+ thumb_scale_w = thumb_width * 1.0 / width
+ thumb_scale_h = thumb_height * 1.0 / height
+ cairo_context.scale(thumb_scale_w, thumb_scale_h)
+ Gdk.cairo_set_source_window(cairo_context, window, 0, 0)
+ cairo_context.paint()
+
+ link_width, link_height = THUMBNAIL_SIZE
+ link_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
+ link_width, link_height)
+
+ cairo_context = cairo.Context(link_surface)
+ dest_x = style.zoom(0)
+ dest_y = style.zoom(0)
+ cairo_context.set_source_surface(screenshot_surface, dest_x, dest_y)
+ thumb_width, thumb_height = THUMBNAIL_SIZE
+ cairo_context.rectangle(dest_x, dest_y, thumb_width, thumb_height)
+ cairo_context.fill()
+
+ bg_width, bg_height = THUMBNAIL_SIZE
+ pixbuf_bg = Gdk.pixbuf_get_from_surface(link_surface, 0, 0,
+ bg_width, bg_height)
+
+ preview_image = Gtk.Image()
+ preview_image.set_from_pixbuf(pixbuf_bg)
+
+ # Set's the default title
+ content_title = None
+ shell_model = shell.get_model()
+ zoom_level = shell_model.zoom_level
+
+ # TRANS: Nouns of what a screenshot contains
+ if zoom_level == shell_model.ZOOM_MESH:
+ content_title = _('Mesh')
+ elif zoom_level == shell_model.ZOOM_GROUP:
+ content_title = _('Group')
+ elif zoom_level == shell_model.ZOOM_HOME:
+ content_title = _('Home')
+ elif zoom_level == shell_model.ZOOM_ACTIVITY:
+ activity = shell_model.get_active_activity()
+ if activity is not None:
+ content_title = activity.get_title()
+ if content_title is None:
+ content_title = _('Activity')
+
+ if content_title is None:
+ title = _('Screenshot')
+ else:
+ title = _('Screenshot of \"%s\"') % content_title
+
+ return preview_image, title
+
+
+def take_screenshot():
+ '''
+ Captures a screenshot and saves
+ it to a temp dir.
+ '''
+ tmp_dir = os.path.join(env.get_profile_path(), 'data')
+ fd, file_path = tempfile.mkstemp(dir=tmp_dir)
+ os.close(fd)
+
+ window = Gdk.get_default_root_window()
+ width, height = window.get_width(), window.get_height()
+
+ screenshot_surface = Gdk.Window.create_similar_surface(
+ window, cairo.CONTENT_COLOR, width, height)
+
+ cr = cairo.Context(screenshot_surface)
+ Gdk.cairo_set_source_window(cr, window, 0, 0)
+ cr.paint()
+ screenshot_surface.write_to_png(file_path)
+
+ return screenshot_surface, file_path
+
+
+def _get_preview_data(screenshot_surface):
+ screenshot_width = screenshot_surface.get_width()
+ screenshot_height = screenshot_surface.get_height()
+
+ preview_width, preview_height = THUMBNAIL_SIZE
+ preview_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
+ preview_width, preview_height)
+ cr = cairo.Context(preview_surface)
+
+ scale_w = preview_width * 1.0 / screenshot_width
+ scale_h = preview_height * 1.0 / screenshot_height
+ scale = min(scale_w, scale_h)
+
+ translate_x = int((preview_width - (screenshot_width * scale)) / 2)
+ translate_y = int((preview_height - (screenshot_height * scale)) / 2)
+
+ cr.translate(translate_x, translate_y)
+ cr.scale(scale, scale)
+
+ cr.set_source_rgba(1, 1, 1, 0)
+ cr.set_operator(cairo.OPERATOR_SOURCE)
+ cr.paint()
+ cr.set_source_surface(screenshot_surface)
+ cr.paint()
+
+ preview_str = StringIO.StringIO()
+ preview_surface.write_to_png(preview_str)
+
+ return dbus.ByteArray(preview_str.getvalue())