diff --git a/checkdependencies.py b/checkdependencies.py index a3867ec..a1d9f89 100755 --- a/checkdependencies.py +++ b/checkdependencies.py @@ -104,5 +104,9 @@ def checkApplication(name, friendlyName, tutorial): checkApplication("convert", "ImageMagick", "http://www.imagemagick.org/script/binary-releases.php") + checkApplication("xclip", "xclip", "https://github.com/milki/xclip/blob/master/INSTALL") + + + except (KeyboardInterrupt, EOFError): print diff --git a/cli/area.py b/cli/selection.py similarity index 100% rename from cli/area.py rename to cli/selection.py diff --git a/gui/perdyshot.py b/gui/perdyshot.py index f53d2b7..1aaddf3 100755 --- a/gui/perdyshot.py +++ b/gui/perdyshot.py @@ -1,6 +1,10 @@ #!/usr/bin/env python2 -import os, sys, subprocess, signal +from configobj import ConfigObj +from validate import Validator + +import os, sys, subprocess, signal, tempfile, shutil, pipes + from PyQt4 import QtGui, QtCore from gi.repository import Notify @@ -14,6 +18,18 @@ Notify.init("Perdyshot") + +config = ConfigObj(os.path.join(dirname, os.path.pardir, 'perdyshot.conf'), encoding = 'UTF8', configspec = os.path.join(dirname, os.path.pardir, 'perdyshot.conf.spec')) +validator = Validator() +if not config.validate(validator): + wireutils.cprint("Invalid configuration file", color = wireutils.bcolors.DARKRED) + sys.exit(1) + +settings = {} + +settings['modes'] = config['GUI']['CaptureModes'] + + app = QtGui.QApplication(sys.argv) # Create about dialog @@ -50,9 +66,14 @@ def __init__(self, icon, parent = None): QtGui.QSystemTrayIcon.__init__(self, icon, parent) menu = QtGui.QMenu(parent) + self.menu = menu - menu.addAction("Capture Active Window", self.onCaptureActiveWindow) - menu.addAction("Capture Selection", self.onCaptureSelection) + # Add the options + for key in settings['modes']: + action = menu.addAction(key) + action.triggered.connect( + lambda x, key = key: self.onCapture(key) + ) menu.addSeparator() @@ -67,13 +88,46 @@ def onQuit(self): def onAbout(self): aboutDialog.show() - def onCaptureActiveWindow(self): - subprocess.call(["/usr/bin/env", "python2", os.path.join(dirname, os.path.pardir, "cli", "window.py"), "--delay", "0"]) - notification = Notify.Notification.new("Screenshot saved", "", ICON) - notification.show() + def onCapture(self, item): + options = settings['modes'][item] + + if options['type'] == 'script': + subprocess.call([ options['file'] ]) + + elif options['type'] == 'simple': + filename = os.path.join(tempfile.gettempdir(), 'perdygui.png') + + args = [ + '/usr/bin/env', 'python2', os.path.join(dirname, os.path.pardir, 'cli', options['mode'] + '.py'), + + '-f', filename + ] + + if options['mode'] == 'window': + args.extend(['--delay', '0']) + + # Capture the screenshot + subprocess.call(args) + + # Okay the screenshot has been captures. What do we do now? + if options['file'] != None: + newFilename = time.strftime(options['file']) + shutil.copyfile(filename, newFilename) + filename = newFilename + + if options['program'] != None: + subprocess.call(options['program'] % filename, shell = True) + + if options['copy']: + subprocess.call('xclip -i -sel clip < ' + pipes.quote(filename), shell = True) - def onCaptureSelection(self): - subprocess.call(["/usr/bin/env", "python2", os.path.join(dirname, os.path.pardir, "cli", "area.py")]) + if options['notification']: + notification = Notify.Notification.new( + options['notificationTitle'], + options['notificationDescription'], + options['notificationImage'] if options['notificationImage'] != None else ICON + ) + notification.show() aboutDialog = AboutDialog() diff --git a/perdyshot.conf b/perdyshot.conf index 459e3c6..cf0deb2 100644 --- a/perdyshot.conf +++ b/perdyshot.conf @@ -39,6 +39,71 @@ borderImageDM = "assets/elementary_border_dm.png" +# GUI Settings +[GUI] + [[CaptureModes]] + # The name of the capture mode as shown in the GUI menu + [[["Capture Active Window"]]] + # The type of capture + # Values: + # simple: Simple options. Should get the most common operations done + # script: Executes a script. Full control + type = "simple" + + # All the below settings is for type = "simple" only. + # For type = "script", simply use file = "/path/to/script.sh". That's all you need + + # The capture mode + # Values: + # window: Captures the active window + # selection: Custom rectangle selection + mode = "window" + + # The file to save the resulting picture to + # I.e. "~/Pictures/screenshot.png" + # For formatting options, please refer to https://docs.python.org/2/library/time.html#time.strftime + # By default (None) doesn't save the image + #file = None + + # A shell command to execute after capturing + # I.e. "gimp '%s'" + # %s is replaced by `file` if one is set (otherwise uses the tempfile) + # If left out, no command is executed + # Defaults to None + #program = "" + + # Whether to copy the image (after `program` terminates) to the clipboard + # Type: boolean + # Defaults to False + copy = True + + # Whether to display a notification when everything's done + # Type: boolean + # Defaults to False + notification = True + + # The image used for the notificatin + # Either a path to a custom picture or a system image provided by lib-notify + # Please note that custom pictures are broken on Elementary OS and will always use the info icon + # Defaults to the Perdyshot logo + #notificationImage = None + + # The title of the notification + # Defaults to "Screenshot taken!" + notificationTitle = "Screenshot taken!" + + # The description of the notification + # Defaults to an empty string + notificationDescription = "" + + [[["Capture Selection"]]] + type = "simple" + mode = "selection" + program = "pinta '%s'" + copy = True + notification = True + + # Application-specific settings [Applications] # The WM_CLASS of the application diff --git a/perdyshot.conf.spec b/perdyshot.conf.spec index 827d7de..9ac9125 100644 --- a/perdyshot.conf.spec +++ b/perdyshot.conf.spec @@ -8,6 +8,19 @@ borderImage = string(default = '') borderImageDM = string(default = '') +[GUI] + [[CaptureModes]] + [[[__many__]]] + type = option('simple', 'script') + mode = option('window', 'selection', default = None) + file = string(default = None) + program = string(default = None) + copy = boolean(default = False) + notification = boolean(default = False) + notificationImage = string(default = None) + notificationTitle = string(default = 'Screenshot taken!') + notificationDescription = string(default = '') + [Applications] [[__many__]] sizeBugged = integer(default = 0)