From dbfbf2e2b02d82af9cb7977987b3eac94d498d76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Fil=C3=ADpek?= Date: Mon, 1 Dec 2025 16:20:13 +0100 Subject: [PATCH 1/2] Option to create windows installer --- check_env.sh | 22 +++ .../config_manager.cpython-313.pyc | Bin 12678 -> 13883 bytes src/__pycache__/constants.cpython-313.pyc | Bin 1856 -> 2593 bytes src/config_manager.py | 94 ++++++++--- src/constants.py | 32 +++- .../__pycache__/build_desktop.cpython-313.pyc | Bin 9547 -> 16933 bytes src/logic/build_desktop.py | 155 +++++++++++++++++- .../__pycache__/main_window.cpython-313.pyc | Bin 44990 -> 52061 bytes src/ui/main_window.py | 117 +++++++++++-- 9 files changed, 380 insertions(+), 40 deletions(-) diff --git a/check_env.sh b/check_env.sh index 4d6edc7..ebc4829 100644 --- a/check_env.sh +++ b/check_env.sh @@ -97,5 +97,27 @@ else elif [[ "$OS_TYPE" == "windows" ]]; then echo -e " Windows: Při instalaci Pythonu zaškrtněte 'tcl/tk and IDLE'." fi +fi + +# --- 6. Kontrola Inno Setup (jen Windows) --- +if [[ "$OS_TYPE" == "windows" ]]; then + echo -n "Kontrola Inno Setup (pro instalátor)... " + # Hledáme ISCC.exe v PATH nebo v typických složkách + ISCC_PATH=$(which iscc 2>/dev/null) + if [[ -z "$ISCC_PATH" ]]; then + if [[ -f "/c/Program Files (x86)/Inno Setup 6/ISCC.exe" ]]; then + ISCC_PATH="/c/Program Files (x86)/Inno Setup 6/ISCC.exe" + elif [[ -f "/c/Program Files/Inno Setup 6/ISCC.exe" ]]; then + ISCC_PATH="/c/Program Files/Inno Setup 6/ISCC.exe" + fi + fi + + if [[ -n "$ISCC_PATH" ]]; then + echo -e "${GREEN}OK${NC}" + else + echo -e "${YELLOW}NENALEZENO${NC}" + echo -e " -> Pro vytváření instalátorů nainstalujte Inno Setup: https://jrsoftware.org/isdl.php" + fi +fi exit 0 \ No newline at end of file diff --git a/src/__pycache__/config_manager.cpython-313.pyc b/src/__pycache__/config_manager.cpython-313.pyc index 55bacf30ff86e5bc3ada52432b58f14620c26f06..f3af5a126b2f268314cb08bf179b38d6c876e971 100644 GIT binary patch delta 4068 zcmZ`+4QyN06@JhEiC-Kias2=DnmBcwG)@8uElpcU({>Mo-7z_(!{huplCnR#CFbow&PUn zD*5iY_nv#+Ip>~x&h0|9)gZ&v`sM|dK#v^R1r8CLV32#@QVYg1 ztr6_@6^I>fl8`cFh4SnVlr{Avq= zchkbzs}~KMPNvFoRp(mQxi;M08@d}dHB6%|Z?WY~=0e-uU*A+J+=kC}Ox@0$ zZyz0eTBr9{FRC8ZJJ0KvM%HznRn@w#Wz))3)m+tC*LBu+bav6RR$~aV0=i;I+zB`d zMq+r0djTY6dNwVau9i*L%}&RoXuhONCGMq^h?^xYEzX`vOl70syjTWZhHgMVyjNvoqws^#bcz6B_a?+d_I8_bnVk5rYWB z2!|04A`Aiebro)@PG*v+Og5I9O2CawPGv<5X0ZdI95SV7DSL)S4b}5HgK*nz4Edzd z&CU^n`R8ELTjtx%cpT!*2z>zM>)T`LWzUl{7B{d74L0(OWie2;-mlzJlX^h>3hpiC z2cRWmhU~R?$h}r0`)#sl-LIj!KtYVvCi1>@?It{*F;E_^oE!yW45^a-5MaI3Fz2IRu4$Cy1FM}F-Fos{ zK2-}T^!N>77OjjhAw6U?CwZe?RUcNQ)Iv>ZcSIGcg(dsWQr2u>4i^|Er8z!?N~E-c zw#=#(bYzFucJl*}NihY|7FI?y1}3Z$8cH(}ZAli)t8Y}7Mm$5F(pwg^6$xD@U<#ov ztShDP$~-Ob#bqX3B{Y?3h2SmIRRYF8ZNP(NP^J|^+ZGLlLl@D7;NmTmCQH45g^{)` zMUOue(NM?fQrd78_^T``qV0q77}I0Di)gpzk(+XsrG>hRVk^2Prgx?|1V2ONn1fhN zKYslCC^QcAD3r|O&qu0C;zpq;>KUFHeNXNq>XLym2!x7LsE)AUZT*ePEh9>&u8XL= zjGvo(gskm2urLuCKX&=SLzge`{gKJ>(f-Ncz>)C?KN=hk^$!I3snh39zWKzN%P&sB z-)a8r^yL@dyztgbe2gET2=yO}@afsNo<2J}pGaN)HLODt4^-1MI5cmh9Q}Lw30mTK z-&`Zu>f=wIo8H>Bz_(`4rTKZzAK*h+3Fpov1L7^fDBg*yu?4CsGTv4qA4>bY*&m_)fdEdOk7x3F4L4p{XT=AN2 z!EEL+mb5jGEaZ3ft$5Zsf1Wd5<(%uBbAxl|8=7)l6BK>tj-1X4uL&o=s(qe&ntRsp zuA_7DNZ#UJx3n)FhVpN6ubh5Cb+w^my`iIEY|L3(FFG#PwJV8PV18Z4OHtBQijL0+!m7Ye4;Om#TO*>QPx@v4*H#Tp0 zcW)T?fEukmEBbY#H}CK*>GI9KoRJ4nM(@Qvf2h4N-+j}PZo}5GZVVKcG)&8$tKR)r zy!+qv-m-4wmz4Pi^E(YY^WM&t@bYNh*M7z1y{2VaZe>3WvW&AU@Q)D7aLxi(mop8% zG5yA!xo{*`e{6%ht$Cusf0?_84K zh;j{}-?_eW^!bh`^ekEQO;=W4L+f*U={rMtU8GkQBsoyE#Xzlm68*h3s4%l+kG~J< zQPen3KKAcxMtNf*RwnVg02TZ&k{lVhbj0Jgka%0W!pV~5w%xE9o)l{zwwYMXLELwk z{HOg;kQ$3#q9wB8?v>5nR{GFl@dpU#<86<@^Sg!>EiAdRYoVy;+Z~-f_|lT~+-B_7 z0pTg)jS-zdNOr3D@-7P*3i#PQBpujYgXI(IJ(eBOLS6~nvEV||hJeQ+zh;gi6-Kxn z;Z6i<+g(T{5%AR_-i?q&xDVlL2oE4Uitrf1_YfXOcoJb1;aLEwF&c%JVYWRv6^&)H zV)Eo%Hj#-&FEJwONG%ZYClLkw{gio_{IYY0W{2AG*$_+K>)fv$WYw0>#uS9_a@W&M z$nSU1Ux4B)ndq9()0|e1Vg|_5UHdzJRFWvZfK>TYl5XG3YoDK4TE+#{U7+B~_9D delta 2883 zcmaJ@eQZF)@F*HutsL@=L7%(KZd!Ic@ z*qVva7W%P3Pd8Cjte|S0qA63SY*M9etERxFO;eQ&CM=J&(zIzqnx?dLo3#GZd+xKH zk4}4k{N8!@o_p>&zw=?gH~IW{?Sq;cgTS8Zv)w7J_e!muY`fw)sFj4HWJH35p%G+b zqgej%b)fG0=V)VyC@bYRHJA1Au<59|vSF!gjI=lQ9koQokV-jAZFZqeh-#cdR9jiI zpCDe{eN>3t$2+_=aE|NWF5TUW^32R&~g4mbwNXr#E=E$TOTCRs(=F@Jp8&r1}eCjB0fEoT_MyvrNacG;=CBo>T0KN`XAajibqI zB6pG=WS=tD8RG$~;ji@rBo3_&4-*&s%;f;N;jRyT<}OD{b)@iFsyH;bT55~2)h_~^(8W3$ZFkT#bqA?x<)aFj4jTK zu@qE^5!~Jo11^oicdaejEEDB? zp-|U2d+yS?*_lf-SD(FI7g*8lnH@Yfpc-5=<ya!$$K zhQz^{mJoRx=37EaU5ll<_P~$2jL;)xf>AW4Gzd3FpFxYfLC~r~9aamYj+gTX(nH!G zvTr#6J$?&FtuE#pt4o!hz?ID%@N8=uoWWX~YK+thQFWiXJntppD_f!j9tm~@R)^l0 zIKav!Q6&gLVN6_I=d(#Tj@X#7ApG8TSZ>hhE(n8zD1@CKQ79XvD=J{;aAd5+~%Y#3x|QcmV% zkHk7a^5pSSk96$pq?FCvx^X%)olFO$5md>~oJvXQg!Hw=pO2r+OfSv{ygJI0!MkaF z=_!?i19Ba)n3`hUMDlndKZ%2cUtQFd1bGd|sOVTTZQ{rBaILdn_fxhZUlyRyxo_V+ zWBro3_Z|N`?xjbLFEyOFV?0^#4_s|oHhK$2(_Lfpva$J&(Oqb4TQatNsuzro>$=<3 zoU_bdMo9AX2@@rZBi||B`Q|W<)=X%UU`zW5;4Q~c_?d48kW;aZy|5GCL z+o=9LgS90A{@y*>|KQ>o_^6xxg7+rZyPO1hi_eF@0E*k|2taFJAoDj{_G%5R`6`Vp zLT{g=1_v7(M|M17fiL$xIn#uq4FR*H4BNdZ9YQ#a5JTX>j-zxO0f#D0BRq|eM>vb{ z4TSRuFCe^xFpKai!gmm^GALT&aXFXB`BLNYL@q~D$MU(P9FNZl6n&)p4<7ylq6qj0 zNj?v;{#H%1rsw|0wO>2IqZmTE&u=k diff --git a/src/__pycache__/constants.cpython-313.pyc b/src/__pycache__/constants.cpython-313.pyc index f30d72c319c1b2fc031cc249ed09a73b2b0b61ff..28a6693299a12a030837ae7b80af3e4c40547734 100644 GIT binary patch delta 845 zcmZWn%Wl&^6m^grN}7~3FFSRcq=mkC6(J-LJCmAX>Nr)#5o%@0a-C6X)fq?QL{%f9 zbioG{b<-s*kywCOu;mlX&Kj}f2P*Xk7^fyGFw(WpIdktl$CAHKf5@#|q*4in9`xzH z{ga|!A^CH15xDsLZe>RYd7K9YTmT&A0FQZ4#6>WRXMunPFo);BJe~(7TmofW)(fDb zb6`Q|X%%VB(h|U;J_l~;^We5#0!w-sEI&-(N_%B(^~>8g?2x1_49y-iY~=M!$AOqk z+X%Tvx4-Au-ah4%Bi_djNsf?XTM&7W%#7HfJuq?0usdcO67H(xb?Cn6;;&w>cjQ2l z4ts}&<#xIldY4W=P#hxzYStO2z42TO-GYPpBrI_@I`@jA71``F4rZ{6&6jd0-u`cT&v zzOoa$u_4KANjpZhA&Ht~$STl8MUfgL6RNVR){X7vb43O(sg@jT&4xnKW2VSeNd*$g zkCoT*uGrWxvIs9)3Xgi8@nQG);t=G025&&{tz2cyWV9VH$z?N3u zz7kdu)y*a~1tc|gm8*0zyCJ<0n~HY%O;mXyZ+>JhnA5%Zt0{^8iZNOq8$10Lw_?Gm zaJ@7j1XaNjkZQOzZABoh2zxu zBs0OCB?C5nvKX+rlf8f~o;?cK^7~APo(3#`wj83z0bB6-)qtJxv(L`+Qwi?c4 k7$@)L@Z;77ssX7hZeo}$#+l6cU~(0w9D5^IktR?O0L!xz_5c6? diff --git a/src/config_manager.py b/src/config_manager.py index 98f8bef..d226752 100644 --- a/src/config_manager.py +++ b/src/config_manager.py @@ -4,7 +4,7 @@ PRESET_MANUAL, KEY_TRANSLATIONS_PATH, KEY_BUILD_TYPE, KEY_BUILD_MODE, KEY_FLAVOR, KEY_ENV, KEY_BUMP_STRATEGY, BUMP_PATCH, KEY_GIT_PUSH, KEY_DISABLE_OBFUSCATION, KEY_UPLOAD_SYMBOLS, KEY_INSTALL_COCOAPODS, - KEY_CHECK_SQLITE_WEB + KEY_CHECK_SQLITE_WEB, KEY_CREATE_INSTALLER, DEFAULT_INNO_CONFIG ) SRC_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -46,25 +46,30 @@ def add_project(self, name, path): """Přidá projekt s výchozí strukturou.""" if 'projects' not in self.config: self.config['projects'] = {} + + default_preset = { + KEY_BUILD_TYPE: "apk", + KEY_BUILD_MODE: "release", + KEY_FLAVOR: "", + KEY_ENV: "", + KEY_BUMP_STRATEGY: BUMP_PATCH, + KEY_GIT_PUSH: True, + KEY_DISABLE_OBFUSCATION: False, + KEY_UPLOAD_SYMBOLS: True, + KEY_INSTALL_COCOAPODS: True, + KEY_CHECK_SQLITE_WEB: False, + KEY_CREATE_INSTALLER: True + } + + default_preset.update(DEFAULT_INNO_CONFIG) self.config['projects'][name] = { "path": path, "flavors": [], "envs": [], - "last_selected_build_preset": "Ručně", + "last_selected_build_preset": PRESET_MANUAL, "build_presets": { - PRESET_MANUAL: { - KEY_BUILD_TYPE: "apk", - KEY_BUILD_MODE: "release", - KEY_FLAVOR: "", - KEY_ENV: "", - KEY_BUMP_STRATEGY: BUMP_PATCH, # Zde jsi měl BUMP_PATCH, tak to nechávám - KEY_GIT_PUSH: True, - KEY_DISABLE_OBFUSCATION: False, - KEY_UPLOAD_SYMBOLS: True, - KEY_INSTALL_COCOAPODS: True, - KEY_CHECK_SQLITE_WEB: False - } + PRESET_MANUAL: default_preset }, "nbsp_settings": { KEY_TRANSLATIONS_PATH: "assets/translations" @@ -181,7 +186,7 @@ def save_project_list(self, project_name, list_name, new_list): def get_project_build_presets(self, project_name): """ Vrátí slovník všech build presetů pro daný projekt. - Vždy zajistí přítomnost klíče PRESET_MANUAL ('Ručně'). + PROVÁDÍ AUTOMATICKOU MIGRACI chybějících klíčů a OPRAVU poškozených dat. """ project_data = self._get_project(project_name) default_presets = {PRESET_MANUAL: {}} @@ -191,22 +196,63 @@ def get_project_build_presets(self, project_name): presets = project_data.get('build_presets', default_presets) - # 1. Pojistka proti špatnému typu + # 1. Kontrola, zda je 'presets' slovník if not isinstance(presets, dict): - print(f"OPRAVA: 'build_presets' pro '{project_name}' byl poškozen. Resetuji na výchozí.") project_data['build_presets'] = default_presets self.save_config() return default_presets + + # --- MIGRACE A OPRAVA DAT --- + migration_needed = False + + # Použijeme list(presets.keys()) abychom mohli bezpečně modifikovat slovník + for preset_name in list(presets.keys()): + settings = presets[preset_name] - # 2. Pojistka: VŽDY zajistit existenci "Ručně" - # I když je v configu smazaný nebo prázdný, v paměti (a pro UI) ho chceme vidět. - if PRESET_MANUAL not in presets: - presets[PRESET_MANUAL] = {} - # Volitelně můžeme rovnou uložit opravu do souboru: - # self.save_project_build_preset(project_name, PRESET_MANUAL, {}) + # --- OPRAVA CHYBY (TUPLE) --- + # Pokud hodnota není slovník (např. je to tuple, list nebo string), opravíme ji + if not isinstance(settings, dict): + print(f"OPRAVA: Preset '{preset_name}' byl poškozen (typ {type(settings)}). Resetuji.") + + # Vytvoříme nový čistý slovník + new_settings = { + KEY_BUILD_TYPE: "apk", + KEY_BUILD_MODE: "release", + KEY_FLAVOR: "", + KEY_ENV: "", + KEY_BUMP_STRATEGY: BUMP_PATCH, + KEY_GIT_PUSH: True, + KEY_DISABLE_OBFUSCATION: False, + KEY_UPLOAD_SYMBOLS: True, + KEY_INSTALL_COCOAPODS: True, + KEY_CHECK_SQLITE_WEB: False, + KEY_CREATE_INSTALLER: False + } + new_settings.update(DEFAULT_INNO_CONFIG) + + # Nahradíme poškozená data novým slovníkem + presets[preset_name] = new_settings + settings = new_settings # Aktualizujeme lokální proměnnou pro další kontroly + migration_needed = True + # ----------------------------- + + # 1. Klíč pro zapnutí instalátoru + if KEY_CREATE_INSTALLER not in settings: + settings[KEY_CREATE_INSTALLER] = False + migration_needed = True + + # 2. Klíče pro konfiguraci Inno Setupu + for key, default_val in DEFAULT_INNO_CONFIG.items(): + if key not in settings: + settings[key] = default_val + migration_needed = True + + if migration_needed: + print(f"MIGRACE: Doplněny/Opraveny klíče pro projekt '{project_name}'.") + self.save_config() + # ------------------------------------------- return presets - # --- KONEC OPRAVENÉ METODY --- def save_project_build_preset(self, project_name, preset_name, settings): """Uloží nebo přepíše nastavení pro jeden build preset v rámci projektu.""" diff --git a/src/constants.py b/src/constants.py index d1414a8..ce32488 100644 --- a/src/constants.py +++ b/src/constants.py @@ -48,7 +48,6 @@ KEY_UPLOAD_SYMBOLS = "upload_symbols" KEY_INSTALL_COCOAPODS = "install_cocoapods" KEY_CHECK_SQLITE_WEB = "check_sqlite_web" - KEY_BUMP_STRATEGY = "bump_strategy" # Klíče pro jednotlivé strategie @@ -56,4 +55,33 @@ BUMP_MAJOR = "major" BUMP_MINOR = "minor" BUMP_PATCH = "patch" -BUMP_BUILD = "build" \ No newline at end of file +BUMP_BUILD = "build" + +# --- NOVÉ KONSTANTY PRO INNO SETUP --- +KEY_CREATE_INSTALLER = "create_installer" + +# Klíče parametrů +KEY_INNO_PUBLISHER = "inno_publisher" +KEY_INNO_URL = "inno_url" +KEY_INNO_LICENSE = "inno_license" +KEY_INNO_WIZARD_IMAGE = "inno_wizard_image" +KEY_INNO_WIZARD_SMALL_IMAGE = "inno_wizard_small_image" +KEY_INNO_WIZARD_STYLE = "inno_wizard_style" +KEY_INNO_COMPRESSION = "inno_compression" +KEY_INNO_TASK_DESKTOP = "inno_task_desktop" +KEY_INNO_LANGUAGES = "inno_languages" +KEY_INNO_ICON = "inno_icon" + +# Defaultní hodnoty (pro migraci a nové projekty) +DEFAULT_INNO_CONFIG = { + KEY_INNO_PUBLISHER: "My Company", + KEY_INNO_URL: "", + KEY_INNO_LICENSE: "", + KEY_INNO_WIZARD_IMAGE: "", + KEY_INNO_WIZARD_SMALL_IMAGE: "", + KEY_INNO_WIZARD_STYLE: "modern", + KEY_INNO_COMPRESSION: "lzma", + KEY_INNO_TASK_DESKTOP: True, + KEY_INNO_LANGUAGES: "english, czech", + KEY_INNO_ICON: "windows/runner/resources/app_icon.ico" +} \ No newline at end of file diff --git a/src/logic/__pycache__/build_desktop.cpython-313.pyc b/src/logic/__pycache__/build_desktop.cpython-313.pyc index 36c1ac7a254a15a34de7dd3feb4dcfe3ee30a4fc..1d39c8c5929ad5de4809f7e0ae8933ee2987eb28 100644 GIT binary patch literal 16933 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 Q-1PJ<>1_!vd}aH80UG|n-v9sr delta 3025 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 delta 7408 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 CmrIEN diff --git a/src/ui/main_window.py b/src/ui/main_window.py index 2dec0af..70c0b22 100644 --- a/src/ui/main_window.py +++ b/src/ui/main_window.py @@ -18,7 +18,12 @@ KEY_FLAVOR, KEY_ENV, KEY_BUMP_STRATEGY, BUMP_NONE, BUMP_MAJOR, BUMP_MINOR, BUMP_PATCH, BUMP_BUILD, KEY_GIT_PUSH, KEY_DISABLE_OBFUSCATION, KEY_UPLOAD_SYMBOLS, KEY_INSTALL_COCOAPODS, - KEY_CHECK_SQLITE_WEB + KEY_CHECK_SQLITE_WEB, KEY_CREATE_INSTALLER, + KEY_INNO_PUBLISHER, KEY_INNO_URL, KEY_INNO_LICENSE, + KEY_INNO_WIZARD_IMAGE, KEY_INNO_WIZARD_SMALL_IMAGE, + KEY_INNO_WIZARD_STYLE, KEY_INNO_COMPRESSION, + KEY_INNO_TASK_DESKTOP, KEY_INNO_LANGUAGES, KEY_INNO_ICON, + DEFAULT_INNO_CONFIG ) class MainWindow(tk.Toplevel): @@ -36,7 +41,7 @@ def __init__(self, parent, config_manager, current_project_name): self._switch_to_project(current_project_name) - self._is_loading_preset = False # Vlajka, která brání ukládání během načítání + self._is_loading_preset = True # Vlajka, která brání ukládání během načítání # --- ZMĚNA: Oddělené proměnné --- self.build_vars = {} @@ -210,16 +215,26 @@ def _initialize_build_vars(self): value=manual_settings.get(KEY_CHECK_SQLITE_WEB, False) ), } + + # Inicializace proměnných pro Inno Setup (s defaulty z konstant) + self.build_vars.update({ + KEY_CREATE_INSTALLER: tk.BooleanVar(value=True), + + KEY_INNO_PUBLISHER: tk.StringVar(value=DEFAULT_INNO_CONFIG[KEY_INNO_PUBLISHER]), + KEY_INNO_URL: tk.StringVar(value=DEFAULT_INNO_CONFIG[KEY_INNO_URL]), + KEY_INNO_LICENSE: tk.StringVar(value=DEFAULT_INNO_CONFIG[KEY_INNO_LICENSE]), + KEY_INNO_WIZARD_IMAGE: tk.StringVar(value=DEFAULT_INNO_CONFIG[KEY_INNO_WIZARD_IMAGE]), + KEY_INNO_WIZARD_SMALL_IMAGE: tk.StringVar(value=DEFAULT_INNO_CONFIG[KEY_INNO_WIZARD_SMALL_IMAGE]), + KEY_INNO_WIZARD_STYLE: tk.StringVar(value=DEFAULT_INNO_CONFIG[KEY_INNO_WIZARD_STYLE]), + KEY_INNO_COMPRESSION: tk.StringVar(value=DEFAULT_INNO_CONFIG[KEY_INNO_COMPRESSION]), + KEY_INNO_TASK_DESKTOP: tk.BooleanVar(value=DEFAULT_INNO_CONFIG[KEY_INNO_TASK_DESKTOP]), + KEY_INNO_LANGUAGES: tk.StringVar(value=DEFAULT_INNO_CONFIG[KEY_INNO_LANGUAGES]), + KEY_INNO_ICON: tk.StringVar(value=DEFAULT_INNO_CONFIG[KEY_INNO_ICON]), + }) # 3. Až teď zapneme sledování změn (trace) for key, var in self.build_vars.items(): - if key == KEY_PRESET: - continue - # Sledování strategie povýšení (ta se ukládá přes bind, ale pro jistotu ji necháme netracovanou nebo tracovanou, - # zde raději netracujeme, protože dropdown má svůj bind) - if key == KEY_BUMP_STRATEGY: - continue - + if key == KEY_PRESET or key == KEY_BUMP_STRATEGY: continue var.trace_add("write", self._save_current_build_settings) def _create_checkbox(self, parent, text, var_key, **pack_kwargs): @@ -309,15 +324,61 @@ def _create_build_tab(self): KEY_UPLOAD_SYMBOLS, padx=(20, 0) ) - + self.web_frame = ttk.LabelFrame(frame, text="Web", padding=5) self.web_frame.grid(row=8, column=0, columnspan=3, sticky="ew", padx=5, pady=5) + self.web_check = self._create_checkbox( self.web_frame, "Zkontrolovat sqlite3.wasm & sqflite_sw.js", KEY_CHECK_SQLITE_WEB ) + + # --- SEKCE WINDOWS INSTALLER --- + self.windows_frame = ttk.LabelFrame(frame, text="Windows", padding=5) + self.windows_frame.grid(row=8, column=0, columnspan=3, sticky="ew", padx=5, pady=5) + self.installer_check = self._create_checkbox( + self.windows_frame, "Vytvořit instalátor (Inno Setup)", KEY_CREATE_INSTALLER + ) + + # Frame pro detailní nastavení (bude se schovávat) + self.inno_settings_frame = ttk.Frame(self.windows_frame) + self.inno_settings_frame.pack(fill="x", expand=True, padx=10, pady=5) + + # Grid layout pro nastavení + f = self.inno_settings_frame + f.columnconfigure(1, weight=1) + f.columnconfigure(4, weight=1) + + # 1. Sloupec + self._create_entry_row(f, 0, "Publisher:", KEY_INNO_PUBLISHER) + self._create_entry_row(f, 1, "URL:", KEY_INNO_URL) + self._create_file_row(f, 2, "Licence (.txt):", KEY_INNO_LICENSE, [("Text files", "*.txt")]) + self._create_file_row(f, 3, "Ikona (.ico):", KEY_INNO_ICON, [("Icon files", "*.ico")]) + + # 2. Sloupec (vedle) - Styl a Obrázky + ttk.Label(f, text="Styl:").grid(row=0, column=3, sticky="w", padx=(20, 5)) + ttk.Combobox(f, textvariable=self.build_vars[KEY_INNO_WIZARD_STYLE], + values=["modern", "classic"], state="readonly").grid(row=0, column=4, sticky="ew") + + ttk.Label(f, text="Komprese:").grid(row=1, column=3, sticky="w", padx=(20, 5)) + ttk.Combobox(f, textvariable=self.build_vars[KEY_INNO_COMPRESSION], + values=["lzma", "zip", "bzip"], state="readonly").grid(row=1, column=4, sticky="ew") + + self._create_file_row(f, 2, "Velký obrázek:", KEY_INNO_WIZARD_IMAGE, [("Images", "*.bmp")], col_offset=3) + self._create_file_row(f, 3, "Malý obrázek:", KEY_INNO_WIZARD_SMALL_IMAGE, [("Images", "*.bmp")], col_offset=3) + + # Spodní sekce (Jazyky a Checkboxy) + ttk.Label(f, text="Jazyky (oddělené čárkou):").grid(row=4, column=0, sticky="w", pady=(10,0)) + ttk.Entry(f, textvariable=self.build_vars[KEY_INNO_LANGUAGES]).grid(row=4, column=1, columnspan=4, sticky="ew", pady=(10,0)) + + ttk.Checkbutton( + f, + text="Vytvořit zástupce na ploše", + variable=self.build_vars[KEY_INNO_TASK_DESKTOP], + command=self._save_current_build_settings + ).grid(row=5, column=0, columnspan=5, sticky="w", pady=(5,0)) frame.grid_rowconfigure(9, weight=1, minsize=150) self.build_console = scrolledtext.ScrolledText(frame, wrap=tk.WORD, state="disabled") self.build_console.grid(row=9, column=0, columnspan=3, sticky="nsew", pady=(5, 10)) @@ -451,6 +512,30 @@ def _remove_from_list(self, list_name, combobox): self._update_dynamic_list(combobox, list_name) combobox.set("") + def _create_entry_row(self, parent, row, label, var_key, col_offset=0): + ttk.Label(parent, text=label).grid(row=row, column=0+col_offset, sticky="w", padx=5, pady=2) + ttk.Entry(parent, textvariable=self.build_vars[var_key]).grid(row=row, column=1+col_offset, sticky="ew", padx=5, pady=2) + + def _create_file_row(self, parent, row, label, var_key, file_types, col_offset=0): + ttk.Label(parent, text=label).grid(row=row, column=0+col_offset, sticky="w", padx=5, pady=2) + + frame = ttk.Frame(parent) + frame.grid(row=row, column=1+col_offset, sticky="ew", padx=5, pady=2) + frame.columnconfigure(0, weight=1) + + ttk.Entry(frame, textvariable=self.build_vars[var_key]).grid(row=0, column=0, sticky="ew") + ttk.Button(frame, text="...", width=3, + command=lambda: self._browse_file(var_key, file_types)).grid(row=0, column=1, padx=(5,0)) + + def _browse_file(self, var_key, file_types): + path = filedialog.askopenfilename(filetypes=file_types, initialdir=os.getcwd()) + if path: + try: + rel_path = os.path.relpath(path, os.getcwd()) + self.build_vars[var_key].set(rel_path) + except ValueError: + self.build_vars[var_key].set(path) + def _update_build_ui_state(self, *args): try: build_type = self.build_vars[KEY_BUILD_TYPE].get() @@ -477,10 +562,18 @@ def _update_build_ui_state(self, *args): # Logika pro Web if build_type == "web": - self.web_frame.grid() + self.web_frame.grid() + self.windows_frame.grid_remove() # Skrýt Windows + self.build_vars[KEY_CREATE_INSTALLER].set(False) + elif build_type == "windows": + self.web_frame.grid_remove() + self.windows_frame.grid() # Zobrazit Windows + self.build_vars[KEY_CHECK_SQLITE_WEB].set(False) else: - self.web_frame.grid_remove() + self.web_frame.grid_remove() + self.windows_frame.grid_remove() self.build_vars[KEY_CHECK_SQLITE_WEB].set(False) + self.build_vars[KEY_CREATE_INSTALLER].set(False) except (AttributeError, tk.TclError): pass From 66472faa9b9f51c5664b23c836216caa638e00e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Fil=C3=ADpek?= Date: Wed, 17 Dec 2025 10:04:24 +0100 Subject: [PATCH 2/2] WIP --- .../config_manager.cpython-313.pyc | Bin 13883 -> 13883 bytes src/__pycache__/constants.cpython-313.pyc | Bin 2593 -> 2593 bytes .../__pycache__/build_android.cpython-313.pyc | Bin 7637 -> 7637 bytes .../__pycache__/build_common.cpython-313.pyc | Bin 19248 -> 19711 bytes .../__pycache__/build_desktop.cpython-313.pyc | Bin 16933 -> 16933 bytes src/logic/build_common.py | 22 +++++++++++++++++- .../__pycache__/main_window.cpython-313.pyc | Bin 52061 -> 52061 bytes 7 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/__pycache__/config_manager.cpython-313.pyc b/src/__pycache__/config_manager.cpython-313.pyc index f3af5a126b2f268314cb08bf179b38d6c876e971..3bfe96e572465c072851dbc21d2a0dbf10ebaa5f 100644 GIT binary patch delta 20 acmdm;vpa|TGcPX}0}zN8I&S1PFarQX(FI%p delta 20 acmdm;vpa|TGcPX}0}%XJue*`kzzhIO2nJ^W diff --git a/src/__pycache__/constants.cpython-313.pyc b/src/__pycache__/constants.cpython-313.pyc index 28a6693299a12a030837ae7b80af3e4c40547734..b52de0431e3347092da036e40c4abb88e70e0a18 100644 GIT binary patch delta 20 acmZ1|vQUKkGcPX}0}zN8I&S0^;{pIPH3TvM delta 20 acmZ1|vQUKkGcPX}0}$k`(cQ=`#svU2lmxH< diff --git a/src/logic/__pycache__/build_android.cpython-313.pyc b/src/logic/__pycache__/build_android.cpython-313.pyc index f625f582eabbbfc7fd77739d9aff6e5156e54e4f..5f7219d7e708a170d88dd59a7a23f273af92fd14 100644 GIT binary patch delta 20 acmca=ebt)#GcPX}0}zN8I&S1XB?|ySTcvdB?|yTNCmF| diff --git a/src/logic/__pycache__/build_common.cpython-313.pyc b/src/logic/__pycache__/build_common.cpython-313.pyc index 7b0bc525f4e9003709f89a88b3ec4db6ed415711..64ae33c0c55f74d459816155b6de45520d3f9f9b 100644 GIT binary patch delta 2823 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 diff --git a/src/logic/build_common.py b/src/logic/build_common.py index ce227de..bff497e 100644 --- a/src/logic/build_common.py +++ b/src/logic/build_common.py @@ -5,6 +5,8 @@ import platform import time import glob +import sys # <--- PŘIDÁNO +import shutil # <--- PŘIDÁNO from ..constants import ADT_PROJECT_CONFIG_FILENAME @@ -18,6 +20,22 @@ def execute_command(command, logger, title="", working_dir=None, log_stdout=True if title: logger.header(f"\n--- {title} ---") + # --- FIX PRO WINDOWS FLUTTER (ZAČÁTEK) --- + # Pokud jsme na Windows a voláme 'flutter', musíme volat 'flutter.bat' + if sys.platform == "win32" and command and command[0] == "flutter": + # Zkusíme najít plnou cestu k flutter.bat + flutter_bat = shutil.which("flutter.bat") + + if flutter_bat: + command[0] = flutter_bat + else: + # Fallback: pokud se nenajde přes which, zkusíme prostě přidat příponu + command[0] = "flutter.bat" + + # Jen pro debug, abyste viděli, že se to děje (můžete smazat) + # logger.info(f"Windows detekován: Příkaz 'flutter' přepsán na '{command[0]}'") + # --- FIX PRO WINDOWS FLUTTER (KONEC) --- + logger.info(f"🔧 Spouštím v '{working_dir or os.getcwd()}': {' '.join(command)}") startupinfo = None @@ -44,6 +62,9 @@ def execute_command(command, logger, title="", working_dir=None, log_stdout=True except FileNotFoundError: logger.error(f"PŘÍKAZ NENALEZEN: Příkaz '{command[0]}' nebyl nalezen.") + # Tip pro uživatele + if "flutter" in command[0]: + logger.error("TIP: Ujistěte se, že máte Flutter přidaný v systémové PATH.") return -1, f"PŘÍKAZ NENALEZEN: {command[0]}" except Exception as e: logger.error(f"CHYBA PŘI VYKONÁNÍ: {e}") @@ -252,7 +273,6 @@ def perform_git_push(logger, params, version_name, build_number, actions_perform else: logger.warn("Git commit selhal (možná nebyly žádné změny k commitu).") -# --- NOVÁ FUNKCE (přesunuta z android a zobecněna) --- def get_package_name(logger, env_vars): """Najde packageName v env_vars (z adt_tools_config.env).""" package_name = env_vars.get("PACKAGE_NAME") diff --git a/src/ui/__pycache__/main_window.cpython-313.pyc b/src/ui/__pycache__/main_window.cpython-313.pyc index 986f845abda256db4573e725a22d7e5fb8123e40..a774470d4f35403ef2e9ca6015067ef6b2d2e8ee 100644 GIT binary patch delta 22 ccmcaRjrs00X710tyj%=GAYSOWkvr%#090rOu>b%7 delta 22 ccmcaRjrs00X710tyj%=GaBZXRM(&`~09w5VoB#j-