changeset 0:dcd610585610

INIT
author prymula <prymula76@outlook.com>
date Thu, 21 Sep 2023 22:32:14 +0200
parents
children 82b75cc1e524
files bandm3u/bandm3u.py bubblesort/bubblesort-recursive.py bubblesort/bubblesort.py bubblesort/test.py cover2musc/chanelog.txt cover2musc/cover2music cover2musc/cover2music.desktop cover2musc/cover2music.ico cover2musc/cover2music.png cover2musc/cover2music.py cover2musc/makefile cover2musc/setup.py photocrop/DEBIAN/HOWTO photocrop/DEBIAN/debian.changelog photocrop/DEBIAN/debian.control photocrop/DEBIAN/debian.rules photocrop/DEBIAN/format.sh photocrop/DEBIAN/photocrop.dsc photocrop/INSTALL photocrop/LICENSE photocrop/Makefile photocrop/Makefile.in.gz photocrop/RPM/photocrop.spec photocrop/bugs.txt photocrop/changelog photocrop/configure.gz photocrop/data/IMG_6854.JPG photocrop/data/clip.png photocrop/data/photocrop.desktop photocrop/src/photocrop.py photocrop/xcf/clip.xcf postagelabels/DEBIAN/HOWTO.txt postagelabels/DEBIAN/debian.changelog postagelabels/DEBIAN/debian.control postagelabels/DEBIAN/debian.rules postagelabels/DEBIAN/format.sh postagelabels/DEBIAN/photocrop.dsc postagelabels/RPM/postagelabels.spec postagelabels/changelog.txt postagelabels/makefile postagelabels/png/blank_small.png postagelabels/png/postagelabels.png postagelabels/png/szablon.png postagelabels/postagelabels.desktop postagelabels/postagelabels.py postagelabels/xcf/blank_small.xcf postagelabels/xcf/labelpost.xcf verysimpleslideshow/COPYRIGHT verysimpleslideshow/Changelog verysimpleslideshow/CzytajTo verysimpleslideshow/DEBIAN/HOWTO.txt verysimpleslideshow/DEBIAN/debian.changelog verysimpleslideshow/DEBIAN/debian.control verysimpleslideshow/DEBIAN/debian.postinst verysimpleslideshow/DEBIAN/debian.postrm verysimpleslideshow/DEBIAN/debian.rules verysimpleslideshow/DEBIAN/format.sh verysimpleslideshow/DEBIAN/verysimpleslideshow.dsc verysimpleslideshow/Makefile verysimpleslideshow/RPM/verysimpleslideshow.spec verysimpleslideshow/run.txt verysimpleslideshow/verysimpleslideshow.py
diffstat 62 files changed, 4724 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bandm3u/bandm3u.py	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+# bandm3u- skrypt do tworzenia playlist m3u
+# 16-02-2023
+# Edytor: Geany
+# (c) by P.R.P
+# Mój pierwszy skrypt stworzony w Windows 11
+
+import os 
+
+dir = os.getcwd()
+
+data_files = []
+data_out = []
+extension = ['mp3', 'ogg', 'wav']
+
+def check(string, sub_str):
+	if (string.find(sub_str) == -1):
+		return False
+	else:
+		return True
+
+for data in os.listdir(dir):
+	for e in extension:
+		if check(data, e):
+			data_files += [os.path.basename(data)]
+
+#print (data_files)
+for n in range(100):
+	for f in data_files:
+		if n > 9:
+			nn = str(n)+" "
+		else:
+			nn = "0"+str(n)+" "
+		# sprawdza liczbę porządkową
+		if check(f, nn):
+			data_out.insert(n, f)
+
+
+c = '\\' 
+
+# indeksy wysępowania znaku slash/unslash w łańcuchu
+slash = [pos for pos, char in enumerate(dir) if char == c]
+# zdejmuje ostatni indeks
+last_slash  = slash.pop()
+
+
+f=open(dir[last_slash+1:]+".m3u","w+") # file name and mode
+for x in range(0, len(data_out)):
+    f.writelines(data_out[x])
+    f.writelines("\r\n")
+f.close()
+
+print (dir)
+print (data_out)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bubblesort/bubblesort-recursive.py	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,23 @@
+#!/usr/bin/env python3
+
+tab = [3, 10, 1, 4, 5, 9, 8, 20, 11, 15, 12, 17, 18]
+
+def func1(i):
+	if i == 0:
+		return
+	else:
+		func2(len(tab) - i - 1)
+		#print("i: "+str(i))
+		func1(i - 1)
+		
+def func2(j):
+	if j < 0:
+		return
+	else:
+		if (tab[j] > tab[j + 1]):
+			tab[j], tab[j+ 1] = tab[j + 1], tab[j]
+		#print ("j:"+str(j))
+		func2(j - 1)
+		
+func1(len(tab))
+print(tab)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bubblesort/bubblesort.py	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,13 @@
+#!/usr/bin/env python3
+
+tab = [3, 10, 1, 4, 5, 9, 8]
+
+n = len(tab)
+
+for i in range(0, n - 1):
+	for j in range(0, n - i - 1):
+		print ("j: "+str(j))
+		if (tab[j] > tab[j + 1]):
+			tab[j], tab[j+ 1] = tab[j + 1], tab[j]
+			
+print(tab)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bubblesort/test.py	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+
+"""
+for i int range(0,5):
+	print (i)
+"""
+
+def func(i):
+	if i == 0:
+		return
+	print(i)
+	func(i-1)
+	
+func(5)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cover2musc/chanelog.txt	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,31 @@
+210512-4 - kolejna zmina numeru wersji, poprawki w makefile oraz przystosowanie do debianizowania
+0.1-3 - zmiana numeru wersji i przeniesienie wszystkiego do /usr
+20210512-3 - poprawiłem przyciski Ok w oknach dialogowych postępu, w ten sposób że pojawiają się dopiero po zakończonej operacji
+20210512-2 - w pełni sprawne ProgrssBar dla usuwanych i dodawanych okładek, jedynie pozostaje wyregulować częstotlwość odpytywania funkcji callback. szczególne dla usuwania okladek
+20210512-1 - przeniesienie funkcji usuwających okładkę do klasy DialogDeleteProgress, czyczenie kodu
+20210512 - nieźle dzialająca klasa ProgressBar, jeszcze korzysta z funkcji poza klasowych 
+20210511 - przeniosłem część kodu odpowiedzialnego za usuwanie poza klase główną i przeniosłem wywołanie usuwania okładek z Okna Dialogowego
+20210507-2 - nie udane próby dodania progress bar dla usuwanych okładek - okienko z postępem wyświetla się dopiero po usunięciu okładek
+20210507-1 detekcja na postwaie 'magic number' zaimplementowana, jednak może okazać się nie wystarczająca dla plków MP3 (ID3v2.3)
+20210507 - pierwsze nieśmiale próby detekcji pliku muzycznego innego niż rozszeżenie pliku
+20210505-1 - usunięcie zbędnych atrybutów dla tagów okladki dla plików OPUS, zmiany w teksie pomocy 
+20210505 - dodano możliwość usuwania okładek z kontenera OGG z zachowaniem pozostalych tagów
+20210504-1 - dla kontenera OGG jest teraz możliwe kasowanie plików o różnych kodekach
+20210504 - dla kontenera OGG możliwy jest teraz wybór mieszany.
+20210503-3 - dodałem obsługę plików OPUS, wyświetlają się zarówno w eksploatorze jak i odtwarzaczu
+20210503-2 - dodałem dodawanie i usuwanie okladek dla formatu Ogg FLAC (OGA), jednak zmian nie widać w eksploatorze plików, tylko w odtwarzaczu graficznym
+20210503-1 - powiększono okno na szerokość, oraz ustabilizowano przyciski
+20210502-4 - dodano możliwość usuwania okładek z plików OGG, jednak kasowane są również pozostałe tagi
+20210502-3 - poprawki w menu
+20210502-2 - dopisałem możliwość usuwania okładek z plików mp3, dla plików ogg, implementacji brak
+20210502 - zmiana nazwy na cover2music, zwiększenie idioto odporności
+20210430e - na powrót konwertuje, ale jedynie pliki ogg a nie mp3
+20210430d - dodałem obsługę mp3, jednak program przestał konwertować
+20210430c - dodałem automatyczne suwaki 
+20210428 - po zaimportowaniu modułu 'python3-mutagen' możliwe jest już dodawanie obrazków do plików ogg
+20210427h - dodałem ramki w oknach oraz kontrolkach, dodałem link do strony domowej w About
+20210427g - poprawiłem błąd przy kolejnym wyborze obrazka (linie 447-451)
+20210427f - wyświetlanie wybranych utworów w widżecie
+20210427e - przepisanie image_new oraz image z zmiennej globalnej do klasy
+20210427d - implementacja wyświetlanego zmiany obrazka
+20210426 - rozpoczęcie projektu
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cover2musc/cover2music	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+python3 /opt/pietraszczyk/cover2music/main.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cover2musc/cover2music.desktop	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,15 @@
+#!/usr/bin/env xdg-open
+
+[Desktop Entry]
+Encoding=UTF-8
+Type=Application
+Categories=AudioVideo;Audio;
+
+Name=Cover2Music
+
+Exec=python3 /usr/bin/cover2music.py
+#Exec=gnome-terminal -e "bash -c 'python3 /usr/bin/cover2music.py;$SHELL'"
+Terminal=false
+Icon=/usr/share/pixmaps/cover2music.png
+
+Name[pl_PL]=Cover2Music
Binary file cover2musc/cover2music.ico has changed
Binary file cover2musc/cover2music.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cover2musc/cover2music.py	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,835 @@
+#!/usr/bin/env python3
+#
+# cover2music - appka do przypisywania obrazków płyt plikom ogg, oga, opus oraz mp3
+# program: Przemysław R. Pietraszczyk
+# rozpoczęto: 26-04-2021
+# licencja: GPL
+# napisano w edytorze: Atom
+
+import gi, os
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gtk, GdkPixbuf, GLib
+
+import base64
+from mutagen.mp3 import MP3
+from mutagen.id3 import ID3, APIC, error
+from mutagen.oggvorbis import OggVorbis
+from mutagen.oggflac import OggFLAC
+from mutagen.oggopus import OggOpus
+from mutagen.flac import Picture
+import mutagen
+
+file_snd_selected=[]
+file_img_selected=""
+
+#snd_selected=[]
+#COVER ="cover2music.png"
+COVER ="/usr/share/pixmaps/cover2music.png"
+snd_extension="ogg"
+img_extension="png" # dla przykladu
+
+
+UI_INFO = """
+<ui>
+  <menubar name='MenuBar'>
+    <menu action='FileMenu'>
+      <menu action='FileLoad'>
+        <menuitem action='LoadImg' />
+        <menuitem action='LoadOgg' />
+      </menu>
+      <menu action='FileDelete'>
+        <menuitem action='RemoveCover' />
+      </menu>
+      <separator />
+      <menuitem action='FileQuit' />
+    </menu>
+
+    <menu action='ChoicesMenu'>
+      <menuitem action='ChoiceTree'/>
+    </menu>
+
+    <menu action='InfoMenu'>
+      <menuitem action='Help'/>
+      <menuitem action='About'/>
+    </menu>
+  </menubar>
+
+</ui>
+"""
+
+
+class FileChooserIMG(Gtk.Window):
+    def __init__(self):
+        Gtk.Window.__init__(self, title="Wybór plików graficznych")
+        global file_img_selected
+
+        dialog = Gtk.FileChooserDialog(title="Please choose a file", parent=self, action=Gtk.FileChooserAction.OPEN)
+        dialog.add_buttons(
+            Gtk.STOCK_CANCEL,
+            Gtk.ResponseType.CANCEL,
+            Gtk.STOCK_OPEN,
+            Gtk.ResponseType.OK,
+        )
+
+        self.add_filters(dialog)
+
+        response = dialog.run()
+        if response == Gtk.ResponseType.OK:
+            print("Open clicked")
+            print("File selected: " + dialog.get_filename())
+            file_img_selected=dialog.get_filename()
+        elif response == Gtk.ResponseType.CANCEL:
+            print("Cancel clicked")
+
+        dialog.destroy()
+
+    def add_filters(self, dialog):
+        filter_jpeg = Gtk.FileFilter()
+        filter_jpeg.set_name("Pliki JPEG")
+        filter_jpeg.add_mime_type("image/jpeg")
+        dialog.add_filter(filter_jpeg)
+
+        filter_png = Gtk.FileFilter()
+        filter_png.set_name("Pliki PNG")
+        filter_png.add_mime_type("image/png")
+        dialog.add_filter(filter_png)
+
+class FileChooserOgg(Gtk.Window):
+    def __init__(self):
+        Gtk.Window.__init__(self, title="Wybór plików dzwiękowych")
+        global file_snd_selected
+        dialog = Gtk.FileChooserDialog(title="Please choose a file", parent=self, action=Gtk.FileChooserAction.OPEN)
+        dialog.add_buttons(
+            Gtk.STOCK_CANCEL,
+            Gtk.ResponseType.CANCEL,
+            Gtk.STOCK_OPEN,
+            Gtk.ResponseType.OK,
+        )
+
+        self.add_filters(dialog)
+        dialog.set_select_multiple(True)
+        response = dialog.run()
+        if response == Gtk.ResponseType.OK:
+            print("Open clicked")
+            file_snd_selected=dialog.get_filenames()
+
+        elif response == Gtk.ResponseType.CANCEL:
+            print("Cancel clicked")
+
+        dialog.destroy()
+
+    def add_filters(self, dialog):
+
+        filter_ogg = Gtk.FileFilter()
+        filter_ogg.set_name("Pliki OGG")
+        filter_ogg.add_mime_type("audio/ogg")
+        dialog.add_filter(filter_ogg)
+
+        filter_mp3 = Gtk.FileFilter()
+        filter_mp3.set_name("Pliki MP3")
+        filter_mp3.add_mime_type("audio/mp3")
+        dialog.add_filter(filter_mp3)
+
+
+class DialogDeleteProgress(Gtk.Dialog):
+    def __init__(self,parent):
+
+        Gtk.Dialog.__init__(self, title="Postęp", transient_for=parent, flags=0)
+        self.current_snd=0
+        self.props.border_width = 20
+        #self.add_buttons(
+        #    Gtk.STOCK_OK, Gtk.ResponseType.OK
+        #)
+        self.progressbar = Gtk.ProgressBar()
+        self.set_default_size(150, 100)
+        box = self.get_content_area()
+
+        label = Gtk.Label(label="Usuwam okladki z plików\n")
+
+        box.add(label)
+        box.add(self.progressbar)
+        self.divider_next=1/len(file_snd_selected)
+        self.timeout_id = GLib.timeout_add(300, self.on_timeout, len(file_snd_selected))
+        self.activity_mode = False
+        self.show_all()
+
+    def on_timeout(self, user_data):
+
+        #jesli przepytano wszyskie pliki wówczas koniec
+        if self.current_snd == user_data:
+            self.add_buttons(
+                Gtk.STOCK_OK, Gtk.ResponseType.OK
+            )
+            self.show_all()
+            return False
+
+        if self.activity_mode:
+            self.progressbar.pulse()
+        else:
+            new_value = self.progressbar.get_fraction() + self.divider_next
+
+            #if new_value > 1:
+            #    new_value = 0
+
+            self.progressbar.set_fraction(new_value)
+            snd=file_snd_selected[self.current_snd]
+            self.current_snd = self.current_snd +1
+            print ("file selected: ",snd)
+            extension = os.path.splitext(snd)
+            snd_extension=extension[1].replace(".", "")
+            print ("Rozszerzenie pliku dzwiekowego: ", snd_extension)
+
+            type=self.check_file_type(snd)
+            if type == "mp3":
+                self.remove_cover_mp3_generic(snd)
+            elif type == "ogg":
+                self.remove_cover_ogg_generic(snd)
+            elif type == "oga":
+                self.remove_cover_oga_generic(snd)
+            elif type == "opus":
+                self.remove_cover_opus_generic(snd)
+
+        # As this is a timeout function, return True so that it
+        # continues to get called
+        return True
+
+
+    def check_file_type(self,snd):
+
+        magic_numbers = {'ID3v2': bytes([0x49, 0x44, 0x33]),
+                        'ID3v1': bytes([0xFF, 0xF2]),
+                        'ID3': bytes([0xFF, 0xF3]),
+                        'withoutID': bytes([0xFF, 0xFB]),
+                        'ogg': bytes([0x4F, 0x67, 0x67, 0x53])}
+        max_read_size = max(len(m) for m in magic_numbers.values())
+
+        with open(snd, 'rb') as fd:
+            file_head = fd.read()
+            #print(file_head)
+
+        if file_head.startswith(magic_numbers['ID3v2']):
+            print ("Plik MP3- z ID3v2")
+            return "mp3"
+        elif file_head.startswith(magic_numbers['ID3v1']):
+            print ("Plik MP3- z ID3v1")
+            return "mp3"
+        elif file_head.startswith(magic_numbers['ID3']):
+            print ("Plik MP3- z ID3")
+            return "mp3"
+        elif file_head.startswith(magic_numbers['withoutID']):
+            print ("Plik MP3 bez ID3")
+            return "mp3"
+        elif file_head.startswith(magic_numbers['ogg']):
+            print("Kontener OGG")
+            ogg_head=mutagen.File(snd).pprint()[0:20]
+
+            if 'opus' in ogg_head.lower():
+                return "opus"
+            elif 'flac' in ogg_head.lower():
+                return "oga"
+            elif 'vorbis'in ogg_head.lower():
+                return "ogg"
+
+
+
+
+    def remove_cover_mp3_generic(self,snd):
+
+        file = ID3(snd) # Load the file
+        file.delall("APIC") # Delete every APIC tag (Cover art)
+        file.save() # Save the file
+
+    def remove_cover_ogg_generic(self,snd):
+
+        file = OggVorbis(snd)
+        try:
+            artist=file["artist"]
+        except KeyError:
+            artist=""
+        try:
+            title=file["title"]
+        except KeyError:
+            title=""
+        try:
+            year=file["year_of_relase"]
+        except KeyError:
+            year=""
+        try:
+            album=file["album"]
+        except KeyError:
+            album=""
+        try:
+            genre=file["genre"]
+        except KeyError:
+            genre=""
+
+        file.delete()
+        file["year_of_relase"]=year
+        file["artist"]=artist
+        file["title"]=title
+        file["album"]=album
+        file["genre"]=genre
+        file.save()
+
+    def remove_cover_oga_generic(self,snd):
+
+        file = OggFLAC(snd)
+        try:
+            artist=file["artist"]
+        except KeyError:
+            artist=""
+        try:
+            title=file["title"]
+        except KeyError:
+            title=""
+        try:
+            year=file["year_of_relase"]
+        except KeyError:
+            year=""
+        try:
+            album=file["album"]
+        except KeyError:
+            album=""
+        try:
+            genre=file["genre"]
+        except KeyError:
+            genre=""
+
+        file.delete()
+        file["year_of_relase"]=year
+        file["artist"]=artist
+        file["title"]=title
+        file["album"]=album
+        file["genre"]=genre
+        file.save()
+
+    def remove_cover_opus_generic(self,snd):
+
+        file = OggOpus(snd)
+        #year=file["YEAR_OF_RELEASE"]
+        try:
+            artist=file["artist"]
+        except KeyError:
+            artist=""
+        try:
+            title=file["title"]
+        except KeyError:
+            title=""
+        try:
+            year=file["year_of_relase"]
+        except KeyError:
+            year=""
+        try:
+            album=file["album"]
+        except KeyError:
+            album=""
+        try:
+            genre=file["genre"]
+        except KeyError:
+            genre=""
+
+        file.delete()
+        file["year_of_relase"]=year
+        file["artist"]=artist
+        file["title"]=title
+        file["album"]=album
+        file["genre"]=genre
+        file.save()
+
+
+class DialogAddCoverProgress(Gtk.Dialog):
+    def __init__(self,parent):
+
+        Gtk.Dialog.__init__(self, title="Postęp", transient_for=parent, flags=0)
+        self.current_snd=0
+        self.props.border_width = 20
+        #self.add_buttons(
+        #    Gtk.STOCK_OK, Gtk.ResponseType.OK
+        #)
+        self.progressbar = Gtk.ProgressBar()
+        self.set_default_size(150, 100)
+        box = self.get_content_area()
+
+        label = Gtk.Label(label="Dodaję okladkę do plików\n")
+
+        box.add(label)
+        box.add(self.progressbar)
+
+        self.divider_next=1/len(file_snd_selected)
+        self.timeout_id = GLib.timeout_add(300, self.on_timeout, len(file_snd_selected))
+        self.activity_mode = False
+        self.show_all()
+
+    def on_timeout(self, user_data):
+        global img_extension
+        #jesli przepytano wszyskie pliki wówczas koniec
+        if self.current_snd == user_data:
+            self.add_buttons(
+                Gtk.STOCK_OK, Gtk.ResponseType.OK
+            )
+            self.show_all()
+            return False
+
+        if self.activity_mode:
+            self.progressbar.pulse()
+        else:
+            new_value = self.progressbar.get_fraction() + self.divider_next
+
+            #if new_value > 1:
+            #    new_value = 0
+
+            self.progressbar.set_fraction(new_value)
+            snd=file_snd_selected[self.current_snd]
+            self.current_snd = self.current_snd +1
+            print ("file selected: ",snd)
+            extension = os.path.splitext(snd)
+            snd_extension=extension[1].replace(".", "")
+            print ("Rozszerzenie pliku dzwiekowego: ", snd_extension)
+
+            
+            #print ("file selected: ",snd)
+            #extension = os.path.splitext(snd)
+            #snd_extension=extension[1].replace(".", "")
+            #print ("Rozszerzenie pliku dzwiekowego: ", snd_extension)
+
+            if snd_extension.lower() == "ogg":
+
+                file_ = OggVorbis(snd)
+                print("IMAGE FILE: ",file_img_selected)
+                with open(file_img_selected, "rb") as h:
+                    data = h.read()
+
+                    img_extension=img_extension.lower()
+                    picture = Picture()
+                    picture.data = data
+                    picture.type = 17
+                    picture.desc = u"Picture set by cover2music"
+                    picture.mime = u"image/"+img_extension
+                    picture.width = 100
+                    picture.height = 100
+                    picture.depth = 24
+
+                    picture_data = picture.write()
+                    encoded_data = base64.b64encode(picture_data)
+                    vcomment_value = encoded_data.decode("ascii")
+
+                    file_["metadata_block_picture"] = [vcomment_value]
+                    file_.save()
+
+            elif snd_extension.lower() == "oga":
+
+                #for snd in file_snd_selected:
+                file_ = OggFLAC(snd)
+                print("IMAGE FILE: ",file_img_selected)
+                with open(file_img_selected, "rb") as h:
+                    data = h.read()
+
+                    img_extension=img_extension.lower()
+                    picture = Picture()
+                    picture.data = data
+                    picture.type = 17 # 0x7f
+                    picture.desc = u"Picture set by cover2music"
+                    picture.mime = u"image/"+img_extension
+                    picture.width = 100
+                    picture.height = 100
+                    picture.depth = 24
+
+                    picture_data = picture.write()
+                    encoded_data = base64.b64encode(picture_data)
+                    vcomment_value = encoded_data.decode("ascii")
+
+                    file_["metadata_block_picture"] = [vcomment_value]
+                    file_.save()
+
+
+            elif snd_extension.lower() == "opus":
+
+                #for snd in file_snd_selected:
+                file_ = OggOpus(snd)
+                print("IMAGE FILE: ",file_img_selected)
+                with open(file_img_selected, "rb") as h:
+                    data = h.read()
+
+                    img_extension=img_extension.lower()
+                    picture = Picture()
+                    picture.data = data
+                    picture.type = 17 # 0x7f
+                    picture.desc = u"Picture set by cover2music"
+                    picture.mime = u"image/"+img_extension
+                    #picture.width = 100
+                    #picture.height = 100
+                    #picture.depth = 24
+
+                    picture_data = picture.write()
+                    encoded_data = base64.b64encode(picture_data)
+                    vcomment_value = encoded_data.decode("ascii")
+
+                    file_["metadata_block_picture"] = [vcomment_value]
+                    file_.save()
+
+            elif snd_extension.lower() == "mp3":
+                #for snd in file_snd_selected:
+                print ("Dodaje do mp3: ",snd)
+                print ("file_img_selected: ", file_img_selected)
+                file = MP3(snd, ID3=ID3)
+
+                try:
+                    file.add_tags()
+                except error:
+                    pass
+
+                file.tags.add(APIC(mime="image/"+img_extension,type=3,desc=u'Cove by cover2music',data=open(file_img_selected,'rb').read()))
+                file.save()  # save the current changes
+
+            else:
+                print ("źle")
+
+        # As this is a timeout function, return True so that it
+        # continues to get called
+        return True
+
+
+
+class DialogHelp(Gtk.Dialog):
+    def __init__(self, parent):
+        Gtk.Dialog.__init__(self, title="Pomoc", transient_for=parent, flags=0)
+        self.props.border_width = 20
+        self.add_buttons(
+            Gtk.STOCK_OK, Gtk.ResponseType.OK
+        )
+
+        self.set_default_size(150, 100)
+        txt="-jednak samo załadownie obrazka do pliku nie gwarantuje, że zmieni się ikona w menedżerze plików.\n W tym względzie są przyjazne menedżery takie jak PCManFM, jak i nieprzyjazne jak Nemo.\n Jednak w graficznym odtwarzaczu, załadowany obrazek powinien pojawić się zawsze\n\n"
+        label1 = Gtk.Label(label="Aplikacja jest w stanie dodać okładkę do prawie wszystkich plików MP3, oraz do plików OGG (Vorbis),\n OGA (OGG FLAC) oraz OPUS. Możliwe jest również usuwanie okładek z pozostawieniem pozostałych tagów.\n  Pliki można zmieniać pojedynczo jak i grupowo. Okładki odczytywane są w formatach JPEG oraz PNG.\n Należy zadbać wcześniej aby obrazy okładek nie były zbyt duże, optymalna wielkość to 384x384 px.\n\n")
+        label2 = Gtk.Label(label=" Uwagi:\n-format JPEG w plikach OPUS nie jest wspierany \n-mieszana kolekcja plików zakodowanych rożnymi kodekami w kontenerach OGG jest co prawda możliwa,\n  jednak skrypt może zachowywać się niestabilnie\n"+txt)
+        box = self.get_content_area()
+        box.add(label1)
+        box.add(label2)
+        self.show_all()
+
+class DialogAbout(Gtk.Dialog):
+    def __init__(self, parent):
+        Gtk.Dialog.__init__(self, title="O Programie", transient_for=parent, flags=0)
+        self.props.border_width = 20
+        self.add_buttons(
+            Gtk.STOCK_OK, Gtk.ResponseType.OK
+        )
+
+        self.set_default_size(150, 100)
+
+        label = Gtk.Label(label="\tAplikacja napisana na podstawie:\n\nhttps://python-gtk-3-tutorial.readthedocs.io/\n\n\t\t\tWersja: 0.1-3\n\n\t\tPrzemysław R. Pietraszczyk\n\n\t\t\tKwiecień/Maj 2021\n\t\t\tLicencja: GPL\n\n")
+        #label3 = Gtk.Label(label="-jednak samo załadownie obrazka do pliku nie gwarantuje, że zmieni się ikona w menedżerze plików.\n W tym względzie są przyjazne menedżery takie jak PCManFM, jak i nie przyjazne jak Nemo.\n Jednak w graficznym odtwarzaczu, załadowany obrazek powinien pojawić się zawsze.\n\n")
+
+        box = self.get_content_area()
+        box.add(label)
+
+        button = Gtk.LinkButton("http://www.prp.xlx.pl", label="Strona Domowa")
+        box.add(button)
+
+        self.show_all()
+
+class DialogNoSelectIMG(Gtk.Dialog):
+    def __init__(self, parent):
+        Gtk.Dialog.__init__(self, title="Błąd", transient_for=parent, flags=0)
+        self.props.border_width = 20
+        self.add_buttons(
+            Gtk.STOCK_OK, Gtk.ResponseType.OK
+        )
+
+        self.set_default_size(150, 100)
+
+        label = Gtk.Label(label="Nie wybrano żadnego pliku z muzyką!\n")
+
+        box = self.get_content_area()
+        box.add(label)
+
+        self.show_all()
+
+def get_resource_path(rel_path):
+    dir_of_py_file = os.path.dirname(__file__)
+    rel_path_to_resource = os.path.join(dir_of_py_file, rel_path)
+    abs_path_to_resource = os.path.abspath(rel_path_to_resource)
+    return abs_path_to_resource
+
+
+grid = Gtk.Grid()
+
+
+class MyWindow(Gtk.Window):
+
+    def __init__(self):
+        super().__init__()
+
+        self.init_ui()
+
+
+    def init_ui(self):
+        global grid, file_img_selected, snd_extension
+        self.image_new=None
+        #grid = Gtk.Grid()
+        self.props.border_width = 20
+        #self.img_extension="png" # dla przykladu
+        #snd_extension="ogg"
+
+        self.add(grid)
+
+        grid.set_row_spacing(10)
+        grid.set_column_spacing(10)
+        grid.set_column_homogeneous(True) # rozszerza kontrolke z utworami na resztę okna
+
+        action_group = Gtk.ActionGroup(name="my_actions")
+
+        self.add_file_menu_actions(action_group)
+        self.add_info_menu_actions(action_group)
+        self.add_choices_menu_actions(action_group)
+
+        uimanager = self.create_ui_manager()
+        uimanager.insert_action_group(action_group)
+
+        menubar = uimanager.get_widget("/MenuBar")
+
+        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
+        box.pack_start(menubar, False, False, 0)
+
+        grid.attach(box, 0, 0, 2, 1)
+        file_img_selected=get_resource_path(COVER)
+        pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
+            filename=file_img_selected,
+            width=100,
+            height=100,
+            preserve_aspect_ratio=True)
+
+        self.image = Gtk.Image.new_from_pixbuf(pixbuf)
+        grid.attach(self.image,0,1,1,1)
+
+        quitBtn = Gtk.Button(label="Wykonaj !")
+        quitBtn.set_size_request(60, 30)
+
+        quitBtn.connect("clicked", self.on_button_clicked)
+
+        grid.attach(quitBtn, 0, 2, 1, 1) # lewo, top wielkosc, wysokosc
+
+        self.liststore = Gtk.ListStore(str, str)
+        self.treeview = Gtk.TreeView(model=self.liststore)
+
+        self.renderer_text = Gtk.CellRendererText()
+        self.column_text = Gtk.TreeViewColumn("Wybrane Utwory", self.renderer_text, text=0)
+        self.treeview.append_column(self.column_text)
+
+        self.scrolled_window = Gtk.ScrolledWindow ()
+        self.scrolled_window.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
+
+        self.scrolled_window.add (self.treeview)
+        grid.attach_next_to(self.scrolled_window, self.image ,Gtk.PositionType.RIGHT,6,2)
+
+        self.set_border_width(10)
+        self.set_title("Cover2Music")
+        self.set_default_size(650, 180)
+        self.connect("destroy", Gtk.main_quit)
+
+        self.set_icon_from_file(get_resource_path(COVER))
+
+    def on_button_clicked(self, widget):
+        global file_img_selected, snd_extension
+
+        if len(file_snd_selected)<1:
+            print("nie zaznaczyleś żadnego pliku z muzyką !")
+            dialog = DialogNoSelectIMG(self)
+            response = dialog.run()
+            dialog.destroy()
+            return
+
+
+        progress =DialogAddCoverProgress(self)
+        response = progress.run()
+        progress.destroy()
+
+
+    def add_info_menu_actions(self, action_group):
+        action_info_menu = Gtk.Action(name="InfoMenu", label="Info")
+        action_group.add_action(action_info_menu)
+
+        action_new = Gtk.Action(
+            name="Help",
+            label="Pomoc",
+            tooltip="Create a new file",
+        )
+        action_new.connect("activate", self.on_menu_help)
+        action_group.add_action_with_accel(action_new, None)
+
+        action_new = Gtk.Action(
+            name="About",
+            label="O Programie",
+            tooltip="Create a new file",
+        )
+        action_new.connect("activate", self.on_menu_about)
+        action_group.add_action_with_accel(action_new, None)
+
+    def add_file_menu_actions(self, action_group):
+        action_filemenu = Gtk.Action(name="FileMenu", label="Plik")
+        action_group.add_action(action_filemenu)
+
+        action_fileloadmenu = Gtk.Action(name="FileLoad", stock_id=Gtk.STOCK_NEW)
+        action_group.add_action(action_fileloadmenu)
+
+        action_new = Gtk.Action(
+            name="LoadImg",
+            label="Załaduj okladkę",
+            tooltip="Wybór okladki",
+        )
+        action_new.connect("activate", self.on_menu_file_load_img_generic)
+        action_group.add_action_with_accel(action_new, None)
+
+
+        action_new = Gtk.Action(
+            name="LoadOgg",
+            label="Załaduj muzykę",
+            tooltip="Wybór muzyki",
+        )
+        action_new.connect("activate", self.on_menu_file_load_ogg_generic)
+        action_group.add_action_with_accel(action_new, None)
+
+        action_fileloadmenu = Gtk.Action(name="FileDelete", label="Usuń", stock_id=None)
+        action_group.add_action(action_fileloadmenu)
+
+        action_new = Gtk.Action(
+            name="RemoveCover",
+            label="Usuwa okladkę",
+            tooltip="Usuwa okladkę z pliku",
+        )
+        action_new.connect("activate", self.on_menu_file_erase_cover_all)
+        action_group.add_action_with_accel(action_new, None)
+
+
+        action_filequit = Gtk.Action(name="FileQuit", stock_id=Gtk.STOCK_QUIT)
+        action_filequit.connect("activate", self.on_menu_file_quit)
+        action_group.add_action(action_filequit)
+
+    def add_choices_menu_actions(self, action_group):
+        action_group.add_action(Gtk.Action(name="ChoicesMenu", label="Opcje"))
+
+        three = Gtk.ToggleAction(name="ChoiceTree", label="Pozwolenie")
+        three.connect("toggled", self.on_menu_choices_toggled)
+        action_group.add_action(three)
+
+    # tworzy menu bar
+    def create_ui_manager(self):
+        uimanager = Gtk.UIManager()
+
+        # Throws exception if something went wrong
+        uimanager.add_ui_from_string(UI_INFO)
+
+        # Add the accelerator group to the toplevel window
+        accelgroup = uimanager.get_accel_group()
+        self.add_accel_group(accelgroup)
+        return uimanager
+
+    def on_menu_help(self, widget):
+        dialog = DialogHelp(self)
+        response = dialog.run()
+
+        dialog.destroy()
+
+    def on_menu_about(self, widget):
+        dialog = DialogAbout(self)
+        response = dialog.run()
+
+        dialog.destroy()
+
+
+    def on_menu_file_load_img_generic(self, widget):
+        global grid, file_img_selected, img_extension
+
+        print("A File|New menu item was selected.")
+        file=FileChooserIMG()
+        print ("file:"+str(file_img_selected))
+        pixbuf_new = GdkPixbuf.Pixbuf.new_from_file_at_scale(
+        filename=file_img_selected,
+        width=100,
+        height=100,
+        preserve_aspect_ratio=True)
+
+        if self.image != None:
+            grid.remove(self.image)
+            self.image=None
+        else:
+            grid.remove(self.image_new)
+
+
+        # TODO - pozbyć się self.image_new na rzecz self.image
+        self.image_new = Gtk.Image.new_from_pixbuf(pixbuf_new)
+        grid.attach_next_to(self.image_new, self.scrolled_window,Gtk.PositionType.LEFT,1,1)
+
+        self.show_all()
+
+        extension = os.path.splitext(file_img_selected)
+        #self.img_extension=extension[1].replace(".", "") # tupla (0) wskazuje na nazwe pliku !
+        img_extension=extension[1].replace(".", "") # tupla (0) wskazuje na nazwe pliku !
+
+
+    def on_menu_file_load_ogg_generic(self, widget):
+        global file_snd_selected
+        file=FileChooserOgg()
+        #grid.remove(self.treeview)
+        self.scrolled_window.remove(self.treeview)
+        grid.remove(self.scrolled_window)
+        self.liststore = Gtk.ListStore(str, str)
+        self.treeview.remove_column(self.column_text)
+
+        print ("file selected: ",file_snd_selected)
+
+        for o in file_snd_selected:
+            self.liststore.append([o,""])
+
+        self.scrolled_window = Gtk.ScrolledWindow ()
+        self.scrolled_window.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
+
+        self.treeview = Gtk.TreeView(model=self.liststore)
+        self.renderer_text = Gtk.CellRendererText()
+        self.column_text = Gtk.TreeViewColumn("Wybrane Utwory", self.renderer_text, text=0)
+        self.treeview.append_column(self.column_text)
+
+        if self.image != None:
+            self.scrolled_window.add (self.treeview)
+            grid.attach_next_to(self.scrolled_window, self.image ,Gtk.PositionType.RIGHT,6,2)
+        else:
+            self.scrolled_window.add (self.treeview)
+            grid.attach_next_to(self.scrolled_window, self.image_new ,Gtk.PositionType.RIGHT,6,2)
+
+        self.show_all()
+    """
+    def close_progress(self, gparmstring):
+        self.progress.destroy()
+    """
+    def on_menu_file_erase_cover_all(self, widget):
+
+        if len(file_snd_selected)<1:
+            dialog = DialogNoSelectIMG(self)
+            response = dialog.run()
+            dialog.destroy()
+            return
+
+        self.progress =DialogDeleteProgress(self)
+        response = self.progress.run()
+        self.progress.destroy()
+
+
+    def on_menu_file_quit(self, widget):
+        Gtk.main_quit()
+
+    def on_menu_choices_toggled(self, widget):
+        if widget.get_active():
+            print(widget.get_name() + " activated")
+        else:
+            print(widget.get_name() + " deactivated")
+
+    def on_button_press_event(self, widget, event):
+        # Check if right mouse button was preseed
+        if event.type == Gdk.EventType.BUTTON_PRESS and event.button == 3:
+            self.popup.popup(None, None, None, None, event.button, event.time)
+            return True  # event has been handled
+
+
+win = MyWindow()
+win.show_all()
+Gtk.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cover2musc/makefile	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,18 @@
+#
+prefix=/usr
+
+install:
+#	mkdir -pm -755 $(prefix)
+	mkdir -pm -755 $(prefix)/share/pixmaps
+	install -m 0755 cover2music.py $(prefix)/bin
+	install -m 0644 cover2music.png $(prefix)/share/pixmaps
+	install -m 0755 cover2music.desktop $(prefix)/share/applications
+
+.PHONY: install
+
+uninstall:
+	rm $(prefix)/bin/cover2music.py
+	rm $(prefix)/share/pixmaps/cover2music.png
+	rm $(prefix)/share/applications/cover2music.desktop
+
+.PHONY: uninstall
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cover2musc/setup.py	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,29 @@
+#setup.py
+from distutils.sysconfig import get_python_lib
+from os.path import join
+from glob import glob
+from cx_Freeze import setup, Executable
+
+# Basically just copy all of the CEF distribution into the installer
+# I have only tested this on windows
+cefPath = join(get_python_lib(), "cefpython3")
+CEF_INCLUDES = glob(join(cefPath, "*"))
+#CEF_INCLUDES.remove(join(cefPath, "examples"))
+
+setup(
+    name = "cover2music",
+    version = "20210428",
+    options = {
+        "build_exe": {
+        'packages': ["os","gi","gi.repository","base64","mutagen.oggvorbis","mutagen.flac","mutagen.mp3","mutagen.id3"],
+        'include_files': CEF_INCLUDES + ['cover2music.png'],
+        'include_files': CEF_INCLUDES,
+
+        'include_msvcr': True,
+    }},
+    #executables = [Executable("main.py", base="Win32GUI")]
+    #executables = [Executable("main.py", base = "Win32GUI"), icon = "C:/Program Files/iNTMI/assets/images/programIcon.ico")]
+    executables = [Executable("main.py", base = "Win32GUI"), icon = "cover2music.ico")]
+
+
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/photocrop/DEBIAN/HOWTO	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,2 @@
+foramt zapisu nazwy pliku:
+	photocrop_0.221225-0~alpha.tar.gz
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/photocrop/DEBIAN/debian.changelog	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,5 @@
+photocrop (0.221225-4) unstable; urgency=low
+
+  * Last release
+
+ -- Przemysław R. Pietraszczyk  Sat, 25 Dec 2022 08:31:41 +0200
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/photocrop/DEBIAN/debian.control	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,13 @@
+Source: photocrop
+Section: python
+Priority: extra
+Maintainer: Przemysław R. Pietraszczyk
+Build-Depends: debhelper-compat (= 13), python3-all, python-setuptools, dh-python, python3-gi, python3-gi-cairo, gir1.2-gtk-3.0, fakeroot
+Standards-Version: 0.230112-0~alpha
+Homepage: http://pietraszczyk.vxm.pl/przycianie-zdjec
+
+
+Package: photocrop
+Architecture: all
+Depends: ${misc:Depends}, python3-all, python3-gi, python3-gi-cairo, gir1.2-gtk-3.0
+Description: An application for cropping photos to popular paper sizes.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/photocrop/DEBIAN/debian.rules	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,29 @@
+#!/usr/bin/make -f
+
+export DH_VERBOSE = 1
+#export PYBUILD_NAME = photocrop
+#export PYBUILD_SYSTEM = custom
+
+clean:
+	@
+	
+build:
+	@
+
+binary:
+	mkdir -pm 0755 debian/photocrop
+	mkdir -pm 0755 debian/photocrop/usr/bin
+	mkdir -pm 0755 debian/photocrop/usr/share
+	mkdir -pm 0755 debian/photocrop/usr/share/photocrop
+	mkdir -pm 0755 debian/photocrop/usr/share/applications
+	cp src/photocrop.py debian/photocrop/usr/bin
+	cp data/clip.png debian/photocrop/usr/share/photocrop
+	cp data/IMG_6854.JPG debian/photocrop/usr/share/photocrop
+	cp data/photocrop.desktop  debian/photocrop/usr/share/applications
+	dh_gencontrol
+	dh_builddeb
+#	dh $@ --with python3 --buildsystem=pybuild
+#	dh $@ --with python3
+
+#override_dh_auto_configure:
+#	dh_auto_configure --
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/photocrop/DEBIAN/format.sh	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,1 @@
+exec /usr/lib/build/debtransform ./ ./photocrop.dsc ./exec
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/photocrop/DEBIAN/photocrop.dsc	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,41 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA256
+
+Format: 1.0
+Source: photocrop
+Binary: photocrop
+Architecture: all
+Version: 0.230112-0~alpha
+Maintainer: Przemysław R. Pietraszczyk <przem@pietraszczyk.vxm.pl>
+Homepage: http://pietraszczyk.vxm.pl
+DEBTRANSFORM-TAR: debian.tar.gz
+DEBTRANSFORM-TAR: photocrop_0.2301012-0~alpha.tar.gz
+ 
+Standards-Version: 0.2301012-0~alpha
+Build-Depends: debhelper-compat (= 13), python3-all, python-setuptools, dh-python, python3-gi, python3-gi-cairo, gir1.2-gtk-3.0, fakeroot
+Package-List:
+ photocrop deb x11 optional arch=all
+Files:
+ b31649bc23b2b7bca9ab70ea3410711a 128820 photocrop_0.230112-0~alpha.tar.gz
+ 29e7e7e60bc81891e3da3871b9eeb549 764 photocrop-0.230112-0~alpha.debian.tar.xz
+
+-----BEGIN PGP SIGNATURE-----
+
+mQENBGEf/c4BCAC2d4ymW0pRZV36qLtlt/WGb83kos5UX5UbwvkQrbUjAbOPOY8w
+DT3M1neYOAPZx38924aPTFKbZPcz+rK/7Wcv1kzgfux5zXQJTLeqpkhUYAgXUg2p
+oK9ZXsai82fOicTrClOyJLLYQ8C1vj8yUh7e3ERljEyp5Nxg/lY92rwcZ4WYR193
+nGDInlDl5JlWUcLlk/RFnC5bB+T6ZZr5FBX/eDnKAPEl+N3MWpDs2JLDy7EUPhcG
+U/60X0wuXHPTwMoNbB3ep/bWRxwEej0sFad5GXeCh7hKCroi/kLmLTDIxSD8lsRr
+Y4H/8H2lBBsQq7bRL88N6ZDGCocPo11V83kFABEBAAG0NmhvbWU6cHJ6ZW0gT0JT
+IFByb2plY3QgPGhvbWU6cHJ6ZW1AYnVpbGQub3BlbnN1c2Uub3JnPokBPgQTAQgA
+KAUCYR/9zgIbAwUJBB6wAAYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQcXEc
+NPcNefFEAAf+Kg4cs/C99kEIMv/PO85VW+p8rcTwCViOFUX5WrBhwsRyPAKrJPPG
+KD6PdnvoplcNQwhQ8nRsRiiaiUtPcj8Bvi6EdPgSgXXObKKJtCyaAa1rURdlb9iW
+CfvXA6oW+PGlii9BMnXOAtkeFIzZooO9oXd+wez66P+4VWFiFzxanLfLn/hwbWxQ
+68rlO3QNGbrMeODBgwh9s83XGmAg47mn2fldTAmTbJDf9tMi1LhX2MmLyN9wjqsd
+4IZ9JMri2JTnIhYfxWdKT9gsu7q0g8LqonaXMvlOEyHFRF1YQ0i7G6fFbvDcKCZN
+W1Eja55FdN7smv5Eck6UTIIYyWPuAv45uohGBBMRAgAGBQJhH/3PAAoJEDswEbdr
+nWUj4M0AniJ389dyvUjjgS91AcOb08E4moV9AJ9WDL3/7GYYUL/Azw43QucWPnXr
+uw==
+=+lfH
+-----END PGP SIGNATURE-----
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/photocrop/INSTALL	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,92 @@
+Windows
+
+Go to http://www.msys2.org/ and download the x86_64 installer
+
+Follow the instructions on the page for setting up the basic environment
+
+Run C:\msys64\mingw64.exe - a terminal window should pop up
+
+Execute pacman -Suy
+
+Execute pacman -S mingw-w64-x86_64-gtk3 mingw-w64-x86_64-python3 mingw-w64-x86_64-python3-gobject
+
+
+Ubuntu/Debian
+
+Installing the system provided PyGObject:
+Open a terminal
+
+Execute sudo apt install python3-gi python3-gi-cairo gir1.2-gtk-3.0
+
+Installing from PyPI with pip:
+Open a terminal and enter your virtual environment
+
+Execute sudo apt install libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev gir1.2-gtk-3.0 to install the build dependencies and GTK
+
+Execute pip3 install pycairo to build and install Pycairo
+
+Execute pip3 install PyGObject to build and install PyGObject
+
+
+
+Fedora
+
+Installing the system provided PyGObject:
+Open a terminal
+
+Execute sudo dnf install python3-gobject gtk3
+
+Open a terminal and enter your virtual environment
+
+Execute sudo dnf install gcc gobject-introspection-devel cairo-gobject-devel pkg-config python3-devel gtk3 to install the build dependencies and GTK
+
+Execute pip3 install pycairo to build and install Pycairo
+
+Execute pip3 install PyGObject to build and install PyGObject
+
+
+Arch Linux
+
+Installing the system provided PyGObject:
+Open a terminal
+
+Execute sudo pacman -S python-gobject gtk3
+
+Installing from PyPI with pip:
+Open a terminal and enter your virtual environment
+
+Execute sudo pacman -S python cairo pkgconf gobject-introspection gtk3 to install the build dependencies and GTK
+
+Execute pip3 install pycairo to build and install Pycairo
+
+Execute pip3 install PyGObject to build and install PyGObject
+
+
+
+
+openSUSE
+
+Installing the system provided PyGObject:
+Open a terminal
+
+Execute sudo zypper install python3-gobject python3-gobject-Gdk typelib-1_0-Gtk-3_0 libgtk-3-0
+
+Installing from PyPI with pip:
+Open a terminal and enter your virtual environment
+
+Execute sudo zypper install cairo-devel pkg-config python3-devel gcc gobject-introspection-devel to install the build dependencies and GTK
+
+Execute pip3 install pycairo to build and install Pycairo
+
+Execute pip3 install PyGObject to build and install PyGObject
+
+
+
+
+macOS
+
+Go to https://brew.sh/ and install homebrew
+
+Open a terminal
+
+Execute brew install pygobject3 gtk+3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/photocrop/LICENSE	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/photocrop/Makefile	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,21 @@
+
+prefix=/usr
+
+all:
+
+install:
+	mkdir -pm 0755 $(prefix)/share/photocrop
+	install -m 0755 src/photocrop.py $(prefix)/bin
+	install -m 0644 data/clip.png $(prefix)/share/photocrop
+	install -m 0644 data/IMG_6854.JPG $(prefix)/share/photocrop
+	install -m 0644 data/photocrop.desktop $(prefix)/share/applications
+
+
+uninstall:
+	rm $(prefix)/share/photocrop/clip.png
+	rm $(prefix)/share/photocrop/IMG_6854.JPG
+	rmdir $(prefix)/share/photocrop/
+	rm $(prefix)/bin/photocrop.py
+	rm $(prefix)/share/applications/photocrop.desktop
+	
+.PHONY: all install uninstall
Binary file photocrop/Makefile.in.gz has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/photocrop/RPM/photocrop.spec	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,71 @@
+#
+# spec file for package photocrop
+#
+# Copyright (c) 2020 SUSE LLC
+#
+# All modifications and additions to the file contributed by third parties
+# remain the property of their copyright owners, unless otherwise agreed
+# upon. The license for this file, and modifications and additions to the
+# file, is the same license as for the pristine package itself (unless the
+# license for the pristine package is not an Open Source License, in which
+# case the license is the MIT License). An "Open Source License" is a
+# license that conforms to the Open Source Definition (Version 1.9)
+# published by the Open Source Initiative.
+
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
+#
+
+%define unmangled_version 0.230112-0~alpha
+Name:       photocrop
+Version:	0.230112
+Release:    0~alpha
+Summary:	An application for cropping photos to popular paper sizes.
+License:	GPL
+URL:		https://pietraszczyk.vxm.pl/przycinanie-zdjec/
+Source0:	%{name}-%{unmangled_version}.tar.gz
+%if 0%{?suse_version}>=150000
+BuildRequires:	python3, python3-gobject, python3-gobject-Gdk, typelib-1_0-Gtk-3_0, libgtk-3-0
+Requires:       python3, python3-gobject, python3-gobject-Gdk, typelib-1_0-Gtk-3_0, libgtk-3-0
+%endif
+%if 0%{?fedora}>=35
+BuildRequires:	python3, python3-gobject, gtk3
+Requires:		python3, python3-gobject, gtk3
+%endif
+BuildArch:	noarch
+
+%description
+
+
+%prep
+%setup -n %{name}-%{unmangled_version} -n %{name}-%{unmangled_version}
+
+%build
+
+%install
+
+mkdir -p %{buildroot}/usr
+mkdir -p %{buildroot}/usr/share
+mkdir -p %{buildroot}/usr/share/photocrop
+mkdir -p %{buildroot}/usr/share/applications
+mkdir -p %{buildroot}/usr/bin
+
+install -m 0755 src/photocrop.py %{buildroot}/usr/bin
+install -m 0644 data/clip.png %{buildroot}/usr/share/photocrop/clip.png
+#install -m 0644 data/blank.png %{buildroot}/usr/share/photocrop/blank.png
+install -m 0644 data/IMG_6854.JPG %{buildroot}/usr/share/photocrop/IMG_6854.JPG
+install -m 0644 data/photocrop.desktop %{buildroot}/usr/share/applications
+
+
+
+%files
+%defattr(0755,root,root)
+/usr/bin/photocrop.py
+/usr/share/photocrop/
+%defattr(0644,root,root)
+/usr/share/photocrop/clip.png
+#/usr/share/photocrop/blank.png
+/usr/share/photocrop/IMG_6854.JPG 
+/usr/share/applications/photocrop.desktop
+
+%changelog
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/photocrop/bugs.txt	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,3 @@
+1. Losowe zniekształcenia na podglądzie po przycięciu, ale tylko na podglądzie, wydruk jest prawidłowy.
+2. Źle współpracuje z grafiką utworzoną w Krita. 
+3. Przed wydrukiem należy spojrzeć w kreatorze wydruku na sugerowaną orientację zdjęcia.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/photocrop/changelog	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,70 @@
+0.230112-0 - Poprawki odświeżania okna po przycięciu
+0.230107-0 - Poprawiłem skalowanie dla średniego formatu. Wyszła na jaw zła współpraca z grafiką utworzoną w Krita ! 
+0.221229-0 - Interfejs po angielsku, poprawiłem skalowanie ramki dla małego i dużego formatu.
+0.221225-0 - Korekta wielkości początkowej ramki
+0.221224-3 - Poprawki dla konfiguracji ramki dla pozostałych formatów
+0.221234-2 - Poprawiłem skalowanie dla zdjęć horyzontalnych
+0.221224-1 - W zależności jaka była pierwotnie orientacja zdjęcia, po obrocie jest ono odpowiednio przycinane
+0.221224-0 - Nie rozciąga już zdjęcia po przycięciu po obrocie na wertylkane
+0.221223-0 - Poprawiłem odzyskiwanie ramki po obrocie, dodałem zapis przyciętej fotografii
+0.221214-3 - Zrezygnowałem z ograniczeń ramki przy krawędziach zdjęcia gdyż źle oddziaływały na ramkę. Przywróciłem sposób z wyświetlaniem okna dialogowego po przekroczeniu krawędzi.
+0.221214-2 - Poprawki drobnych błędów
+0.221214-1 - Zwiększyłem rozmiar ramki po obrocie
+0.221214-0 - Poprawiłem błąd powodujący wyłączenie się skryptu po przycięciu obrazka w dolnych partiach
+0.221213-2 - Dodałem menu wraz z odnośnikiem z licencją (w końcu!). Poprawiłem informacje "O Programie"
+0.221213-1 - Poprawki błędów związanych z literówkami dotyczącymi aspektu ramki 
+0.221213-0 - Poprawiłem odświeżanie kontrolki po obrocie - jednak dla obrazków wertykalnych zbyt niskie położenie ramki grozi krachem aplikacji
+0.221212-1 - Poprawiłem przekształcanie ramki po obrocie
+0.221212-0 - Okno zmienia już swoją wielkość po rotacji, lepsze dobór ramki po rotacji obrazu. 
+0.221211-5 - Prawidłowo obraca obrazek do wydruku
+0.221211-4 - W celu okiełzania ramki należy operować wartościami w "self.border_properties" 
+0.221211-3 - Przycina obrócony obraz, jednak partaczy wydruk
+0.221211-2 - Ramka już nie przyrasta vertykalnie
+0.221211-0 - Próba implementacji obrotu ramki - do poprawki
+0.221210-0 - Przepisanie rozmiaru ramki do słownika. Z sukcesem ! FIXME - zablokować możliwość powiększania ramki po dojściu z jednego z brzegów do konturu. W przeciwnym wypadku kłuci się to z sensownością aplikacji.
+0.220317-0 - Dodałem odczyt plików TIFF, jednak aplikacja źle przycina – szare tło
+0.220315-1 - Należało by aby aplikacja rozróżniała pochodzenie zdjęcia (lustrzanka, kompakt, smartphone)) w celu doboru współczynnika ramki
+0.220314-0 - Drukuje prawidłowo zdjęcia zarówno wertykalne jak i horyzontalne, jednak przy tych ostatnich papier należy również umieścić horyzontalnie w drukarce !
+0.220308-0 - Dalsza korekta ustawień ramki oraz skalowania ramki dla rozmiaru A6
+0.220306-1 - Likwidacja podmenu otwarcia pliku, rozmiar okna dostosowuje się do położenia/rozmiaru zdjęcia.
+0.220306-0 - Korekta ramki dla zdjęć horyzontalnych, korekta dotyczy również skalowania tych zdjęć. Jednak są sytuacje gdy dodawana jest ramka do zdjęć.
+0.220217-0 - Teraz drukuje !
+0.220216-3 - Korekta przy współżędnych tworzenia ramki, potrzebna korekta ramki przy skalowaniu 
+0.220216-2 - Małe poprawki w 'Gtk.PaperSize.new.custom'
+0.220216-1 - Próba wydruku na orginalnych wymiarach zaraz po przycięciu, nie wiem czy drukarka ruszy... 
+0.220216-0 - Podbicie nieco pikseli w wydruku, przejście z milimetrów na punkty przy wydruku
+0.220214-1 - Przywrócenie poprzednich rozmiarów ramki
+0.220214-0 - Rezygnacja ze stalej 0.075 na rzecz nie odejmowania 'crop_y'
+0.220213-0 - Przypisanie 'self.pixbuf_tmp' wartości None, oraz zapobiegnięcie wyjścia ramki poza obrazek przy scrolowaniu kółkiem myszki.
+0.220212-1 - Kalibracja wydruku
+0.220212-0 - Dodałem ograniczenia dla ramki na krawędziach zdjęcia
+0.220211-0 - Korekcja wspóczynników ramki dla rozmiaru 13x18
+0.220210-0 - Poprawiłem przywracanie zdjęcia w kontrolce dla 13x18
+0.220205-0 - Wstępne ustawienia dla papieru do wydruku – wszystkie formaty.
+0.220204-1 - Przyczółek do korekty wydruku w rozmiarze 10x15
+0.220204-0 - Poprawiłem odświeżenie podglądu po przywróceniu, jednak dla formatu ‘13x18’ odświeżenie bywa problematyczne. Dopisałem opcje drukowania bezpośrednio z ‘prevew’.
+0.220202-5 - Dopisałem ustawienia ramki dla pozostałych rozmiarów, uaktualniłem przypisanie rozmiaru obrazka w kontrolce po przywróceniu.
+0.220202-4 - Zakomentowanie odjęcia stałej 0,075 od 'bw' - powód: wyjście poza obszar przy przycięciu w okolicach prawego skraju zdjęcia. 
+0.220202-3 - Optymalizacja kodu → set_ratio_picture_view()
+0.220202-2 - Optymalizacja kodu → self.set_ratio_border_size()
+0.220202-1 - Włącznie stałej 0,075 również do zmiennej ‘bw’ dla zachowania proporcji obrazu.
+0.220202-0 - Ustawienie stałej 0.075 jedynie dla zmiennej ‘bh’, poprawka dla aktualizacji podglądu po przycięciu.
+0.220201-2 - Zmniejszenie progresji ramki w funkcji ‘on_mouse_move_in_drawing_area()
+0.220201-1 - Dopisanie stalych 0.075 do odjęcia ze źródla wzgldem ramki
+0.220201-0 - Poprawiłem przycinanie dolnych partii zdjęcia po przycięciu. Jednak teraz pojawił się narzut po prawej stronie w wyniku.
+0.229128-1 - Cyrkulacja ramki
+0.220129-0 - Dodałem wyłączenie ramki po przycięciu, przywracanie fotografii do oryginału, po nieudanym przycięciu. Jednak skalowanie ramki nie jest idealne, przy pomniejszonym zaznaczeniu bywa że obcina dół. 
+0.220128-0 - Napisałem wycinanie brzegów, jednak wycina więcej nie wskazuje ramka ! Potrafi przyciąć nogi.
+0.220125-2 - Nieudana propozycja kadrowania
+0.220125-1 - Napisałem przycinane zdjęcia, źle kadruje zdjęcia
+0.220125-0 - Prawidłowe wyliczenie proporcji ramki dla papieru A6
+0.220124-1 - Próba sformatowania ramki o proporcjach 3/2 dla wszystkich rozmiarów fotografii cyfrowych
+0.220124-0 - Poprawiłem odświeżanie ramki po ponownym wczytaniu zdjęcia, skalowana ramka dla wszystkich rozmiarów, jeszcze nie dokładna
+0.220123-2 - Dopisałem przesuwanie ramki za pomocą myszki
+0.220123-1 - Ustawiłem prawidłowe skalowanie ramki dla rozmiarów 10z15 0raz A4 (13x18 - nie dotyczy)
+0.220123-0 - Ramkę można teraz zmniejszać i zwiększać jednak bez ustawionych min. i max.
+0.220122-3 - Dodałem plik makefile oraz desktop, oraz ikone png
+0.220122-2 - Skrypt prawidłowo wyświetla zdjęcia, zarówno poziomo jak i pionowo. Ramka również jest prawidłowo rysowana - poza zdjęciami w formcie 4:3 !
+0.220122-1 - dodałem kompletną ramkę póki co nieruchomą, dodanie przycisków oraz combobox
+0.220122-0 - Zaangażowanie klasy DrawingArea do wyświetlania i rysowania linii, póki co skrypt rysuje pojedynczą linie
+0.220121-0 - Rozpoczęcie projektu, wyświetlenie okna z możliwością wczytania i wyświetlenia fotografii
Binary file photocrop/configure.gz has changed
Binary file photocrop/data/IMG_6854.JPG has changed
Binary file photocrop/data/clip.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/photocrop/data/photocrop.desktop	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,15 @@
+#!/usr/bin/env xdg-open
+
+[Desktop Entry]
+Encoding=UTF-8
+Type=Application
+Categories=Graphics;
+
+Name=Photo Crop
+
+Exec=python3 /usr/bin/photocrop.py
+#Exec=gnome-terminal -e "bash -c 'python3 /usr/bin/photocrop.py;$SHELL'"
+Terminal=false
+Icon=/usr/share/photocrop/clip.png
+
+Name[pl_PL]=Przycinanie Zdjęć
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/photocrop/src/photocrop.py	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,1164 @@
+#!/usr/bin/env python3
+# Photo Crop - photo crop to size app to print in the most popular photo paper sizes
+# author: Przemysław R. Pietraszczyk
+# license: GPL v.2
+# date 21-01-2022
+# editor: Geany
+
+import sys
+import cairo
+import gi, os
+import time
+gi.require_version("Gtk", "3.0")
+from gi.repository import Gtk, GdkPixbuf, Gdk
+from gi.repository.GdkPixbuf import Pixbuf
+
+UI_INFO = """
+<ui>
+  <menubar name='MenuBar'>
+  	<menu action='FileMenu'>
+	  <menuitem action='FileLoad' />
+	  <menuitem action='FileSave' />
+	  <menuitem action='FilePrint' />
+	  <separator />
+	  <menuitem action='FileQuit' />
+	</menu>
+	<menu action='EditMenu'>
+	  <menuitem action='Rotate'/>
+	</menu>
+	<menu action='InfoMenu'>
+	  <menuitem action='Help'/>
+	  <menuitem action='About'/>
+	  <separator />
+	  <menuitem action='License'/>
+	</menu>
+  </menubar>
+
+</ui>
+"""
+
+"""
+# szkielet z podmenu
+<ui>
+  <menubar name='MenuBar'>
+	<menu action='FileMenu'>
+	  <menu action='FileLoad'>
+		<menuitem action='LoadImg' />
+	  </menu>
+	  <menuitem action='FilePrint' />
+	  <separator />
+	  <menuitem action='FileQuit' />
+	</menu>
+	<menu action='InfoMenu'>
+	  <menuitem action='Help'/>
+	  <menuitem action='About'/>
+	</menu>
+  </menubar>
+</ui>
+"""
+
+grid = Gtk.Grid()
+rotate = False
+file_img_selected = ""
+
+def get_resource_path(rel_path):
+	dir_of_py_file = os.path.dirname(__file__)
+	rel_path_to_resource = os.path.join(dir_of_py_file, rel_path)
+	abs_path_to_resource = os.path.abspath(rel_path_to_resource)
+	return abs_path_to_resource
+	
+class FileChooserIMGLoad(Gtk.Window):
+	def __init__(self):
+		Gtk.Window.__init__(self, title="Selection of graphic files")
+		global file_img_selected
+
+		dialog = Gtk.FileChooserDialog(title="Selection of graphic files", parent=self, action=Gtk.FileChooserAction.OPEN)
+		dialog.add_buttons(
+			Gtk.STOCK_CANCEL,
+			Gtk.ResponseType.CANCEL,
+			Gtk.STOCK_OPEN,
+			Gtk.ResponseType.OK,
+		)
+
+		self.add_filters(dialog)
+
+		response = dialog.run()
+		if response == Gtk.ResponseType.OK:
+			print("Open clicked")
+			print("File selected: " + dialog.get_filename())
+			file_img_selected=dialog.get_filename()
+		elif response == Gtk.ResponseType.CANCEL:
+			print("Cancel clicked")	
+		
+		dialog.destroy()
+
+	def add_filters(self, dialog):
+		
+		filter_jpeg = Gtk.FileFilter()
+		filter_jpeg.set_name("Files JPEG")
+		filter_jpeg.add_mime_type("image/jpeg")
+		dialog.add_filter(filter_jpeg)
+
+		filter_png = Gtk.FileFilter()
+		filter_png.set_name("Files PNG")
+		filter_png.add_mime_type("image/png")
+		dialog.add_filter(filter_png)
+		"""
+		filter_png = Gtk.FileFilter()
+		filter_png.set_name("Files TIFF")
+		filter_png.add_mime_type("image/tiff")
+		dialog.add_filter(filter_png)
+		"""
+
+class FileChooserIMGSave(Gtk.Window):
+	def __init__(self):
+		Gtk.Window.__init__(self, title="Save the cropped photo")
+		global file_img_selected
+
+		dialog = Gtk.FileChooserDialog(title="Save the cropped photo", parent=self, action=Gtk.FileChooserAction.SAVE)
+		dialog.add_buttons(
+			Gtk.STOCK_CANCEL,
+			Gtk.ResponseType.CANCEL,
+			Gtk.STOCK_SAVE,
+			Gtk.ResponseType.OK,
+		)
+
+		self.add_filters(dialog)
+
+		response = dialog.run()
+		if response == Gtk.ResponseType.OK:
+			print("Open clicked")
+			print("File selected: " + dialog.get_filename())
+			file_img_selected=dialog.get_filename()
+		elif response == Gtk.ResponseType.CANCEL:
+			print("Cancel clicked")	
+		
+		dialog.destroy()
+
+	def add_filters(self, dialog):
+		
+		filter_jpeg = Gtk.FileFilter()
+		filter_jpeg.set_name("Files JPEG")
+		filter_jpeg.add_mime_type("image/jpeg")
+		dialog.add_filter(filter_jpeg)
+		
+		filter_png = Gtk.FileFilter()
+		filter_png.set_name("Files PNG")
+		filter_png.add_mime_type("image/png")
+		dialog.add_filter(filter_png)
+		"""
+		filter_png = Gtk.FileFilter()
+		filter_png.set_name("Files TIFF")
+		filter_png.add_mime_type("image/tiff")
+		dialog.add_filter(filter_png)
+		"""
+
+
+class DialogWarning(Gtk.Dialog):
+	def __init__(self, parent):
+		Gtk.Dialog.__init__(self, title="Attention!", transient_for=parent, flags=0)
+		self.props.border_width = 20
+		self.add_buttons(
+			Gtk.STOCK_OK, Gtk.ResponseType.OK
+		)
+		self.set_default_size(150, 100)
+		label1 = Gtk.Label(label="The frame is outside the canvas!\n")
+		box = self.get_content_area()
+		box.add(label1)
+		self.show_all()	
+		
+class DialogCropWarning(Gtk.Dialog):
+	def __init__(self, parent):
+		Gtk.Dialog.__init__(self, title="Attention!", transient_for=parent, flags=0)
+		self.props.border_width = 20
+		self.add_buttons(
+			Gtk.STOCK_OK, Gtk.ResponseType.OK
+		)
+		self.set_default_size(150, 100)
+		label1 = Gtk.Label(label="Crop the photo first!\n")
+		box = self.get_content_area()
+		box.add(label1)
+		self.show_all()	
+
+class DialogHelp(Gtk.Dialog):
+	def __init__(self, parent):
+		Gtk.Dialog.__init__(self, title="Help", transient_for=parent, flags=0)
+		self.props.border_width = 20
+		self.add_buttons(
+			Gtk.STOCK_OK, Gtk.ResponseType.OK
+		)
+
+		self.set_default_size(150, 100)
+		label1 = Gtk.Label(label="An application for cropping photos to the most popular\nformats [13x18, 10x15, A4]\n\nScaling the size of the frame - mouse wheel with the CTRL key pressed\nMoving the frame - pressed LMB and moving the mouse\nin the desired direction.")
+		#label2 = Gtk.Label(lanel="")
+		box = self.get_content_area()
+		box.add(label1)
+		#box.add(label2)
+		self.show_all()	
+	
+class DialogAbout(Gtk.Dialog):
+	def __init__(self, parent):
+		Gtk.Dialog.__init__(self, title="About", transient_for=parent, flags=0)
+		self.props.border_width = 20
+		self.add_buttons(
+			Gtk.STOCK_OK, Gtk.ResponseType.OK
+		)
+
+		self.set_default_size(150, 100)
+
+		label = Gtk.Label(label="\tThe application is based on:")
+		box = self.get_content_area()
+		box.add(label)
+		
+		button = Gtk.LinkButton("https://python-gtk-3-tutorial.readthedocs.io/", label="https://python-gtk-3-tutorial.readthedocs.io/")
+		box.add(button)
+
+		label2 = Gtk.Label(label="\n\tVersion: 0.230112-1~alpha\n\n\tPrzemysław R. Pietraszczyk\n\n\t\t  January 2022\n\n\n")
+		box.add(label2)
+		
+
+		button = Gtk.LinkButton("https://prymula.ct8.pl", label="Site")
+		box.add(button)
+
+		self.show_all()
+		
+class DialogLicense(Gtk.Dialog):
+	def __init__(self, parent):
+		Gtk.Dialog.__init__(self, title="License", transient_for=parent, flags=0)
+		self.props.border_width = 20
+		self.add_buttons(
+			Gtk.STOCK_OK, Gtk.ResponseType.OK
+		)
+
+		self.set_default_size(150, 100)
+
+		label = Gtk.Label(label="This program is distributed without any warranty. More information:\n")
+
+		box = self.get_content_area()
+		box.add(label)
+
+		button = Gtk.LinkButton("https://www.gnu.org/licenses/old-licenses/gpl-2.0.html", label="GNU General License version => 2")
+		box.add(button)
+
+		self.show_all()
+		
+class Brush(object):
+
+	default_rgba_color = (0, 0, 0, 1)
+
+	def __init__(self, width=None, rgba_color=None):
+
+		if rgba_color is None:
+			rgba_color = self.default_rgba_color
+
+		if width is None:
+			width = 3
+
+		self.__width = width
+		self.__rgba_color = rgba_color
+		self.__stroke = []
+		self.__current_line = []
+
+	def _line_ended(self):
+		self.__stroke.append(self.__current_line.copy())
+		self.__current_line = []
+
+	def _add_point(self, point):
+		self.__current_line.append(point)
+
+	def _draw(self, cairo_context):
+
+		cairo_context.set_source_rgba(*self.__rgba_color)
+		cairo_context.set_line_width(self.__width)
+		cairo_context.set_line_cap(cairo.LINE_CAP_ROUND)
+
+		cairo_context.new_path()
+		for line in self.__stroke:
+			for x, y in line:
+				cairo_context.line_to(x, y)
+			cairo_context.new_sub_path()
+
+		for x, y in self.__current_line:
+			cairo_context.line_to(x, y)
+
+		cairo_context.stroke()
+
+
+# ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ #
+# ~                          Getters & Setters                            ~ #
+# ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ # 
+
+	def _get_width(self):
+		return self.__width
+
+	def _set_width(self, width):
+		self.__width = width
+
+	def _get_rgba_color(self):
+		return self.__rgba_color
+
+	def _set_rgba_color(self, rgba_color):
+		self.__rgba_color = rgba_color
+
+	def _get_stroke(self):
+		return self.__stroke
+	
+	def _get_current_line(self):
+		return self.__current_line						
+	
+class MyWindow(Gtk.Window):
+
+	def __init__(self):
+		super().__init__()
+
+		self.init_ui()
+	
+	def on_drawing_area_draw(self, drawable, cairo_context):
+		global rotate
+		 
+		start = time.time()
+		self.brush = Brush()
+
+		# DrawingArea size depends on Pixbuf size
+		#self.drawing_area.get_window().resize(self.displayed_pixbuf.get_width(), 
+		#									  self.displayed_pixbuf .get_height())        
+		#self.drawing_area.set_size_request(self.displayed_pixbuf.get_width(), 
+		#								   self.displayed_pixbuf.get_height())
+		
+		
+		# (x, y) offsets
+		pixbuf_x = 0 #int(self.viewport.get_hadjustment().get_value())
+		pixbuf_y = 0 # int(self.viewport.get_vadjustment().get_value())
+
+		# Width and height of the image's clip
+		width = cairo_context.get_target().get_width()
+		height = cairo_context.get_target().get_height()
+	
+		if width > 0 and height > 0:
+
+			# Draw created area of the Sample's Pixbuf
+			Gdk.cairo_set_source_pixbuf(cairo_context, self.pixbuf_view, pixbuf_x, pixbuf_y)
+			
+			cairo_context.paint() 
+			
+			if self.border_visible == True:
+				# Draw brush strokes
+				self.brush._add_point((self.border_x, self.border_y))
+				self.brush._add_point((self.border_width, self.border_y))
+				self.brush._add_point((self.border_width, self.border_y+self.border_height))
+				self.brush._add_point((self.border_x, self.border_y+self.border_height))
+				self.brush._add_point((self.border_x, self.border_y)) # nie działa ?
+
+				self.brush._draw(cairo_context)
+
+		end = time.time()
+		#print(f"Runtime of the program is {end - start}")
+
+
+	def set_ratio_border_size(self):
+		
+		self.border_x = 0
+		self.border_y = 0
+		
+		if self.format_size == "10x15":
+			if self.horizontal == True and self.vertical == False:
+				single = self.picture_view_height*0.5
+				self.border_height = single
+				self.border_width = single*1.4
+				#self.look = "horizontal"
+				#self.border_type = "horizontal"
+			elif self.horizontal == False and self.vertical == True:
+				single = self.picture_view_width*0.5
+				self.border_width = single
+				self.border_height = single*1.4
+				#self.look = "vertical"
+				#self.border_type = "vertical"
+			elif self.horizontal == False and self.vertical == False:
+				self.border_height = self.picture_view_height
+				self.border_width = self.picture_view_width
+			
+		elif self.format_size == "13x18":
+			if self.horizontal == True and self.vertical == False:
+				single = self.picture_view_height*0.5
+				self.border_height = single
+				self.border_width = single*1.42
+			elif self.horizontal == False and self.vertical == True:
+				single = self.picture_view_width*0.5
+				self.border_width = single
+				self.border_height = single*1.42
+			elif self.horizontal == False and self.vertical == False:
+				self.border_height = self.picture_view_height
+				self.border_width = self.picture_view_width
+			
+		elif self.format_size == "A4":
+			if self.horizontal == True and self.vertical == False:
+				single = self.picture_view_height*0.5
+				self.border_height = single
+				self.border_width = single*1.4
+			elif self.horizontal == False and self.vertical == True:
+				single = self.picture_view_width*0.5
+				self.border_width = single
+				self.border_height = single*1.4
+			elif self.horizontal == False and self.vertical == False:
+				self.border_height = self.picture_view_height
+				self.border_width = self.picture_view_width
+		
+		
+		
+	# ustaw proporcje dla obrazu w kontrolce
+	def set_ratio_picture_view(self):
+		self.picture_orig_width = float(self.pixbuf_orig.get_width())
+		self.picture_orig_height = float(self.pixbuf_orig.get_height())
+		#if self.format_size == "10x15":
+		#self.picture_orig_x = 0
+		#self.picture_orig_y = 0
+		
+		if self.picture_orig_width > self.picture_orig_height:
+			self.picture_view_width = 586.66 #600
+			m = self.picture_orig_width / 586.66 #600
+			self.picture_view_height = self.picture_orig_height/m
+		if self.picture_orig_height > self.picture_orig_width:
+			self.picture_view_height = 586.66 #600
+			m = self.picture_orig_height / 586.66 #600
+			self.picture_view_width = self.picture_orig_width/m
+
+		# Zapamiętanie rozmiaru obrazka dla kontrolki
+		self.orig_ratio_width = self.picture_view_width
+		self.orig_ratio_height = self.picture_view_height
+		
+		
+		
+	# ustaw proporcje dla obrazu w kontrolce ppo rotacji
+	def set_ratio_picture_view_after_rotation(self):
+		
+		self.picture_tmp_width = self.border_width - self.border_x
+		self.picture_tmp_height = self.border_height - self.border_y
+		
+		if self.border_x != 0 :
+			bx = self.picture_orig_width / self.border_x
+			crop_x = self.picture_tmp_width / bx
+		else:
+			crop_x = 0
+			
+		if self.border_y != 0:
+			by = self.picture_orig_height / self.border_y
+			crop_y = self.picture_tmp_height / by
+		else:
+			crop_y = 0
+		
+		
+		self.picture_orig_x = crop_x
+		self.picture_orig_y = crop_y
+		"""
+		W zależności jaka była pierwotnie orientacja zdjęcia, po obrocie 
+		jest ono odpowiedio przycinane
+		"""
+		print ("ORIG: "+self.look)
+		if self.look == "vertical":
+			if self.border_type == "horizontal":
+				bw = self.picture_orig_width / (self.border_width - self.border_x)
+				self.picture_tmp_width = self.picture_orig_width / bw - crop_x
+				# w tym wypadku 'y' bez odejmowania gdyż skróciło by to fotografie w pione 
+				bh = self.picture_orig_height / self.border_height
+				self.picture_tmp_height = self.picture_orig_height / bh
+
+			elif self.border_type == "vertical":
+				bw = self.picture_orig_width / (self.border_width - self.border_x)
+				self.picture_tmp_width = self.picture_orig_width / bw - crop_x
+		
+				bh = self.picture_orig_height / (self.border_height - self.border_y)
+				self.picture_tmp_height = self.picture_orig_height / bh
+
+		elif self.look == "horizontal":
+			if self.border_type == "horizontal":
+				bw = self.picture_orig_width / (self.border_width - self.border_x)
+				self.picture_tmp_width = self.picture_orig_width / bw - crop_x
+		
+				bh = self.picture_orig_height / (self.border_height - self.border_y)
+				self.picture_tmp_height = self.picture_orig_height / bh
+
+			elif self.border_type == "vertical":
+				bw = self.picture_orig_width / (self.border_width - self.border_x)
+				self.picture_tmp_width = self.picture_orig_width / bw - crop_x
+		
+				bh = self.picture_orig_height / (self.border_height - self.border_y)
+				self.picture_tmp_height = self.picture_orig_height / bh
+		
+			
+		if self.picture_tmp_width > self.picture_tmp_height:
+			self.picture_view_width = 586.66
+			m = self.picture_tmp_width / 586.66
+			self.picture_view_height = self.picture_tmp_height/m
+		if self.picture_tmp_height > self.picture_tmp_width:
+			self.picture_view_height = 586.66
+			m = self.picture_tmp_height / 586.66
+			self.picture_view_width = self.picture_tmp_width/m
+		
+		# Zapamiętanie rozmiaru obrazka dla kontrolki
+		self.orig_ratio_width = self.picture_view_width
+		self.orig_ratio_height = self.picture_view_height
+		
+	def on_menu_file_load_img_generic(self, widget):
+		global grid, file_img_selected
+
+		filename=FileChooserIMGLoad()
+		
+		if len(file_img_selected) != 0:
+			
+			self.pixbuf_orig = GdkPixbuf.Pixbuf.new_from_file(filename=file_img_selected)
+			
+			self.set_ratio_picture_view()
+			self.pixbuf_view = self.pixbuf_orig.scale_simple(self.picture_view_width, self.picture_view_height, GdkPixbuf.InterpType.HYPER)
+			
+			if self.picture_view_width > self.picture_view_height:
+				self.horizontal = True
+				self.vertical = False
+				self.resize(582.66,413.34)
+				self.look = "horizontal"
+				self.border_type = "horizontal"
+			elif self.picture_view_height > self.picture_view_width:
+				self.vertical = True
+				self.horizontal = False
+				self.resize(413.34,582.66)
+				self.look = "vertical"
+				self.border_type = "vertical"
+			else:
+				self.horizontal = False
+				self.vertical = False
+				
+				
+			self.set_ratio_border_size()
+			
+			
+				
+			self.border_visible = True
+			
+			# nie rysujemy na orginale ale na kopii z okna
+			self.drawing_area.set_size_request(self.pixbuf_view.get_width(), self.pixbuf_view.get_height())
+			self.drawing_area.set_events(Gdk.EventMask.ALL_EVENTS_MASK)
+
+			self.show_all()
+			
+	def add_edit_menu_actions(self, action_group):
+		action_info_menu = Gtk.Action(name="EditMenu", label="Edit")
+		action_group.add_action(action_info_menu)
+
+		action_new = Gtk.Action(
+			name="Rotate",
+			label="Frame rotation",
+			tooltip="Rotate border",
+		)
+		action_new.connect("activate", self.on_menu_rotate)
+		action_group.add_action_with_accel(action_new, None)
+
+		
+	def add_info_menu_actions(self, action_group):
+		action_info_menu = Gtk.Action(name="InfoMenu", label="Info")
+		action_group.add_action(action_info_menu)
+
+		action_new = Gtk.Action(
+			name="Help",
+			label="Help",
+			tooltip="Help",
+		)
+		action_new.connect("activate", self.on_menu_help)
+		action_group.add_action_with_accel(action_new, None)
+
+		action_new = Gtk.Action(
+			name="About",
+			label="About",
+			tooltip="About",
+		)
+		action_new.connect("activate", self.on_menu_about)
+		action_group.add_action_with_accel(action_new, None)
+		
+		action_new = Gtk.Action(
+			name="License",
+			label="License",
+			tooltip="License",
+		)
+		action_new.connect("activate", self.on_menu_license)
+		action_group.add_action_with_accel(action_new, None)
+
+
+		
+	def add_file_menu_actions(self, action_group):
+		action_filemenu = Gtk.Action(name="FileMenu", label="File")
+		action_group.add_action(action_filemenu)
+
+		"""
+		# sposób dodawania podmenu
+		action_fileloadmenu = Gtk.Action(name="FileLoad", stock_id=Gtk.STOCK_OPEN)
+		action_group.add_action(action_fileloadmenu)
+
+		action_new = Gtk.Action(
+			name="LoadImg",
+			label="Wczytaj Obrazek",
+			tooltip="Wczytuje obrazek",
+		)
+		action_new.connect("activate", self.on_menu_file_load_img_generic)
+		action_group.add_action_with_accel(action_new, None)
+		"""
+		
+		action_fileload = Gtk.Action(name="FileLoad", stock_id=Gtk.STOCK_OPEN)
+		action_fileload.connect("activate", self.on_menu_file_load_img_generic)
+		action_group.add_action(action_fileload)
+
+		action_filesave = Gtk.Action(name="FileSave", stock_id=Gtk.STOCK_SAVE)
+		action_filesave.connect("activate", self.on_menu_file_save_img)
+		action_group.add_action(action_filesave)
+		
+		
+		action_print = Gtk.Action(name="FilePrint", stock_id=Gtk.STOCK_PRINT)
+		action_print.connect("activate", self.print_image)
+		action_group.add_action(action_print)
+
+
+		action_filequit = Gtk.Action(name="FileQuit", stock_id=Gtk.STOCK_QUIT)
+		action_filequit.connect("activate", self.on_menu_file_quit)
+		action_group.add_action(action_filequit)
+	
+		
+		
+	# tworzy menu bar
+	def create_ui_manager(self):
+		uimanager = Gtk.UIManager()
+
+		# Throws exception if something went wrong
+		uimanager.add_ui_from_string(UI_INFO)
+
+		# Add the accelerator group to the toplevel window
+		accelgroup = uimanager.get_accel_group()
+		self.add_accel_group(accelgroup)
+		return uimanager
+
+	def on_menu_about(self, widget):
+		dialog = DialogAbout(self)
+		response = dialog.run()
+
+		dialog.destroy()
+		
+	def on_menu_license(self, widget):
+		dialog = DialogLicense(self)
+		response = dialog.run()
+
+		dialog.destroy()
+		
+
+	def on_menu_help(self, widget):
+		dialog = DialogHelp(self)
+		response = dialog.run()
+
+		dialog.destroy()
+		
+	def on_menu_rotate(self, widget):
+		global rotate
+		
+		
+		if self.border_type == "horizontal":
+			self.border_type = "vertical"
+			self.horizontal = False
+			self.vertical = True
+			
+			single = self.picture_view_width*0.3
+			self.border_width = single
+			self.border_height = single*1.4
+			self.border_x = 0
+			self.border_y = 0
+			
+			rotate = True
+			
+		elif self.border_type == "vertical":
+			self.border_type = "horizontal"
+			self.horizontal = True
+			self.vertical = False
+			
+			single = self.picture_view_height*0.3
+			self.border_height = single
+			self.border_width = single*1.4
+			self.border_x = 0
+			self.border_y = 0
+		
+			rotate = True
+		else:
+			pass
+		
+		print ("ASPECT: "+self.border_type)
+		print ("BORDER-WIDTH :"+str(self.border_width))
+		print ("BORDER-HEIGHT:"+str(self.border_height))
+			
+		self.drawing_area.queue_draw()
+
+	def on_menu_file_save_img(self, widget):
+		global file_img_selected
+		
+		if self.pixbuf_tmp != None:
+			filename=FileChooserIMGSave()
+			if len(file_img_selected) != 0:
+				self.pixbuf_view.savev(file_img_selected, "jpeg", ["quality"], ["100"])
+		else:
+			dialog = DialogCropWarning(self)
+			response = dialog.run()
+			
+			dialog.destroy()
+
+	def on_menu_file_quit(self, widget):
+		Gtk.main_quit()
+
+	def print_page(self, operation=None, context=None, page_nr=None):
+		
+		ctx = context.get_cairo_context()
+
+		# make cairo ImageSurface from the png file
+		surface = cairo.ImageSurface.create_from_png('/tmp/photocrop.png')
+		#ctx.rectangle(50,50,100,100)
+		ctx.set_source_surface(surface)
+		ctx.paint ()
+		os.remove("/tmp/photocrop.png");
+		
+
+	def print_image(self, widget):
+		
+		if self.pixbuf_tmp == None:
+			self.pixbuf_tmp = self.pixbuf_orig
+			
+			
+		#	źle obraca
+		#if self.border_type == "horizontal":
+		#	self.pixbuf_tmp.rotate_simple(GdkPixbuf.PixbufRotation.COUNTERCLOCKWISE)
+		#	#pixbuf2.rotate_simple(GdkPixbuf.PixbufRotation.CLOCKWISE)
+		#	self.border_type = "vertical"
+			
+		FACTOR_MM_TO_PIXEL = 2.834645669 
+		
+		
+		if self.format_size == "10x15":
+			#if self.horizontal == True and self.vertical == False:
+			if self.border_type == "horizontal":
+				page_width = 148
+				page_height = 104.99
+				
+				img_height =104.99 * FACTOR_MM_TO_PIXEL
+				img_width = 148 * FACTOR_MM_TO_PIXEL
+			#elif self.horizontal == False and self.vertical == True:
+			elif self.border_type == "vertical":
+
+				page_width = 104.99
+				page_height = 148
+				
+				img_width =104.99 * FACTOR_MM_TO_PIXEL
+				img_height = 148 * FACTOR_MM_TO_PIXEL
+				
+			size = "10x15"
+		elif self.format_size == "13x18":
+			#if self.horizontal == True and self.vertical == False:
+			if self.border_type == "horizontal":
+
+				page_width = 178 
+				page_height = 127 
+				
+				img_height = 127 * FACTOR_MM_TO_PIXEL 
+				img_width = 178 * FACTOR_MM_TO_PIXEL 
+			#elif self.horizontal == False and self.vertical == True:
+			elif self.border_type == "vertical":
+
+				page_width = 127 
+				page_height = 178 
+				
+				img_width = 127 * FACTOR_MM_TO_PIXEL 
+				img_height = 178 * FACTOR_MM_TO_PIXEL 
+			size = "5x7"
+		elif self.format_size == "A4":
+			#if self.horizontal == True and self.vertical == False:
+			if self.border_type == "horizontal":
+				page_width = 297
+				page_height = 207
+				
+				img_height = 207 * FACTOR_MM_TO_PIXEL
+				img_width = 297 * FACTOR_MM_TO_PIXEL
+			#elif self.horizontal == False and self.vertical == True:
+			elif self.border_type == "vertical":
+
+				page_width = 207
+				page_height = 297
+				
+				img_width = 207 * FACTOR_MM_TO_PIXEL
+				img_height = 297 * FACTOR_MM_TO_PIXEL
+				
+			size = "A4"
+			
+		dpi = 600
+
+		# z orginalnymi wielkościami nie chce drukowac
+		pixbuf2 = self.pixbuf_tmp.scale_simple(img_width, img_height, GdkPixbuf.InterpType.HYPER)
+
+		pixbuf2.savev("/tmp/photocrop.png","png", ["quailty"], ["100"])
+		
+		#ps = Gtk.PaperSize.new_custom(size, size, self.pixbuf_tmp.get_width(), self.pixbuf_tmp.get_height(), Gtk.Unit.POINTS)
+		ps = Gtk.PaperSize.new_custom(size, size, page_width, page_height, Gtk.Unit.MM)
+
+		print_settings = Gtk.PrintSettings()
+		print_settings.set_resolution(dpi)
+
+		page_setup = Gtk.PageSetup()
+		page_setup.set_paper_size(ps)
+		page_setup.set_bottom_margin(0.0, Gtk.Unit.MM)
+		page_setup.set_left_margin(0.0, Gtk.Unit.MM)
+		page_setup.set_right_margin(0.0, Gtk.Unit.MM)
+		page_setup.set_top_margin(0.0, Gtk.Unit.MM)
+		
+		#if self.border_type == "horizontal":
+		#	page_setup.set_orientation(Gtk.PageOrientation.LANDSCAPE)
+		#elif self.border_type == "vertical":
+		# page_setup.set_orientation(Gtk.PageOrientation.PORTRAIT)
+
+
+		print_operation = Gtk.PrintOperation()
+		print_operation.set_unit(Gtk.Unit.POINTS)
+		print_operation.set_n_pages(1)
+		print_operation.set_default_page_setup(page_setup)
+		print_operation.set_print_settings(print_settings)
+		print_operation.connect("draw_page", self.print_page)
+		#print_operation.set_export_filename("example.pdf")
+
+		result = print_operation.run(Gtk.PrintOperationAction.PRINT_DIALOG, None) # window zamisat None
+
+		#result = print_operation.run(Gtk.PrintOperationAction.PREVIEW, None)
+		print(result)
+
+	# przycinamy !
+	def photo_crop(self, button):
+		
+		if self.border_x < 0:
+			dialog = DialogWarning(self)
+			response = dialog.run()
+			dialog.destroy()
+			return
+		if self.border_y < 0:
+			dialog = DialogWarning(self)
+			response = dialog.run()
+			dialog.destroy()
+			return
+		if self.border_width > self.picture_view_width:
+			dialog = DialogWarning(self)
+			response = dialog.run()
+			dialog.destroy()
+			return
+		# FIXME - w sumie to jest zastanawiające !?
+		if self.border_height + self.border_y > self.picture_view_height:
+			dialog = DialogWarning(self)
+			response = dialog.run()
+			dialog.destroy()
+			return
+		
+		
+		if self.border_x != 0 :
+			bx = self.picture_view_width / self.border_x
+			crop_x = self.picture_orig_width / bx
+		else:
+			crop_x = 0
+			
+		if self.border_y != 0:
+			by = self.picture_view_height / self.border_y
+			crop_y = self.picture_orig_height / by
+		else:
+			crop_y = 0
+
+		bw = self.picture_view_width / self.border_width
+		crop_width = self.picture_orig_width / bw - crop_x
+		
+		bh = self.picture_view_height / self.border_height
+		crop_height = self.picture_orig_height / bh
+		
+		
+		# False - kanał Alpha
+		self.pixbuf_tmp = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, False, 8, crop_width, crop_height)
+
+		# zera na koncu to dest_x i dest_y
+		self.pixbuf_orig.copy_area(crop_x, crop_y, crop_width, crop_height, self.pixbuf_tmp, 0, 0)
+
+		if rotate == False:
+			
+			self.picture_tmp_width = float(self.pixbuf_tmp.get_width())
+			self.picture_tmp_height = float(self.pixbuf_tmp.get_height())
+
+			# tym razem przeliczamy z uwzględnieniem bufora tymczasowego
+			if self.picture_tmp_width > self.picture_tmp_height:
+				self.picture_view_width = 586.66
+				m = self.picture_tmp_width / 586.66
+				self.picture_view_height = self.picture_tmp_height/m
+			if self.picture_tmp_height > self.picture_tmp_width:
+				self.picture_view_height = 586.66
+				m = self.picture_tmp_height / 586.66
+				self.picture_view_width = self.picture_tmp_width/m
+				
+				
+
+		else:
+			self.set_ratio_picture_view_after_rotation()
+	
+		self.drawing_area.set_size_request(self.picture_view_width, self.picture_view_height)
+		self.drawing_area.set_events(Gdk.EventMask.ALL_EVENTS_MASK)
+	
+		self.pixbuf_view = self.pixbuf_tmp.scale_simple(self.picture_view_width, self.picture_view_height, GdkPixbuf.InterpType.HYPER)
+
+		self.picture_view_x = 0
+		self.picture_view_y = 0
+
+		self.border_visible = False
+
+		self.drawing_area.queue_draw()
+
+	# przywracamy
+	def photo_restore(self, button):
+		
+		self.border_visible = True
+		
+		self.set_ratio_picture_view()		
+		self.pixbuf_view = self.pixbuf_orig.scale_simple(self.orig_ratio_width, self.orig_ratio_height, GdkPixbuf.InterpType.BILINEAR)
+
+		self.drawing_area.set_size_request(self.orig_ratio_width, self.orig_ratio_height)
+		self.drawing_area.set_events(Gdk.EventMask.ALL_EVENTS_MASK)
+		self.pixbuf_tmp = None # uniemożliwiamy zapis
+		self.show_all()
+
+		self.drawing_area.queue_draw()
+		
+
+	def on_format_combo_changed(self, combo):
+		tree_iter = combo.get_active_iter()
+		if tree_iter is not None:
+			model = combo.get_model()
+			self.format_size = model[tree_iter][0]
+			print("Selected: format=%s" % self.format_size)
+			
+			self.set_ratio_border_size()
+				
+			self.drawing_area.queue_draw()
+
+	def on_scroll(self, widget, event):
+		""" handles on scroll event"""
+		# Handles zoom in / zoom out on Ctrl+mouse wheel
+		accel_mask = Gtk.accelerator_get_default_mod_mask()
+		if event.state & accel_mask == Gdk.ModifierType.CONTROL_MASK:
+			direction = event.get_scroll_deltas()[2]
+			
+			if direction > 0:
+				scrolling = "zoom_out"
+			else:
+				scrolling = "zoom_in"
+			
+			self.border_height += self.border_properties[self.format_size][self.border_type][scrolling]["height"]
+			self.border_width += self.border_properties[self.format_size][self.border_type][scrolling]["width"]
+			"""
+			# tu jest jakiś błąd
+			if self.border_width > self.picture_view_width:  
+				self.border_width -= 1
+			if self.border_height+self.border_y > self.picture_view_height:
+				self.border_height -= 1
+			"""
+			self.drawing_area.queue_draw()
+			
+	def unclick_in_drawing_area (self, box, event):
+		self.button_press = False
+		print ("Przycisk myszki puszczony")
+
+	
+	def onclick_in_drawing_area (self, box, event):
+		if event.button == 1:
+			self.button_press = True
+			print ("Lewy przyciski myszki naciśnięty")
+			
+	def on_mouse_move_in_drawing_area(self, box, event):
+
+		
+		if self.button_press == True:
+			
+			if self.border_type == "vertical":
+				
+				#print ("VERTICAL  %%")
+				
+				if self.last_x < event.x:
+					self.border_x += 1
+					self.border_width += 1
+				if event.x < self.last_x:
+					self.border_x -= 1
+					self.border_width -= 1
+				if self.last_y < event.y:
+					self.border_y += 1
+					self.border_height += 0.0
+				if event.y < self.last_y:
+					self.border_y -= 1
+					self.border_height -= 0.0
+			
+			elif self.border_type == "horizontal":
+				#print ("Horizontal %%")
+				if self.last_x < event.x:
+					self.border_x += 1
+					self.border_width += 1
+				if event.x < self.last_x:
+					self.border_x -= 1.
+					self.border_width -= 1
+				if self.last_y < event.y:
+					self.border_y += 1
+					self.border_height += 0.0
+				if event.y < self.last_y:
+					self.border_y -= 1
+					self.border_height -= 0.0
+
+			self.last_y = event.y
+			self.last_x = event.x		
+			"""
+			# jeśli będzie się napierać na skraj krawędzi wówczas powiększa ramkę
+			if self.border_x < 0:
+				self.border_x += 1
+				self.border_width += 1
+			if self.border_y < 0:
+				self.border_y += 1
+				self.border_height +=1
+			# tu jest jakiś błąd
+			
+			# powoduje błędne zachowanie ramki
+			if self.border_type == "vertical":
+				if self.border_width > self.picture_view_width:
+					self.border_width -= 1
+					self.border_x -= 1
+				if self.border_height+self.border_y > self.picture_view_height:
+					self.border_height -= 1
+					self.border_y -= 1
+			elif self.border_type == "horizontal":
+				if self.border_height+self.border_y> self.picture_view_width:
+					self.border_width -= 1
+					self.border_x -= 1
+				if self.border_width > self.picture_view_height:
+					self.border_height -= 1
+					self.border_y -= 1
+			"""
+
+			self.drawing_area.queue_draw()
+			
+	def init_ui(self):
+		# JPG akceptuje jedynie z GIMPa
+		self.border_properties = { "10x15" : { "horizontal" : { "zoom_out" : {"width" : -1.48, "height" : -0.92}, "zoom_in" : {"width" : 1.48, "height" : 0.92}},
+			"vertical" : { "zoom_out": { "width" : -0.92, "height" : -1.48}, "zoom_in": { "width" : 0.92, "height" : 1.48}},
+			"square" : { "zoom_out" : { "width" : -1, "height" : -1}, "zoom_out" : { "width" : 1, "height" : 1}}},
+				
+			"13x18" : { "horizontal" : { "zoom_out" : {"width" : -1.82, "height" : -1.30}, "zoom_in" : {"width" : 1.82, "height" : 1.30}},
+			"vertical" : { "zoom_out": { "width" : -1.30, "height" : -1.78}, "zoom_in": { "width" : 1.30, "height" : 1.78}},
+			"square" : { "zoom_out" : { "width" : -1, "height" : -1}, "zoom_out" : { "width" : 1, "height" : 1}}},
+				
+			"A4" : { "horizontal" : { "zoom_out" : {"width" : -2.97, "height" : -1.84}, "zoom_in" : {"width" : 2.97, "height" : 1.84}},
+			"vertical" : { "zoom_out": { "width" : -1.84, "height" : -2.97}, "zoom_in": { "width" : 1.84, "height" : 2.97}},
+			"square" : { "zoom_out" : { "width" : -1, "height" : -1}, "zoom_out" : { "width" : 1, "height" : 1}}}}
+				
+	
+		#self.props.border_width = 20
+		self.add(grid)
+		self.pixbuf_tmp = None
+		grid.set_row_spacing(10)
+		grid.set_column_spacing(10)
+		grid.set_column_homogeneous(True) # rozszerza kontrolki na resztę okna
+		
+		action_group = Gtk.ActionGroup(name="my_actions")
+
+		self.add_file_menu_actions(action_group)
+		self.add_edit_menu_actions(action_group)
+		self.add_info_menu_actions(action_group)
+		
+		uimanager = self.create_ui_manager()
+		uimanager.insert_action_group(action_group)
+
+		menubar = uimanager.get_widget("/MenuBar")
+		box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
+		box.pack_start(menubar, False, False, 0)
+		
+		grid.attach(box, 0, 0, 3, 1)
+		
+		
+		file_img_selected=get_resource_path("/usr/share/photocrop/IMG_6854.JPG") #img/blank.png
+		self.pixbuf_orig = GdkPixbuf.Pixbuf.new_from_file(filename=file_img_selected)
+		
+		self.format_size = "10x15"
+		self.set_ratio_picture_view()
+		self.pixbuf_view = self.pixbuf_orig.scale_simple(self.picture_view_width, self.picture_view_height, GdkPixbuf.InterpType.HYPER)
+		
+		self.border_visible = True
+		
+		if self.picture_view_width > self.picture_view_height:
+			self.horizontal = True
+			self.vertical = False
+			self.look = "horizontal"
+			self.border_type = "horizontal"
+		elif self.picture_view_height > self.picture_view_width:
+			self.vertical = True
+			self.horizontal = False
+			self.look = "vertical"
+			self.border_type = "vertical"
+		else:
+			self.horizontal = False
+			self.vertical = False
+			self.look = "square"
+				
+		self.drawing_area = Gtk.DrawingArea()
+
+		self.drawing_area.set_size_request(self.pixbuf_view.get_width(), self.pixbuf_view.get_height())
+		self.drawing_area.set_events(Gdk.EventMask.ALL_EVENTS_MASK)
+		
+		self.drawing_area.connect("draw", self.on_drawing_area_draw)
+
+		frame = Gtk.Frame()
+		event_box  = Gtk.EventBox ()
+		self.last_x = 1
+		self.last_y = 1
+		self.border_x = 0
+		self.border_y = 0
+		self.button_press = False
+		self.pixbuf_tmp = None
+		event_box.connect ('button-press-event', self.onclick_in_drawing_area)
+		event_box.connect ('button-release-event', self.unclick_in_drawing_area)
+		event_box.connect("motion-notify-event", self.on_mouse_move_in_drawing_area)
+		event_box.add_events(Gdk.EventMask.POINTER_MOTION_MASK | Gdk.EventMask.BUTTON_PRESS_MASK)
+
+		event_box.add(self.drawing_area)
+		frame.add(event_box)
+		grid.attach(frame,0,1,3,1) 
+
+		button1 = Gtk.Button.new_with_label("Crop")
+		button1.connect("clicked", self.photo_crop)
+		grid.attach(button1,0,4,1,1)
+		
+		button2 = Gtk.Button.new_with_label("Restore")
+		button2.connect("clicked", self.photo_restore)
+		grid.attach(button2,1,4,1,1)
+		
+		format_store = Gtk.ListStore(str)
+		format_photo = [
+			"10x15",
+			"13x18",
+			"A4",
+		]
+		for fp in format_photo:
+			format_store.append([fp])
+
+		format_combo = Gtk.ComboBox.new_with_model(format_store)
+		format_combo.connect("changed", self.on_format_combo_changed)
+		renderer_text = Gtk.CellRendererText()
+		format_combo.pack_start(renderer_text, True)
+		format_combo.add_attribute(renderer_text, "text", 0)
+		format_combo.set_active(0)
+		grid.attach(format_combo,2,4,1,1)
+
+		self.drawing_area.connect('scroll-event', self.on_scroll)
+
+		self.set_border_width(10)
+		self.set_title("Photo Crop (alpha)")
+		#self.set_default_size(700, 600)
+		#self.resize(700, 600)
+		self.set_resizable(False)
+		self.connect("destroy", Gtk.main_quit)
+	
+	
+	
+win = MyWindow()
+win.show_all()
+Gtk.main()
Binary file photocrop/xcf/clip.xcf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/postagelabels/DEBIAN/HOWTO.txt	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,2 @@
+foramt zapisu nazwy pliku:
+	photocrop_0.221225-0~alpha.tar.gz
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/postagelabels/DEBIAN/debian.changelog	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,5 @@
+photocrop (0.220120-2~beta) unstable; urgency=low
+
+  * Last release
+
+ -- Przemysław R. Pietraszczyk  Sat, 25 Dec 2022 08:31:41 +0200
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/postagelabels/DEBIAN/debian.control	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,13 @@
+Source: postagelabels
+Section: python
+Priority: extra
+Maintainer: Przemysław R. Pietraszczyk
+Build-Depends: debhelper-compat (= 13), python3-all, python-setuptools, dh-python, python3-gi, python3-gi-cairo, gir1.2-gtk-3.0, fakeroot
+Standards-Version: 0.220120-2~beta
+Homepage: http://pietraszczyk.vxm.pl
+
+
+Package: postagelabels
+Architecture: all
+Depends: ${misc:Depends}, python3-all, python3-gi, python3-gi-cairo, gir1.2-gtk-3.0
+Description: An application for cropping photos to popular paper sizes.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/postagelabels/DEBIAN/debian.rules	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,25 @@
+#!/usr/bin/make -f
+
+export DH_VERBOSE = 1
+
+clean:
+	@
+	
+build:
+	@
+
+binary:
+	mkdir -pm 0755 debian/postagelabels
+	mkdir -pm 0755 debian/postagelabels/usr
+	mkdir -pm 0755 debian/postagelabels/usr/bin
+	mkdir -pm 0755 debian/postagelabels/usr/share
+	mkdir -pm 0755 debian/postagelabels/usr/share/postagelabels
+	mkdir -pm 0755 debian/postagelabels/usr/share/applications
+	cp postagelabels.py debian/postagelabels/usr/bin
+	cp png/postagelabels.png debian/postagelabels/usr/share/postagelabels
+	cp png/blank_small.png debian/postagelabels/usr/share/postagelabels
+	cp png/szablon.png debian/postagelabels/usr/share/postagelabels
+	cp postagelabels.desktop debian/postagelabels/usr/share/applications
+	dh_gencontrol
+	dh_builddeb
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/postagelabels/DEBIAN/format.sh	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,1 @@
+exec /usr/lib/build/debtransform ./ ./photocrop.dsc ./exec
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/postagelabels/DEBIAN/photocrop.dsc	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,41 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA256
+
+Format: 1.0
+Source: postagelabels
+Binary: postagelabels
+Architecture: all
+Version: 0.220120-2~beta
+Maintainer: Przemysław R. Pietraszczyk <przem@pietraszczyk.vxm.pl>
+Homepage: http://pietraszczyk.vxm.pl
+DEBTRANSFORM-TAR: debian.tar.gz
+DEBTRANSFORM-TAR: postagelabels_0.220120-2~beta.tar.gz
+ 
+Standards-Version: 0.220120-2~beta
+Build-Depends: debhelper-compat (= 13), python3-all, python-setuptools, dh-python, python3-gi, python3-gi-cairo, gir1.2-gtk-3.0, fakeroot
+Package-List:
+ photocrop deb x11 optional arch=all
+Files:
+ b31649bc23b2b7bca9ab70ea3410711a 128820 postagelabels_0.220120-2~beta.tar.gz
+ 29e7e7e60bc81891e3da3871b9eeb549 764 postagelabels-0.220120-2~beta.debian.tar.xz
+
+-----BEGIN PGP SIGNATURE-----
+
+mQENBGEf/c4BCAC2d4ymW0pRZV36qLtlt/WGb83kos5UX5UbwvkQrbUjAbOPOY8w
+DT3M1neYOAPZx38924aPTFKbZPcz+rK/7Wcv1kzgfux5zXQJTLeqpkhUYAgXUg2p
+oK9ZXsai82fOicTrClOyJLLYQ8C1vj8yUh7e3ERljEyp5Nxg/lY92rwcZ4WYR193
+nGDInlDl5JlWUcLlk/RFnC5bB+T6ZZr5FBX/eDnKAPEl+N3MWpDs2JLDy7EUPhcG
+U/60X0wuXHPTwMoNbB3ep/bWRxwEej0sFad5GXeCh7hKCroi/kLmLTDIxSD8lsRr
+Y4H/8H2lBBsQq7bRL88N6ZDGCocPo11V83kFABEBAAG0NmhvbWU6cHJ6ZW0gT0JT
+IFByb2plY3QgPGhvbWU6cHJ6ZW1AYnVpbGQub3BlbnN1c2Uub3JnPokBPgQTAQgA
+KAUCYR/9zgIbAwUJBB6wAAYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQcXEc
+NPcNefFEAAf+Kg4cs/C99kEIMv/PO85VW+p8rcTwCViOFUX5WrBhwsRyPAKrJPPG
+KD6PdnvoplcNQwhQ8nRsRiiaiUtPcj8Bvi6EdPgSgXXObKKJtCyaAa1rURdlb9iW
+CfvXA6oW+PGlii9BMnXOAtkeFIzZooO9oXd+wez66P+4VWFiFzxanLfLn/hwbWxQ
+68rlO3QNGbrMeODBgwh9s83XGmAg47mn2fldTAmTbJDf9tMi1LhX2MmLyN9wjqsd
+4IZ9JMri2JTnIhYfxWdKT9gsu7q0g8LqonaXMvlOEyHFRF1YQ0i7G6fFbvDcKCZN
+W1Eja55FdN7smv5Eck6UTIIYyWPuAv45uohGBBMRAgAGBQJhH/3PAAoJEDswEbdr
+nWUj4M0AniJ389dyvUjjgS91AcOb08E4moV9AJ9WDL3/7GYYUL/Azw43QucWPnXr
+uw==
+=+lfH
+-----END PGP SIGNATURE-----
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/postagelabels/RPM/postagelabels.spec	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,69 @@
+#
+# spec file for package postagelabels
+#
+# Copyright (c) 2020 SUSE LLC
+#
+# All modifications and additions to the file contributed by third parties
+# remain the property of their copyright owners, unless otherwise agreed
+# upon. The license for this file, and modifications and additions to the
+# file, is the same license as for the pristine package itself (unless the
+# license for the pristine package is not an Open Source License, in which
+# case the license is the MIT License). An "Open Source License" is a
+# license that conforms to the Open Source Definition (Version 1.9)
+# published by the Open Source Initiative.
+
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
+#
+
+%define unmangled_version 0.220120-2~beta
+Name:       postagelabels
+Version:	0.220120
+Release:    	2~beta
+Summary:	Grid and print postal labels.
+License:	GPL
+URL:		http://prp.xlx.pl
+Source0:	%{name}-%{unmangled_version}.tar.gz
+%if 0%{?suse_version}==1530
+BuildRequires:	python3, python3-gobject, python3-gobject-Gdk, typelib-1_0-Gtk-3_0, libgtk-3-0
+Requires:       python3, python3-gobject, python3-gobject-Gdk, typelib-1_0-Gtk-3_0, libgtk-3-0
+%else
+BuildRequires:	python3, python3-gobject, gtk3
+Requires:		python3, python3-gobject, gtk3
+%endif
+BuildArch:	noarch
+
+%description
+
+
+%prep
+%setup -n %{name}-%{unmangled_version} -n %{name}-%{unmangled_version}
+
+%build
+
+%install
+
+mkdir -p %{buildroot}/usr
+mkdir -p %{buildroot}/usr/share
+mkdir -p %{buildroot}/usr/share/postagelabels
+mkdir -p %{buildroot}/usr/share/applications
+mkdir -p %{buildroot}/usr/bin
+
+install -m 0755 postagelabels.py %{buildroot}/usr/bin
+install -m 0644 png/postagelabels.png %{buildroot}/usr/share/postagelabels/postagelabels.png
+install -m 0644 png/blank_small.png %{buildroot}/usr/share/postagelabels/blank_small.png
+install -m 0644 png/szablon.png %{buildroot}/usr/share/postagelabels/szablon.png
+install -m 0644 postagelabels.desktop %{buildroot}/usr/share/applications
+
+
+
+%files
+%defattr(0755,root,root)
+/usr/bin/postagelabels.py
+/usr/share/postagelabels/
+%defattr(0644,root,root)
+/usr/share/postagelabels/postagelabels.png
+/usr/share/postagelabels/blank_small.png
+/usr/share/postagelabels/szablon.png
+/usr/share/applications/postagelabels.desktop
+
+%changelog
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/postagelabels/changelog.txt	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,63 @@
+0.220120-0 - kolejna zmiana numeracji, zabezpieczyłem odczyt anulowanej etykiety oraz wyjustowałem prawidłowo etykiety na siatce
+
+0.30-0 - dopisałem nadpisywanie siatki nowym szablonem
+
+0.29-0 - dodanie odstępów w kreatorze etykiet, dodanie pliku makefile
+
+0.28-0 - kosmetyka, czyszcenie kodu
+
+0.27-0 - utworzoną etykietę skrypt zapisuje i dodaje do listy dostępnych etykiet
+
+0.26-0 - zmiana numeracji, dodanie okna dialogowego z zapisem (póki co jeszcze nie zapisuje), dodanie przycisku "wyczyć" w kompozytorze
+
+0.0-25 - dodanie kompozytora etykiet, póki co kompozycja w oknie
+
+0.0-24 - kosmetyka
+
+0.0-23 – powrót do skalowania obrazu przed drukowaniem
+
+0.0-22 – dodałem ‘self.show_all()’ w funkcji ‘onclick_in_pixbuf’ zobaczymy czy pomoże na odświeżanie siatki po dodaniu do niej etykiety.
+
+0.0-21 – przymiarki do pakietowania, po instalacji pakietu okazało się że nie odświeża siatki i nie widać dodawanych etykiet. 
+
+0.0-20 - sprawdziłem jak skrypt zachowuje się w SUSE - efekt taki że do funkcji savev dodałem jeszcze dwa argumenty nt. jakości obrazu
+
+0.0-19 – ładnie ustawia etykiety na stronie do wydruku, jednak nie drukuje bezpośrednio. Należy najpierw zapisać plik PDF do wydruku. Póki co brakuje kompozytora etykiet. 
+
+0.0-18 – poprawiłem nieco ułożenie etykiet na docelowym płótnie, jednak wynik jest inny od oczekiwanego. Na skrajnych górnych pozycjach myszki na najniższej siatce kiepsko odczytuje jej położenie.
+
+0.0-17 – drukuje etykiety ułożone w siatkę, jednak trzeba uwzględnić marginesy z kartki ‘Galerii Papieru’
+
+0-0.16 – przygotowuje prawidłowy plik do druku, jednak drukuje w znacznym powiększeniu
+
+0.0-15 – drukuje ale pojedynczą etykietę, oraz znacznie powiększoną 
+
+0.0-14 – przygotowano możliwość druku, ale nie drukuje – efekt pustej strony
+
+0.0-13 – dodano listę z danymi do druku 
+
+0.0-12 – wyświetla okno dialogowe z informacją w przypadku braku zaznaczenia z listy dostępnych etykiet. Modyfikacje przy liście dostępnych etykiet – błąd krytyczny naprawiony, odświeżanie kontrolki również. 
+
+0.0-11 – usiłuje wydrukować przykładowy obrazek – bez skutku
+
+0.0-10 – poprawiłem punkty odniesienia. Prawidłowo umieszcza i kasuje etykiety na siatce
+
+0.0-9 – wyświetla w siatce etykiety, po wcześniejszym zaznaczeniu na liście
+
+0.0-8 – pola dla etykiet w siatce po prawej są pozycjonowane „równo”, są kłopoty z właściwym wyświetleniem etykiety po naciśnięciu lewego przycisku myszy
+
+0.0-7 – wyświetla poszczególne etykiety w siatce po prawej stronie, ale nie równo.
+
+0.0-6 – podzieliłem główny obrazek po prawej stronie na części
+
+0.0-5 – rysuje zaznaczenie na self.image1, jednak kasując całkowicie poprzedni obraz. Robiąc przy okazji roszadę w ui.
+
+0.0-4 – odczytuje pozycje myszy na self.image1 po naciśnięciu klawisza myszy
+
+0.0-3 – nieśmiała przymiarka do drag and drop -nieudana 
+
+0.0-2 – zaznaczenie nazwy etykiety z listy, zmienia obraz etykiety
+
+0,0-1 – dodałem wczytywanie etykiety, wyświetlenia jej w polu, oraz dodanie nazwy etykiety do listy, znajdującej się poniżej wizerunku etykiety.
+
+0.0-0 – inicjacja.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/postagelabels/makefile	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,22 @@
+
+prefix=/usr
+
+install:
+	mkdir -pm 0755 $(prefix)/share/postagelabels
+	install -m 0755 postagelabels.py $(prefix)/bin
+	install -m 0644 png/postagelabels.png $(prefix)/share/postagelabels
+	install -m 0644 png/blank_small.png $(prefix)/share/postagelabels
+	install -m 0644 png/szablon.png $(prefix)/share/postagelabels
+	install -m 0644 postagelabels.desktop /usr/share/applications
+
+.PHONY: install
+
+uninstall:
+	rm $(prefix)/share/postagelabels/postagelabels.png
+	rm $(prefix)/share/postagelabels/blank_small.png
+	rm $(prefix)/share/postagelabels/szablon.png
+	rmdir $(prefix)/share/postagelabels/
+	rm $(prefix)/bin/postagelabels.py
+	rm /usr/share/applications/postagelabels.desktop
+	
+.PHONY: uninstall
Binary file postagelabels/png/blank_small.png has changed
Binary file postagelabels/png/postagelabels.png has changed
Binary file postagelabels/png/szablon.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/postagelabels/postagelabels.desktop	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,15 @@
+#!/usr/bin/env xdg-open
+
+[Desktop Entry]
+Encoding=UTF-8
+Type=Application
+Categories=Office;
+
+Name=Postage Labels
+
+Exec=python3 /usr/bin/postagelabels.py
+#Exec=gnome-terminal -e "bash -c 'python3 /usr/bin/postagelabels.py;$SHELL'"
+Terminal=false
+Icon=/usr/share/postagelabels/postagelabels.png
+
+Name[pl_PL]=Naklejki Pocztowe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/postagelabels/postagelabels.py	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,1012 @@
+#!/usr/bin/env python3
+# Postage Labels - aplikacja do aranżacji wydruków etykiet pocztowych
+# autor: Przemysław R. Pietraszczyk
+# licencja: GPL
+# data 20-IX-2021
+# edytor: Geany
+
+import sys
+import cairo
+import gi, os
+gi.require_version("Gtk", "3.0")
+from gi.repository import Gtk, GdkPixbuf, Gdk
+from gi.repository.GdkPixbuf import Pixbuf
+
+
+UI_INFO = """
+<ui>
+  <menubar name='MenuBar'>
+    <menu action='FileMenu'>
+      <menu action='FileLoad'>
+        <menuitem action='NewTemplate' />
+        <menuitem action='LoadImg' />
+        <menuitem action='Composite' />
+      </menu>
+      <menuitem action='FilePrint' />
+      <separator />
+      <menuitem action='FileQuit' />
+    </menu>
+    <menu action='InfoMenu'>
+      <menuitem action='Help'/>
+      <menuitem action='About'/>
+    </menu>
+  </menubar>
+
+</ui>
+"""
+
+grid = Gtk.Grid()
+file_img_selected=""
+file_label_save=""
+new_pixbuf=""
+list_labels = []
+label_limits = []
+print_limits = []
+#label_selected = ""
+BLANK_W = 1134
+BLANK_H = 496
+
+
+def get_resource_path(rel_path):
+	dir_of_py_file = os.path.dirname(__file__)
+	rel_path_to_resource = os.path.join(dir_of_py_file, rel_path)
+	abs_path_to_resource = os.path.abspath(rel_path_to_resource)
+	return abs_path_to_resource
+
+class DialogCompositor(Gtk.Dialog):
+	def __init__(self, parent):
+		global new_pixbuf
+		Gtk.Dialog.__init__(self, title="Kompozytor", transient_for=parent, flags=0)
+		self.props.border_width = 20
+		self.add_buttons(
+			Gtk.STOCK_CANCEL,
+			Gtk.ResponseType.CANCEL,
+			Gtk.STOCK_SAVE,
+			Gtk.ResponseType.OK,
+		)
+		self.compos = Gtk.Grid()
+		file_img_composite=get_resource_path("/usr/share/postagelabels/blank_small.png")
+		new_pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
+			filename=file_img_composite,
+			width=500,
+			height=250,
+			preserve_aspect_ratio=True)
+
+		self.add(self.compos)
+
+		self.compos.set_row_spacing(10)
+		self.compos.set_column_spacing(10)
+		#self.compos.set_column_homogeneous(True) # rozszerza kontrolke na resztę okna
+		
+		# potrzebne do wyśwetlenia tekstu
+		self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, new_pixbuf.get_width(), new_pixbuf.get_height())
+		self.context = cairo.Context(self.surface)
+
+		Gdk.cairo_set_source_pixbuf(self.context, new_pixbuf, 0, 0)
+		self.context.paint() #paint the pixbuf
+
+		self.fontsize= 25
+		
+		box = self.get_content_area()
+
+		self.com_first = Gtk.Image.new_from_pixbuf(new_pixbuf)
+		self.compos.attach(self.com_first,0,0,1,3)
+		
+		
+		self.entry1 = Gtk.Entry()
+		self.entry1.set_text("Hello World")
+		self.compos.attach(self.entry1,1,0,1,1)
+
+		
+		self.entry2 = Gtk.Entry()
+		self.entry2.set_text("Hello World")
+		self.compos.attach(self.entry2,1,1,1,1)
+		
+		self.entry3 = Gtk.Entry()
+		self.entry3.set_text("Hello World")
+		self.compos.attach(self.entry3,1,2,1,1)
+		
+		self.entry4 = Gtk.Entry()
+		self.entry4.set_text("Hello World")
+		self.compos.attach(self.entry4,1,3,1,1)
+		
+		button1 = Gtk.Button.new_with_label("Aktualizuj")
+		button1.connect("clicked", self.actualization1)
+		self.compos.attach(button1,2,0,1,1)
+		
+		button2 = Gtk.Button.new_with_label("Aktualizuj")
+		button2.connect("clicked", self.actualization2)
+		self.compos.attach(button2,2,1,1,1)
+		
+		button3 = Gtk.Button.new_with_label("Aktualizuj")
+		button3.connect("clicked", self.actualization3)
+		self.compos.attach(button3,2,2,1,1)
+
+		button4 = Gtk.Button.new_with_label("Aktualizuj")
+		button4.connect("clicked", self.actualization4)
+		self.compos.attach(button4,2,3,1,1)
+
+
+		button_clear = Gtk.Button.new_with_label("Wyczyść")
+		button_clear.connect("clicked", self.entry_clear)
+		self.compos.attach(button_clear,3,0,1,4)
+		box.add(self.compos)
+		
+		self.show_all()
+		
+	def entry_clear(self, button):
+		global new_pixbuf
+		file_img_selected=get_resource_path("/usr/share/postagelabels/blank_small.png")
+		new_pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
+			filename=file_img_selected,
+			width=500,
+			height=250,
+			preserve_aspect_ratio=True)
+
+		
+		if self.com_first != None:
+			self.compos.remove(self.com_first)
+			self.com_first=None
+		else:
+			self.compos.remove(self.com_new)
+			
+		# czyści etykiete
+		self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, new_pixbuf.get_width(), new_pixbuf.get_height())
+		self.context = cairo.Context(self.surface)
+		Gdk.cairo_set_source_pixbuf(self.context, new_pixbuf, 0, 0)
+		self.context.paint() #paint the pixbuf
+
+
+		self.com_new = Gtk.Image.new_from_pixbuf(new_pixbuf)
+		self.compos.attach(self.com_new,0,0,1,3) 
+
+		self.show_all()
+		
+		
+	def actualization1(self, button):
+		global new_pixbuf
+		self.context.move_to(15, 20+self.fontsize)
+		self.context.set_font_size(self.fontsize)
+		self.context.set_source_rgba(0,0,0,1)
+		self.context.show_text(self.entry1.get_text())
+
+		#get the resulting pixbuf
+		self.surface= self.context.get_target()
+		new_pixbuf= Gdk.pixbuf_get_from_surface(self.surface, 0, 0, self.surface.get_width(), self.surface.get_height())
+		
+		if self.com_first != None:
+			self.compos.remove(self.com_first)
+			self.com_first=None
+		else:
+			self.compos.remove(self.com_new)
+
+		
+		self.com_new = Gtk.Image.new_from_pixbuf(new_pixbuf)
+		self.compos.attach(self.com_new,0,0,1,3)
+		
+		self.show_all()
+    
+	def actualization2(self, button):
+		global new_pixbuf
+		self.context.move_to(15, 20+self.fontsize+self.fontsize+15)
+		self.context.set_font_size(self.fontsize)
+		self.context.set_source_rgba(0,0,0,1)
+		self.context.show_text(self.entry2.get_text())
+
+		#get the resulting pixbuf
+		self.surface= self.context.get_target()
+		new_pixbuf= Gdk.pixbuf_get_from_surface(self.surface, 0, 0, self.surface.get_width(), self.surface.get_height())
+		
+		if self.com_first != None:
+			self.compos.remove(self.com_first)
+			self.com_first=None
+		else:
+			self.compos.remove(self.com_new)
+
+		
+		self.com_new = Gtk.Image.new_from_pixbuf(new_pixbuf)
+		self.compos.attach(self.com_new,0,0,1,3)
+		
+		self.show_all()
+	def actualization3(self, button):
+		global new_pixbuf
+		self.context.move_to(15, 20+self.fontsize+self.fontsize+self.fontsize+30)
+		self.context.set_font_size(self.fontsize)
+		self.context.set_source_rgba(0,0,0,1)
+		self.context.show_text(self.entry3.get_text())
+
+		#get the resulting pixbuf
+		self.surface= self.context.get_target()
+		new_pixbuf= Gdk.pixbuf_get_from_surface(self.surface, 0, 0, self.surface.get_width(), self.surface.get_height())
+		
+		if self.com_first != None:
+			self.compos.remove(self.com_first)
+			self.com_first=None
+		else:
+			self.compos.remove(self.com_new)
+
+		
+		self.com_new = Gtk.Image.new_from_pixbuf(new_pixbuf)
+		self.compos.attach(self.com_new,0,0,1,3)
+		
+		self.show_all()
+        
+	def actualization4(self, button):
+		global new_pixbuf
+		self.context.move_to(15, 20+self.fontsize+self.fontsize+self.fontsize+self.fontsize+50)
+		self.context.set_font_size(self.fontsize)
+		self.context.set_source_rgba(0,0,0,1)
+		self.context.show_text(self.entry4.get_text())
+
+		#get the resulting pixbuf
+		self.surface= self.context.get_target()
+		new_pixbuf= Gdk.pixbuf_get_from_surface(self.surface, 0, 0, self.surface.get_width(), self.surface.get_height())
+		
+		if self.com_first != None:
+			self.compos.remove(self.com_first)
+			self.com_first=None
+		else:
+			self.compos.remove(self.com_new)
+
+		
+		self.com_new = Gtk.Image.new_from_pixbuf(new_pixbuf)
+		self.compos.attach(self.com_new,0,0,1,3)
+		
+		self.show_all()
+        
+        
+class DialogHelp(Gtk.Dialog):
+	def __init__(self, parent):
+		Gtk.Dialog.__init__(self, title="Pomoc", transient_for=parent, flags=0)
+		self.props.border_width = 20
+		self.add_buttons(
+			Gtk.STOCK_OK, Gtk.ResponseType.OK
+		)
+
+		self.set_default_size(150, 100)
+		label1 = Gtk.Label(label="Aplikacja służąca do aranżacji wydruku etykiet pocztowych.\nMożna zrówno tworzyć jak i wczytywać gotowe etykiety,\n a następnie umieszczać jena siatce.\nAplikacja bierze poprawkę dla drukarki Epson serii L,\nz ramką wokół wydruku.\n")
+		label2 = Gtk.Label(label="Pojedyńcza etykieta powinna mieć wymiary: 1134x496 px.\nKomptabilny papier pochodzi z zasobów \'Galerii Papieru\'\n\nNa siatce etykiete dodajemy \'lpm\', a usuwamy \'ppm\'.\n\nAplikacja na ekranach HD Ready będzie zachowywać się\nniestabilnie! Zalecany ekran to Full HD.")
+		box = self.get_content_area()
+		box.add(label1)
+		box.add(label2)
+		self.show_all()
+
+class DialogAbout(Gtk.Dialog):
+	def __init__(self, parent):
+		Gtk.Dialog.__init__(self, title="O Programie", transient_for=parent, flags=0)
+		self.props.border_width = 20
+		self.add_buttons(
+			Gtk.STOCK_OK, Gtk.ResponseType.OK
+		)
+
+		self.set_default_size(150, 100)
+
+		label = Gtk.Label(label="\tAplikacja napisana na podstawie:\n\nhttps://python-gtk-3-tutorial.readthedocs.io/\n\n\t\tWersja: 0.220120-2\n\n\t\tPrzemysław R. Pietraszczyk\n\n\t\t\tWrzesień 2021\n\t\t\tLicencja: GPL\n\n")
+
+		box = self.get_content_area()
+		box.add(label)
+
+		button = Gtk.LinkButton("http://www.prp.xlx.pl", label="Strona Domowa")
+		box.add(button)
+
+		self.show_all()
+
+
+
+
+class DialogMessage(Gtk.Dialog):
+	def __init__(self, parent):
+		super().__init__(title="Błąd zaznaczenia", transient_for=parent, flags=0)
+		self.add_buttons(
+			Gtk.STOCK_OK, Gtk.ResponseType.OK
+
+		)
+
+		self.set_default_size(150, 100)
+
+		label = Gtk.Label(label="Powinieneś najperw zaznaczyć etykiete,\nz listy dostępnych etykiet.")
+
+		box = self.get_content_area()
+		box.add(label)
+		self.show_all()
+
+
+
+
+class FileChooserIMG(Gtk.Window):
+	def __init__(self):
+		Gtk.Window.__init__(self, title="Wybór plików graficznych")
+		global file_img_selected
+
+		dialog = Gtk.FileChooserDialog(title="Please choose a file", parent=self, action=Gtk.FileChooserAction.OPEN)
+		dialog.add_buttons(
+			Gtk.STOCK_CANCEL,
+			Gtk.ResponseType.CANCEL,
+			Gtk.STOCK_OPEN,
+			Gtk.ResponseType.OK,
+		)
+
+		self.add_filters(dialog)
+
+		response = dialog.run()
+		if response == Gtk.ResponseType.OK:
+			print("Open clicked")
+			print("File selected: " + dialog.get_filename())
+			file_img_selected=dialog.get_filename()
+			list_labels.append(file_img_selected)
+		elif response == Gtk.ResponseType.CANCEL:
+			print("Cancel clicked")	
+		
+		dialog.destroy()
+
+	def add_filters(self, dialog):
+		filter_png = Gtk.FileFilter()
+		filter_png.set_name("Pliki PNG")
+		filter_png.add_mime_type("image/png")
+		dialog.add_filter(filter_png)
+		
+		filter_jpeg = Gtk.FileFilter()
+		filter_jpeg.set_name("Pliki JPEG")
+		filter_jpeg.add_mime_type("image/jpeg")
+		dialog.add_filter(filter_jpeg)
+
+
+
+
+class FileChooserLabel(Gtk.Window):
+	def __init__(self, this):
+		global glob_liststore
+		Gtk.Window.__init__(self, title="Zapis etykiety")
+		global file_label_save
+
+		dialog = Gtk.FileChooserDialog(title="Please choose a file", parent=self, action=Gtk.FileChooserAction.SAVE)
+		dialog.add_buttons(
+			Gtk.STOCK_CANCEL,
+			Gtk.ResponseType.CANCEL,
+			Gtk.STOCK_SAVE,
+			Gtk.ResponseType.OK,
+		)
+
+		self.add_filters(dialog)
+
+		response = dialog.run()
+		if response == Gtk.ResponseType.OK:
+			print("Open clicked")
+			print("File selected: " + dialog.get_filename())
+			file_label_save=dialog.get_filename()
+			pixbuf2 = new_pixbuf.scale_simple(1134, 496, GdkPixbuf.InterpType.BILINEAR)
+			pixbuf2.savev(file_label_save,"png", ["quality"], ["100"])
+			this.available_labels(file_label_save)
+
+
+		elif response == Gtk.ResponseType.CANCEL:
+			print("Cancel clicked")	
+		
+		dialog.destroy()
+
+	def add_filters(self, dialog):
+		filter_png = Gtk.FileFilter()
+		filter_png.set_name("Pliki PNG")
+		filter_png.add_mime_type("image/png")
+		dialog.add_filter(filter_png)
+		"""
+		filter_jpeg = Gtk.FileFilter()
+		filter_jpeg.set_name("Pliki JPEG")
+		filter_jpeg.add_mime_type("image/jpeg")
+		dialog.add_filter(filter_jpeg)
+		"""
+
+
+
+
+
+
+
+class MyWindow(Gtk.Window):
+
+	def __init__(self):
+		super().__init__()
+
+		self.init_ui()
+
+	
+	def refresh_label_view(self):
+		
+		if self.image2 != None:
+			grid.remove(self.image2)
+			self.image2=None
+		else:
+			grid.remove(self.image_new)
+
+
+		pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
+			filename=self.label_selected,
+			width=500,
+			height=250,
+			preserve_aspect_ratio=True)
+
+		self.image_new = Gtk.Image.new_from_pixbuf(pixbuf)
+		grid.attach(self.image_new,0,1,1,1)
+		
+		self.show_all()
+	
+	def on_menu_file_new_template(self, widget):
+	
+		n = 0
+		file_img_selected=get_resource_path("/usr/share/postagelabels/blank_small.png")
+		pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
+			filename=file_img_selected,
+			width=250,
+			height=117, #125,
+			preserve_aspect_ratio=True)
+			
+		
+		for l in label_limits:
+			
+			print ("IMAGE2: "+str(pixbuf))
+			if pixbuf is not None:
+				self.image_template[n].set_from_pixbuf(pixbuf)
+				print_limits[n][2] = None
+
+				
+				
+			n += 1
+		self.show_all()  # najprawdopodobnie wymagane po pakietowaniu
+	
+	def on_menu_file_load_img_generic(self, widget):
+		global grid
+		filename=FileChooserIMG()
+		
+		if len(file_img_selected) != 0:
+	
+			if self.image2 != None:
+				grid.remove(self.image2)
+				self.image2=None
+			else:
+				grid.remove(self.image_new)
+
+		
+			pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
+				filename=file_img_selected,
+				width=500,
+				height=250,
+				preserve_aspect_ratio=True)
+
+			self.image_new = Gtk.Image.new_from_pixbuf(pixbuf)
+		
+			grid.attach(self.image_new,0,1,1,1)
+
+		
+			self.scrolled_window.remove(self.treeview)
+			grid.remove(self.scrolled_window)
+			self.liststore = Gtk.ListStore(str, str)
+
+			self.treeview.remove_column(self.column_text)
+        
+			for o in list_labels:
+				self.liststore.append([o,""])
+
+			self.scrolled_window = Gtk.ScrolledWindow ()
+			self.scrolled_window.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
+
+			self.treeview = Gtk.TreeView(model=self.liststore)
+
+			self.renderer_text = Gtk.CellRendererText()
+			self.column_text = Gtk.TreeViewColumn("Dostępne etykiety", self.renderer_text, text=0)
+			self.treeview.append_column(self.column_text)
+        
+			self.treeview.connect("button_release_event", self.mouse_selected)
+		
+			self.scrolled_window.add (self.treeview)
+			grid.attach(self.scrolled_window,0,2,1,6)
+
+			self.show_all()
+
+	def on_menu_composite_generic(self, widget):
+		dialog = DialogCompositor(self)
+		response = dialog.run()
+
+		if response == Gtk.ResponseType.OK:
+			print("Save clicked")
+			dialog_file_label=FileChooserLabel(self)
+		elif response == Gtk.ResponseType.CANCEL:
+			print("Cancel clicked")	
+		
+		dialog.destroy()
+
+	def on_menu_file_quit(self, widget):
+		Gtk.main_quit()
+
+	def on_menu_help(self, widget):
+		dialog = DialogHelp(self)
+		response = dialog.run()
+
+		dialog.destroy()
+		
+	def on_menu_about(self, widget):
+		dialog = DialogAbout(self)
+		response = dialog.run()
+
+		dialog.destroy()
+
+
+	def add_info_menu_actions(self, action_group):
+		action_info_menu = Gtk.Action(name="InfoMenu", label="Info")
+		action_group.add_action(action_info_menu)
+
+		action_new = Gtk.Action(
+			name="Help",
+			label="Pomoc",
+			tooltip="Create a new file",
+		)
+		action_new.connect("activate", self.on_menu_help)
+		action_group.add_action_with_accel(action_new, None)
+
+		action_new = Gtk.Action(
+			name="About",
+			label="O Programie",
+			tooltip="Create a new file",
+		)
+		action_new.connect("activate", self.on_menu_about)
+		action_group.add_action_with_accel(action_new, None)
+
+	def add_file_menu_actions(self, action_group):
+		action_filemenu = Gtk.Action(name="FileMenu", label="Plik")
+		action_group.add_action(action_filemenu)
+
+		action_fileloadmenu = Gtk.Action(name="FileLoad", stock_id=Gtk.STOCK_NEW)
+		action_group.add_action(action_fileloadmenu)
+
+		action_new = Gtk.Action(
+			name="LoadImg",
+			label="Załaduj etykiete",
+			tooltip="Wczytuje etykiete",
+		)
+		action_new.connect("activate", self.on_menu_file_load_img_generic)
+		action_group.add_action_with_accel(action_new, None)
+		
+		
+		action_new = Gtk.Action(
+			name="NewTemplate",
+			label="Nowy szablon",
+			tooltip="Tworzy szablon na nowo",
+		)
+		action_new.connect("activate", self.on_menu_file_new_template)
+		action_group.add_action_with_accel(action_new, None)
+		
+		
+		action_new = Gtk.Action(
+			name="Composite",
+			label="Kompozytor",
+			tooltip="Tworzy nową etykiete",
+		)
+		action_new.connect("activate", self.on_menu_composite_generic)
+		action_group.add_action_with_accel(action_new, None)
+		
+
+		action_print = Gtk.Action(name="FilePrint", stock_id=Gtk.STOCK_PRINT)
+		action_print.connect("activate", self.print_image)
+		action_group.add_action(action_print)
+
+
+		action_filequit = Gtk.Action(name="FileQuit", stock_id=Gtk.STOCK_QUIT)
+		action_filequit.connect("activate", self.on_menu_file_quit)
+		action_group.add_action(action_filequit)
+	
+	
+	
+	# tworzy menu bar
+	def create_ui_manager(self):
+		uimanager = Gtk.UIManager()
+
+		# Throws exception if something went wrong
+		uimanager.add_ui_from_string(UI_INFO)
+
+		# Add the accelerator group to the toplevel window
+		accelgroup = uimanager.get_accel_group()
+		self.add_accel_group(accelgroup)
+		return uimanager
+
+
+	
+	def mouse_selected(self, tv, event):
+		
+		if event.button == 1:
+			
+			# Begin added code
+			pthinfo = self.treeview.get_path_at_pos(event.x, event.y)
+			if pthinfo != None:
+				path,col,cellx,celly = pthinfo
+				self.treeview.grab_focus()
+				self.treeview.set_cursor(path,col,0)
+			# End added code
+
+			selection = self.treeview.get_selection()
+			(model, iter) = selection.get_selected()
+			print(model[iter][0])
+			self.label_selected = model[iter][0]
+
+			self.refresh_label_view()
+			
+
+	def onclick_in_pixbuf (self, box, event):
+		if event.button == 1:
+			try:
+				print ("\nKliknieto na pozycji")
+				print (event.x, event.y)
+				print ("\n")
+				e = [int(event.x), int(event.y)]
+				n = 0
+		
+				pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
+					filename=self.label_selected,
+					width=250,
+					height=117, #125,
+					preserve_aspect_ratio=True)
+
+		
+				for l in label_limits:
+			
+					x, y = l[:]
+					e_x, e_y = e[:]
+			
+					if e_x >= x and e_y >= y and e_x <= x+250 and e_y <= y+117:
+						if pixbuf is not None:
+							self.image_template[n].set_from_pixbuf(pixbuf)
+							print_limits[n][2] = self.label_selected
+				
+						break
+					n += 1
+			except AttributeError:
+
+				dialog = DialogMessage(self)
+				response = dialog.run()
+
+
+				dialog.destroy()
+		if event.button == 3:
+			
+			
+			e = [int(event.x), int(event.y)]
+			n = 0
+			
+			file_img_selected=get_resource_path("/usr/share/postagelabels/blank_small.png")
+			pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
+				filename=file_img_selected,
+				width=250,
+				height=117, #125,
+				preserve_aspect_ratio=True)
+			
+		
+			for l in label_limits:
+			
+				x, y = l[:]
+				e_x, e_y = e[:]
+			
+				if e_x >= x and e_y >= y and e_x <= x+250 and e_y <= y+117:
+					print ("IMAGE2: "+str(pixbuf))
+					if pixbuf is not None:
+						self.image_template[n].set_from_pixbuf(pixbuf)
+						print_limits[n][2] = None
+
+				
+					break
+				n += 1
+		self.show_all()  # najprawdopodobnie wymagane po pakietowaniu
+		
+	def on_mouse_move_in_pixbuf (self, box, event):
+		e = [int(event.x), int(event.y)]
+		n = 0
+		for l in label_limits:
+			
+			x, y = l[:]
+			e_x, e_y = e[:]
+			
+			if e_x >= x and e_y >= y and e_x <= x+200 and e_y <= y+92:
+				pass
+				
+	# dnae dla wydruku		
+	def set_print_limits(self):
+		start_x = 0
+		start_y = 0
+		end_x = BLANK_W * 2 #1234*2
+		end_y = BLANK_H * 6 #3508 
+		cols = 2
+		rows = 6
+		width = BLANK_W #1234
+		height = BLANK_H #585
+		
+		for j in range (start_y, end_y, height):
+			for i in range (start_x, end_x, width):
+				print_limits.append([i, j, None])
+	
+		print ("PRINT LIMIST")
+		print (print_limits)
+		
+		
+	# dane dla siatki
+	def set_label_limits(self):
+		start_x = 0
+		start_y = 0
+		end_x = 500
+		end_y = 104 * 6 #117 * 6 #700
+		cols = 2
+		rows = 6
+		width = 250
+		height = 104 #117
+		
+		for j in range (start_y, end_y, height):
+			for i in range (start_x, end_x, width):
+				label_limits.append([i, j])
+		
+		
+	def print_page(self, operation=None, context=None, page_nr=None):
+		
+		ctx = context.get_cairo_context()
+
+		# make cairo ImageSurface from the png file
+		surface = cairo.ImageSurface.create_from_png('/tmp/postagelabels.png')
+		
+		#ctx.set_operator(cairo.OPERATOR_SOURCE)
+		ctx.set_source_surface(surface)
+		ctx.paint ()
+		#ctx.set_operator(cairo.OPERATOR_OVER)
+		os.remove("/tmp/postagelabels.png");
+		
+		
+		
+		#page = self.doc.get_page(page_nr)
+		#page.render(ctx)
+		
+		
+		
+		
+		
+	def print_image(self, widget):
+		print ("PRINT LIMITS")
+		print (print_limits)
+		
+		page_width = 210
+		page_height = 297
+		#page_margin_top = 20
+		dpi = 600
+		#_mm_dpi = 72 / 25.4
+
+		
+		
+		
+		pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size('/usr/share/postagelabels/szablon.png', 2480, 3508)
+		
+		for i in range (12):
+			if print_limits[i][2] != None:
+				
+				if i%2 == 1:
+					center_beam = 24
+				else:
+					center_beam = 0
+					
+				label = GdkPixbuf.Pixbuf.new_from_file_at_size(print_limits[i][2], BLANK_W, BLANK_H)
+				#self.freeze_child_notify()
+				label.composite(pixbuf, print_limits[i][0]+89+center_beam, print_limits[i][1]+237, label.get_width(), label.get_height(), print_limits[i][0]+89+center_beam, print_limits[i][1]+237, 1, 1, GdkPixbuf.InterpType.NEAREST, 255)
+				#self.thaw_child_notify()
+			
+		# z orginalnymi wielkościami nie chce drukowac
+		pixbuf2 = pixbuf.scale_simple(600, 855, GdkPixbuf.InterpType.BILINEAR)
+
+		pixbuf2.savev("/tmp/postagelabels.png","png", ["quality"], ["100"])
+		"""
+		paper_size = Gtk.PaperSize.new_custom("1.0x", "2480 x 3508", 2480, 3508, Gtk.Unit.POINTS)
+
+		page_setup = Gtk.PageSetup()
+		page_setup.set_paper_size(paper_size)
+		pd = Gtk.PrintOperation()
+		#pd.set_embed_page_setup(True)
+		pd.set_default_page_setup(page_setup)
+		#pd.set_unit(Gtk.Unit.POINTS)
+		pd.set_n_pages(1)
+		pd.connect("draw_page", self.print_page)
+		result = pd.run(Gtk.PrintOperationAction.PRINT_DIALOG, None) # window zamisat None
+		print(result)  # handle errors etc.
+		"""
+		
+		
+		#ps= Gtk.PaperSize.new_custom("1.0x", "2480 x 3508", 2480, 3508, Gtk.Unit.POINTS)
+
+		ps = Gtk.PaperSize.new_custom("1.0x", "cc", page_width, page_height, Gtk.Unit.MM)
+		print_settings = Gtk.PrintSettings()
+		print_settings.set_resolution(dpi)
+
+		page_setup = Gtk.PageSetup()
+		page_setup.set_paper_size(ps)
+		page_setup.set_bottom_margin(0.0, Gtk.Unit.MM)
+		page_setup.set_left_margin(0.0, Gtk.Unit.MM)
+		page_setup.set_right_margin(0.0, Gtk.Unit.MM)
+		page_setup.set_top_margin(0.0, Gtk.Unit.MM)
+		page_setup.set_orientation(Gtk.PageOrientation.PORTRAIT)
+        
+
+		print_operation = Gtk.PrintOperation()
+		print_operation.set_n_pages(1)
+		print_operation.set_default_page_setup(page_setup)
+		print_operation.set_print_settings(print_settings)
+		print_operation.connect("draw_page", self.print_page)
+		#print_operation.set_export_filename("example.pdf")
+
+		result = print_operation.run(Gtk.PrintOperationAction.PRINT_DIALOG, None) # window zamisat None
+
+		#result = print_operation.run(Gtk.PrintOperationAction.PREVIEW, None)
+		print(result)
+
+	def available_labels(self, name):
+		
+		self.scrolled_window.remove(self.treeview)
+		grid.remove(self.scrolled_window)
+		self.liststore = Gtk.ListStore(str, str)
+
+		self.treeview.remove_column(self.column_text)
+
+		list_labels.append(name)
+		for o in list_labels:
+			self.liststore.append([o,""])
+		
+		self.scrolled_window = Gtk.ScrolledWindow ()
+		self.scrolled_window.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
+
+		self.treeview = Gtk.TreeView(model=self.liststore)
+
+		self.renderer_text = Gtk.CellRendererText()
+		self.column_text = Gtk.TreeViewColumn("Dostępne etykiety", self.renderer_text, text=0)
+		self.treeview.append_column(self.column_text)
+        
+		self.treeview.connect("button_release_event", self.mouse_selected)
+		
+		self.scrolled_window.add (self.treeview)
+		grid.attach(self.scrolled_window,0,2,1,6)
+		
+		self.show_all()
+		
+
+	def init_ui(self):
+		global grid
+		
+		
+		
+		self.image_new=None
+		self.props.border_width = 20
+		
+		self.add(grid)
+
+		grid.set_row_spacing(10)
+		grid.set_column_spacing(10)
+		grid.set_column_homogeneous(True) # rozszerza kontrolke z utworami na resztę okna
+		
+		action_group = Gtk.ActionGroup(name="my_actions")
+
+		self.add_file_menu_actions(action_group)
+		self.add_info_menu_actions(action_group)
+        
+		uimanager = self.create_ui_manager()
+		uimanager.insert_action_group(action_group)
+
+		menubar = uimanager.get_widget("/MenuBar")
+		box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
+		box.pack_start(menubar, False, False, 0)
+
+
+		grid.attach(box, 0, 0, 2, 1)
+		
+		
+		
+		event_box  = Gtk.EventBox ()
+		event_box.connect ('button-press-event', self.onclick_in_pixbuf)
+		event_box.connect("motion-notify-event", self.on_mouse_move_in_pixbuf)
+		event_box.add_events(Gdk.EventMask.POINTER_MOTION_MASK)
+		
+		self.set_label_limits()
+		self.set_print_limits()
+		frame = Gtk.Frame()
+		
+		
+		file_img_selected=get_resource_path("/usr/share/postagelabels/blank_small.png")
+		pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
+			filename=file_img_selected,
+			width=250,
+			height=117, #125
+			preserve_aspect_ratio=True)
+		
+
+		self.all_img_template = Gtk.Grid()
+		
+		self.image_template = []
+		self.image_template= [0 for i in range(12)] 
+
+		
+		left = 0
+		top = 1
+		top_next=False
+		multiplier = 0
+		n_multi = 1;
+		first = False
+		n = 2
+		for i in range(12):
+			print ("left: "+str(left)+"  top: "+str(top))
+
+			if left == 2:
+				left = 0;
+			n_multi += 1
+			print ("multi: " +str(n_multi)+" %"+ str(n_multi%4))
+			if n_multi%2== 0:
+				if first == False:
+					multiplier = 1
+					first = True
+				multiplier += n
+				n *= 2
+			self.image_template[i] = Gtk.Image.new_from_pixbuf(pixbuf)
+			self.all_img_template.attach(self.image_template[i], left, top+multiplier, 1 , top+multiplier)
+			left += 1
+			if top_next == False:
+				top_next = True
+				pass
+			else:
+				top_next = False
+				top +=1
+		
+		event_box.add(self.all_img_template)
+		
+		
+		frame.add(event_box)
+		grid.attach(frame,1,1,1,6)
+
+
+		
+        # powiększenie etykiety po lewej stronie
+		file_img_selected=get_resource_path("/usr/share/postagelabels/blank_small.png")
+		pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
+			filename=file_img_selected,
+			width=500,
+			height=250,
+			preserve_aspect_ratio=True)
+
+		self.image2 = Gtk.Image.new_from_pixbuf(pixbuf)
+
+		grid.attach(self.image2,0,1,1,1) 
+
+        
+        
+		self.liststore = Gtk.ListStore(str, str)
+		self.treeview = Gtk.TreeView(model=self.liststore)
+		self.treeview.connect("button_release_event", self.mouse_selected)
+
+
+
+		self.renderer_text = Gtk.CellRendererText()
+		self.column_text = Gtk.TreeViewColumn("Dostępne etykiety", self.renderer_text, text=0)
+		self.treeview.append_column(self.column_text)
+
+		self.scrolled_window = Gtk.ScrolledWindow ()
+		self.scrolled_window.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
+
+		self.scrolled_window.add (self.treeview)
+		grid.attach(self.scrolled_window,0,2,1,6)
+
+
+
+        
+		self.set_border_width(10)
+		self.set_title("Naklejki Pocztowe")
+		self.set_default_size(1000, 655)
+		self.connect("destroy", Gtk.main_quit)
+		
+        
+
+win = MyWindow()
+win.show_all()
+Gtk.main()
+
+
+
+
+
+
+
+
Binary file postagelabels/xcf/blank_small.xcf has changed
Binary file postagelabels/xcf/labelpost.xcf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/verysimpleslideshow/COPYRIGHT	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,27 @@
+This software is distributed under the Public Domain. Since it is
+not enough anymore to tell people: 'hey, just do with it whatever
+you like to do', you can consider this software being distributed
+under the CC0 Public Domain Dedication
+(http://creativecommons.org/publicdomain/zero/1.0/legalcode.txt).
+
+In cases, where the law prohibits the recognition of Public Domain
+software, this software can be licensed under the zlib license as
+stated below:
+
+Copyright (C) 2023 Przemyslaw R. Pietraszczyk <prymula76@outlook.com>
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+   claim that you wrote the original software. If you use this software
+   in a product, an acknowledgement in the product documentation would be
+   appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/verysimpleslideshow/Changelog	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,17 @@
+0.230913-0 - Dołąćzenie starszego resamplingu: ANTIALIAS obok nowego LANCZOS, plus drobne poprawki
+0.230910-1 - Rozciągnięcie filmu w czasie, teraz pauza pomiędzy klatkami jest całkiem spora. ( parametr -r 0.2  - ffmpeg)
+0.230910-0 - Jawne wariacje z atrybutem Resampling.LANCZOS funkcji resize() - czy skrypt ciągle zjada klatki ? 
+0.230909-1 - Rozpoznaje proporcje zdjęcia i sam decyduje czy wczytać fotografie - działa z błędami 
+0.230908-1 - Próba spowolnienia filmu argumentem ffmpeg - niewiele pomogło
+0.230907-0 - Próba dostosowania skryptu do Okienek - zmiana slash na unslash w path dla list.txt - bez powodzenia
+0.230906-8 - Tworzy film, bez czarnych klatek. ffmpeg generuje dziwny błąd o nieodnalezionej klatce...
+0.230906-7 - Przetwarza na podstawie pliku, dodaje czarne klatki
+0.230906-6 - Próba przetwarzania fotografii na podstawie pliku list.txt dla ffmpeg
+0.230905-2 - Próba przetwarzania w bieżącym katalogu (czasowo)
+0.230905-1 - Ciąg dalszy integracji z Okienkami
+0.230905-0 - Pierwsze przymiarki do komptabilności z Okienkami
+0.230903-3 - Nie gubi już zdjęć, i nie dodaje czarnych klatek
+0.230903-2 - Automatycznie skaluje obrazy do 1080 px dla najdłuższego boku
+0.230903-1 - Skrypt tworzy zarówno video portretowe jak i krajobrazowe
+0.230902-0 - Inicjacja projektu
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/verysimpleslideshow/CzytajTo	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,23 @@
+Very Simple Slide Show (vsss)
+
+Skrypt Pythona służący do tworzenia pokazów slajdów ze zdjęć JPG.
+Aplikacja umożliwia tworzenie filmików ze zdjęć, zarówno w orientacji pionowej jak i poziomej. Powstała z osobistych potrzeb autora. Mając na celu, ułatwienie tworzenia pokazów slajdów na potrzeby Facebooka. Intencją autora nie było tworzenie aplikacji dla wszystkich, pisząc ten skrypt, skupił się w głównej mierze na własnych potrzebach i możliwościach.
+
+Skrypt pracuje ze zdjęciami o wielkości 1080 pikseli dla najdłuższego boku. Jeśli obraz jest większy, zostanie wówczas przeskalowany.
+Dla filmu o orientacji pionowej, zdjęcia horyzontalne, zostaną dodane w parze, jedno pod drugim. Dla obrazu nieparzystego, przewidziane jest umieszczenie fotografii pośrodku kadru. Dla orientacji poziomej filmu, wice wersa.
+
+Program współpracuje z fotografiami o proporcjach 3:2 oraz 4:3. Co jest w zupełności wystarczające dla autora, rozszerzenie o formaty panoramiczne, nie jest przewidziane. Program sam rozpoznaje format zdjęcia – choć potrafi nieoczekiwanie odrzucić to i owo. Do przetwarzania obrazu, skrypt wykorzystuje bibliotekę PILLOW. Natomiast do kodowania filmu, polecenie ‘ffmpeg’. W przypadku Fedory, z której korzysta autor. Wykorzystywany pakiet to ‘ffmpeg’ z RPM Fusion. Argumenty z tej wersji polecenia, mogą być niezgodne z wersją ‘ffmpeg-free’ z repozytorium Fedora Core, co trzeba mieć na uwadze. Wykorzystywany kodek to x264 (zamiast openh264 z FC). Więc jeśli używasz ‘ffmpeg-free’ i chciałbyś używać tego skryptu, to mogę Tobie polecić tą stronę, zawierającą informacje o zmianie wersji pakietu: https://rpmfusion.org/Howto/Multimedia
+Skrypt został w ostatnim czasie, przystosowany do pracy w dystrybucjach Debian/Ubuntu. Testowany był w Lubuntu 22.04 ze standardową wersją ‘ffmpeg’. W przypadku Okienek, testy nie przebiegły pomyślnie.
+
+Instalacja skryptu z archiwum źródlowego:
+	sudo make install
+Deinstalacja:
+	sudo make uninstall
+
+Użyj skryptu zainstalowanego w systemie plików, w katalogu ze zdjęciami, poleceniem:
+‘vsss -H’ lub ‘vsss’ – utworzenie filmu horyzontalnego
+‘vsss -V’ – utworzenie filmu wertykalnego
+‘vsss -h’ – wyświetlenie pomocy oraz numeru wersji.
+
+Z pozdrowieniami:
+Przemysław R. Pietraszczyk
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/verysimpleslideshow/DEBIAN/HOWTO.txt	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,2 @@
+foramt zapisu nazwy pliku:
+	photocrop_0.221225-0~alpha.tar.gz
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/verysimpleslideshow/DEBIAN/debian.changelog	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,18 @@
+verysimpleslideshow (0.230909-1) unstable; urgency=low
+
+  * Last release
+
+ -- Przemysław R. Pietraszczyk  Thu, 09 Sep 2023 22:47:00 +0200
+
+
+verysimpleslideshow (0.230907-0) unstable; urgency=low
+
+  * Last release
+
+ -- Przemysław R. Pietraszczyk  Thu, 07 Sep 2023 19:30:00 +0200
+
+verysimpleslideshow (0.230903-3) unstable; urgency=low
+
+  * Last release
+
+ -- Przemysław R. Pietraszczyk  Sun, 03 Sep 2023 21:21:21 +0200
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/verysimpleslideshow/DEBIAN/debian.control	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,13 @@
+Source: verysimpleslideshow
+Section: python
+Priority: extra
+Maintainer: Przemysław R. Pietraszczyk
+Build-Depends: debhelper-compat (= 12), python3-all, python-setuptools, dh-python, fakeroot
+Standards-Version: 0.230910-1
+Homepage: http://prymula.ct8.pl
+
+
+Package: verysimpleslideshow
+Architecture: all
+Depends: ${misc:Depends}, python3-all, ffmpeg
+Description: CLI script for creating slideshows 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/verysimpleslideshow/DEBIAN/debian.postinst	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,7 @@
+#!/bin/sh
+set -e
+
+chmod 0755 /usr/bin/verysimpleslideshow.py
+ln -s /usr/bin/verysimpleslideshow.py /usr/bin/vsss
+
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/verysimpleslideshow/DEBIAN/debian.postrm	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,10 @@
+#!/bin/sh
+set -e
+
+case "$1" in
+  0) # last one out put out the lights
+    rm -f /usr/bin/vsss
+  ;;
+esac
+
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/verysimpleslideshow/DEBIAN/debian.rules	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,19 @@
+#!/usr/bin/make -f
+
+export DH_VERBOSE = 1
+
+clean:
+	@
+	
+build:
+	@
+
+binary:
+	mkdir -pm 0755 debian/verysimpleslideshow
+	mkdir -pm 0755 debian/verysimpleslideshow/usr/bin
+	mkdir -pm 0755 debian/verysimpleslideshow/usr/share
+	mkdir -pm 0755 debian/verysimpleslideshow/usr/share/verysimpleslideshow
+	cp verysimpleslideshow.py debian/verysimpleslideshow/usr/bin/
+	cp CzytajTo debian/verysimpleslideshow/usr/share/verysimpleslideshow/
+	dh_gencontrol
+	dh_builddeb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/verysimpleslideshow/DEBIAN/format.sh	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,2 @@
+mkdir exec
+exec /usr/lib/build/debtransform ./ ./verysimpleslideshow.dsc ./exec
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/verysimpleslideshow/DEBIAN/verysimpleslideshow.dsc	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,40 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA256
+
+Format: 1.0
+Source: verysimpleslideshow
+Binary: verysimpleslideshow
+Architecture: all
+Version: 0.230910-1
+Maintainer: Przemysław R. Pietraszczyk <prymula76@outlook.com>
+Homepage: http://prymula.ct8.pl
+DEBTRANSFORM-TAR: verysimpleslideshow-0.230910-1.tar.gz
+ 
+Standards-Version: 0.230910-1
+Build-Depends: debhelper-compat (>= 12), python3-all, python-setuptools, dh-python, fakeroot
+Package-List:
+ verysimpleslideshow deb x11 optional arch=all
+Files:
+ b31649bc23b2b7bca9ab70ea3410711a 128820 verysimpleslideshow_0.230910-1.tar.gz
+ 29e7e7e60bc81891e3da3871b9eeb549 764 verysimpleslideshow-0.230910-1.debian.tar.xz
+
+-----BEGIN PGP SIGNATURE-----
+
+mQENBGEf/c4BCAC2d4ymW0pRZV36qLtlt/WGb83kos5UX5UbwvkQrbUjAbOPOY8w
+DT3M1neYOAPZx38924aPTFKbZPcz+rK/7Wcv1kzgfux5zXQJTLeqpkhUYAgXUg2p
+oK9ZXsai82fOicTrClOyJLLYQ8C1vj8yUh7e3ERljEyp5Nxg/lY92rwcZ4WYR193
+nGDInlDl5JlWUcLlk/RFnC5bB+T6ZZr5FBX/eDnKAPEl+N3MWpDs2JLDy7EUPhcG
+U/60X0wuXHPTwMoNbB3ep/bWRxwEej0sFad5GXeCh7hKCroi/kLmLTDIxSD8lsRr
+Y4H/8H2lBBsQq7bRL88N6ZDGCocPo11V83kFABEBAAG0NmhvbWU6cHJ6ZW0gT0JT
+IFByb2plY3QgPGhvbWU6cHJ6ZW1AYnVpbGQub3BlbnN1c2Uub3JnPokBPgQTAQgA
+KAUCYR/9zgIbAwUJBB6wAAYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQcXEc
+NPcNefFEAAf+Kg4cs/C99kEIMv/PO85VW+p8rcTwCViOFUX5WrBhwsRyPAKrJPPG
+KD6PdnvoplcNQwhQ8nRsRiiaiUtPcj8Bvi6EdPgSgXXObKKJtCyaAa1rURdlb9iW
+CfvXA6oW+PGlii9BMnXOAtkeFIzZooO9oXd+wez66P+4VWFiFzxanLfLn/hwbWxQ
+68rlO3QNGbrMeODBgwh9s83XGmAg47mn2fldTAmTbJDf9tMi1LhX2MmLyN9wjqsd
+4IZ9JMri2JTnIhYfxWdKT9gsu7q0g8LqonaXMvlOEyHFRF1YQ0i7G6fFbvDcKCZN
+W1Eja55FdN7smv5Eck6UTIIYyWPuAv45uohGBBMRAgAGBQJhH/3PAAoJEDswEbdr
+nWUj4M0AniJ389dyvUjjgS91AcOb08E4moV9AJ9WDL3/7GYYUL/Azw43QucWPnXr
+uw==
+=+lfH
+-----END PGP SIGNATURE-----
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/verysimpleslideshow/Makefile	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,15 @@
+
+prefix=/usr/local
+
+all:
+
+install:
+	install -m 0755 verysimpleslideshow.py $(prefix)/bin
+	ln -s $(prefix)/bin/verysimpleslideshow.py $(prefix)/bin/vsss
+
+
+uninstall:
+	rm $(prefix)/bin/vsss
+	rm $(prefix)/bin/verysimpleslideshow.py
+	
+.PHONY: all install uninstall
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/verysimpleslideshow/RPM/verysimpleslideshow.spec	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,72 @@
+#
+# spec file for package vsss
+#
+# Copyright (c) 2020 SUSE LLC
+#
+# All modifications and additions to the file contributed by third parties
+# remain the property of their copyright owners, unless otherwise agreed
+# upon. The license for this file, and modifications and additions to the
+# file, is the same license as for the pristine package itself (unless the
+# license for the pristine package is not an Open Source License, in which
+# case the license is the MIT License). An "Open Source License" is a
+# license that conforms to the Open Source Definition (Version 1.9)
+# published by the Open Source Initiative.
+
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
+#
+
+%define unmangled_version 0.230910-1
+Name:       verysimpleslideshow
+Version:	0.230910
+Release:    1
+Summary:	CLI script for creating slideshows 
+License:	Public Domain
+URL:		https://prymula.ct8.pl
+Source0:	%{name}-%{unmangled_version}.tar.gz
+%if 0%{?suse_version}>=150000
+BuildRequires:	python3
+Requires:       python3, ffmpeg
+%endif
+%if 0%{?fedora}>=36
+BuildRequires:	python3
+Requires:		python3, ffmpeg
+%endif
+BuildArch:	noarch
+
+%description
+
+
+%prep
+%setup -n %{name}-%{unmangled_version} -n %{name}-%{unmangled_version}
+rm -f %{_bindir}/vsss
+
+%post
+%{__ln_s} -f %{_bindir}/verysimpleslideshow.py %{_bindir}/vsss
+
+%postun
+rm -f %{_bindir}/vsss
+
+%build
+
+%install
+
+mkdir -p %{buildroot}/usr
+mkdir -p %{buildroot}/usr/bin
+mkdir -p %{buildroot}/usr/share
+mkdir -p %{buildroot}/usr/share/verysimpleslideshow
+
+
+install -m 0755 verysimpleslideshow.py %{buildroot}/usr/bin
+install -m 0644 CzytajTo %{buildroot}/usr/share/verysimpleslideshow
+
+
+
+%files
+%defattr(0755,root,root)
+/usr/bin/verysimpleslideshow.py
+/usr/share/verysimpleslideshow/
+%defattr(0644,root,root)
+/usr/share/verysimpleslideshow/CzytajTo
+
+%changelog
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/verysimpleslideshow/run.txt	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,1 @@
+ffmpeg -f concat -r 1 -i list.txt -framerate 0.3 -c:v mpeg4 output.mp4
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/verysimpleslideshow/verysimpleslideshow.py	Thu Sep 21 22:32:14 2023 +0200
@@ -0,0 +1,288 @@
+#!/usr/bin/env python3
+# Very Simple Slide Show
+# autor: Prymula (PRP)
+# licencja: Public Domain
+# data 02-09-2023
+# edytor: Geany
+
+import os, sys
+import tempfile
+import shutil
+from sys import platform
+from PIL import Image
+from itertools import filterfalse
+
+VER = "0.230913-0"
+
+if platform == "linux" or platform == "linux2":
+	SLA = '/'
+elif platform == "darwin":
+	SLA = '/'
+elif platform == "win32":
+	SLA = '\\'
+	
+#count = 0
+tmp_path =  tempfile.mkdtemp()
+#mp_path =  dir_path = os.getcwd()
+#list_path =  dir_path = os.getcwd()
+tmp_list = tmp_path + SLA + "list.txt"
+# NIE USUWAC !
+#command = "ffmpeg -framerate 0.3 -pattern_type glob -i '"+tmp_path+"/*.jpg' -c:v libopenh264 -profile:v high -crf 20 -pix_fmt yuv420p output.mp4"
+command = "ffmpeg -f concat -y -r 0.2 -safe 0 -i '"+tmp_list+"' -framerate 1 -c:v libx264 -profile:v high -crf 20 -pix_fmt yuv420p -filter:a 'atempo=0.5' output.mp4"
+#command = "ffmpeg -f concat -y -r 0.2 -safe 0 -i '"+tmp_list+"' -framerate 1 -c:v mpeg4 -crf 20 -pix_fmt yuv420p output.mp4"
+
+#num = 0
+sample = None
+try:
+	sample = Image.Resampling.LANCZOS
+	print ("Uzywam LANCZOS")
+except AttributeError:
+	sample = Image.ANTIALIAS
+	print ("Uzywam: ANTIALIAS")
+	
+
+class App():
+	
+	BASE_APSC = 724
+	LONG = 1080
+	HALF = 540
+	BASE_MICRO = 810
+	BASE = None
+	#n_pictures = 0
+	count = 0
+	
+	def list_files(self, dir_path):
+		res = []
+		try:
+			for file_path in os.listdir(dir_path):
+				if os.path.isfile(os.path.join(dir_path, file_path)):
+					res.append(os.path.join(dir_path, file_path))
+		except FileNotFoundError:
+			print(f"The directory {dir_path} does not exist")
+		except PermissionError:
+			print(f"Permission denied to access the directory {dir_path}")
+		except OSError as e:
+			print(f"An OS error occurred: {e}")
+		return res
+
+	def file_exclusion(self, files):
+		for f in files[:]:
+			if f.rfind('.jpg') == -1:
+				#print('usuwam: '+f)
+				files.remove(f)
+		return files
+
+	def get_files(self):
+		dir_path = os.getcwd()  
+		print ("GETCWD: "+dir_path)
+		files = self.list_files(dir_path)
+		return a.file_exclusion(files)
+
+	def create_horizontal_surface(self):
+		return Image.new('RGB', (a.LONG, a.BASE))
+	
+	def create_vertical_surface(self):
+		return Image.new('RGB', (a.BASE, a.LONG))
+
+	def put_horizontal_image(self, image):
+		global sample
+		new = Image.new("RGB", (a.LONG, a.BASE))
+		if image.size[0] != a.LONG:
+			image = image.resize((a.LONG, a.BASE), sample, None, 3.0)
+		new.paste(image, (0,0), mask = image)
+		return new
+
+	def put_vertical_image(self, image):
+		global sample
+		new = Image.new("RGB", (a.BASE, a.LONG))
+		if image.size[0] != a.BASE:
+			image = image.resize((a.BASE, a.LONG), sample, None, 3.0)
+		new.paste(image, (0,0), mask = image)
+		return new
+
+	# dodaje portrety do kraiobrazu
+	def join_image_to_horizontal(self, image, destinity):
+		global sample  # n_pictures
+		single = False
+		print ("DLUGOSC: "+str(len(image)))
+		if len(image) == 1: #  and n_pictures > 0: # 1
+			print ("SINGIELEK")
+			#num += 1 # tymczasowy
+			tmp = image[-1]. resize((a.HALF, a.BASE), sample, None, 3.0)
+			destinity.paste(tmp, (300,0), mask = tmp)
+			image.pop()
+			single = True
+		elif len(image) > 0:
+			#num += 1 # tymczasowy
+			tmp = image[-1].resize((a.HALF, a.BASE), sample, None, 3.0)
+			destinity.paste(tmp, (0,0), mask = tmp)
+			image.pop()
+			if len(image) > 0:
+				#num += 1 # tymczasowy
+				tmp = image[-1]. resize((a.HALF, a.BASE), sample, None, 3.0)
+				destinity.paste(tmp, (a.HALF,0), mask = tmp)
+				image.pop()
+
+		return destinity, len(image), single
+
+	# dodaje kraiobrazy do portretu
+	def join_image_to_vertical(self, image, destinity):
+		global sample  # n_pictures
+		single = False
+		print ("DLUGOSC: "+str(len(image)))
+		if len(image) ==  1: # and a.n_pictures > 0: # 1
+			print ("SINGIELEK")
+			#num += 1 # tymczasowy
+			tmp = image[-1]. resize((a.BASE, a.HALF), sample, None, 3.0)
+			destinity.paste(tmp, (0,300), mask = tmp)
+			image.pop()
+			single = True
+			#a.n_pictures -= 1
+		elif len(image) > 0:
+			#num += 1 # tymczasowy
+			tmp = image[-1].resize((a.BASE, a.HALF), sample, None, 3.0)
+			destinity.paste(tmp, (0,0), mask = tmp)
+			image.pop()
+			#a.n_pictures -= 1
+			if len(image) > 0:
+				#num += 1 # tymczasowy
+				tmp = image[-1]. resize((a.BASE, a.HALF), sample, None, 3.0)
+				destinity.paste(tmp, (0, a.HALF), mask = tmp)
+				image.pop()
+				#a.n_pictures -= 1
+
+		return destinity, len(image), single
+		
+	def read_images_from_directory(self, files):
+		#global n_pictures
+		images_vertical = []
+		images_horizontal = []
+		if len(files) == 0:
+			print ('Brak plików JPG !')
+			a.cleanup()
+			exit (1)
+		for f in files:
+			image = Image.open(f).convert('RGBA')
+			if image.size[1] > image.size[0]:
+				s = float(image.size[0] / image.size[1]) 
+				if s > 0.6 and s < 0.69:
+					a.BASE = a.BASE_APSC
+					print ("obraz vertical APSC: "+f+"  s:"+str(s))
+					images_vertical.insert(-1, image)
+					#a.n_pictures += 1
+				elif s > 0.7 and s < 0.79:
+					a.BASE = a.BASE_MICRO
+					print ("obraz vertical MICRO: "+f+"  s:"+str(s))
+					images_vertical.insert(-1, image)
+					#a.n_pictures += 1 
+				else:
+					print ("Ver - Niedozwolony rozmiar zdjęcia s: "+str(s) + " Foto: "+f)
+
+			if image.size[0] > image.size[1]:
+				s = float(image.size[0] / image.size[1]) 
+				if s > 1.4 and s <= 1.51:
+					a.BASE = a.BASE_APSC
+					print ("obraz horizontal APSC: "+f+"  s:"+str(s));
+					images_horizontal.insert(-1, image)
+					#a.n_pictures += 1
+				elif s > 1.3 and s < 1.39:
+					a.BASE = a.BASE_MICRO
+					print ("obraz horizontal MICRO: "+f+"  s:"+str(s));
+					images_horizontal.insert(-1, image)
+					#a.n_pictures += 1
+				else:
+					print ("Hor - Niedozwolony rozmiar zdjęcia s: "+str(s) + " Foto: "+f)
+				
+				
+
+		#print ("N_PICTURES: "+str(a.n_pictures))
+		return images_vertical, images_horizontal
+		
+	def cleanup(self):
+		# NIEBEZPIECZNA ! lepiej niczym innym nie nadpisywać tych zmiennych
+		shutil.rmtree(tmp_path)
+
+	def save_vertical_to_horizontal(self, images_vertical, jpg_names):
+		#global count
+		for i in images_vertical[:]:
+			output, list_size, single = a.join_image_to_horizontal(images_vertical, a.create_horizontal_surface())
+			if list_size != 0 or single == True:
+				#output.show()  
+				output.save(str(tmp_path)+SLA+jpg_names[a.count], format='JPEG')
+				a.count += 1
+
+	def save_horizontal_to_vertical(self, images_horizontal, jpg_names):
+		#global count
+		for i in images_horizontal[:]:
+			output, list_size, single  = a.join_image_to_vertical(images_horizontal, a.create_vertical_surface())
+			if list_size != 0 or single == True:
+				#output.show()
+				output.save(str(tmp_path)+SLA+jpg_names[a.count], format='JPEG')
+				a.count += 1
+
+	def save_vertical(self, images_vertica, jpg_names):
+		#global count
+		for i in images_vertical[:]:
+			output = a.put_vertical_image(i)
+			output.save(str(tmp_path)+SLA+jpg_names[a.count], format='JPEG')
+			#output.show()
+			images_vertical.pop()
+			a.count += 1
+
+	def save_horizontal(self, images_horizontal, jpg_names):
+		#global count
+		for i in images_horizontal[:]:
+			output = a.put_horizontal_image(i)
+			output.save(str(tmp_path)+SLA+jpg_names[a.count], format='JPEG')
+			#output.show()
+			images_horizontal.pop()
+			a.count += 1
+
+	def name_jpg_wihout_path(self):
+		files_jpg_names = a.file_exclusion(os.listdir())
+		for f in files_jpg_names:
+			f = f[0] + "file "
+		#print ("Ekstrat: " + str(files_jpg_names))
+		return files_jpg_names
+
+	def at_unslash(self, path):
+		p = path.replace("\\","/")
+		print("PO KONWERSJI: "+p)
+		return p
+		
+	def dump_jpg_list(self, files_jpg_names):
+		print("tmp_list")
+		with open(tmp_list, 'w') as fp:
+			for item in files_jpg_names:
+				# FIXME - to nic nie daje dalej wyrzuca "invalid argument"
+				if platform == "win32":
+					fp.write("file '"+a.at_unslash(str(tmp_path) + SLA +"%s'\r\n" % item))
+				else:
+					# write each item on a new line
+					fp.write("file '"+str(tmp_path) + SLA +"%s'\r\n" % item)
+				
+				print("Zapisany plik do list.txt --> "+item)
+		return files_jpg_names
+a = App()
+jpg_names = a.dump_jpg_list(a.name_jpg_wihout_path())
+if len(sys.argv) == 1 or sys.argv[-1] == '-H':
+	images_vertical, images_horizontal = a.read_images_from_directory(a.get_files())
+	a.save_horizontal(images_horizontal, jpg_names)
+	a.save_vertical_to_horizontal(images_vertical, jpg_names)
+	#print ("_---------------N_PIC: "+str(a.n_pictures))
+
+	print(command)
+	os.popen(command).read()
+elif sys.argv[-1] == '-V':
+	images_vertical, images_horizontal = a.read_images_from_directory(a.get_files())
+	a.save_vertical(images_vertical, jpg_names)
+	a.save_horizontal_to_vertical(images_horizontal, jpg_names)
+	#print ("_---------------N_PIC: "+str(a.n_pictures))
+	print(command)
+	os.popen(command).read()
+else:
+	print ("\n\nUżycie:\n\n Uruchom skrypt w katalogu z plikami JPG\n\n   'vsss -H' | 'vsss'  dla video horyzontalnego\n   'vsss -V'   dla video vertykalnego\n\n \
+	'vsss -h'  aby wyświetlić pomoc i numer wersji.\n		verysimpleslideshow (vsss) ver. "+VER+"\n                SEPT-2023")
+
+
+a.cleanup()