migrazione verso gitea

This commit is contained in:
2026-03-31 19:15:33 +02:00
parent 8806d598eb
commit f6a5b1b29f
118 changed files with 17197 additions and 459 deletions

11
docs/Makefile Normal file
View File

@@ -0,0 +1,11 @@
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
.PHONY: html clean
html:
$(SPHINXBUILD) -b html $(SOURCEDIR) $(BUILDDIR)/html
clean:
$(SPHINXBUILD) -M clean $(SOURCEDIR) $(BUILDDIR)

4
docs/_build/html/.buildinfo vendored Normal file
View File

@@ -0,0 +1,4 @@
# Sphinx build info version 1
# This file records the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 5114b3e0495dd40f0c4652b28de89aa4
tags: 645f666f9bcd5a90fca523b33c5a78b7

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
docs/_build/html/.doctrees/index.doctree vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,77 @@
Riferimento API
===============
La sezione seguente usa ``autodoc`` per estrarre docstring direttamente dai
moduli Python principali del progetto.
main.py
-------
.. automodule:: main
:members:
:undoc-members:
:show-inheritance:
async_msssql_query.py
---------------------
.. automodule:: async_msssql_query
:members:
:undoc-members:
:show-inheritance:
gestione_aree_frame_async.py
----------------------------
.. automodule:: gestione_aree_frame_async
:members:
:undoc-members:
:show-inheritance:
layout_window.py
----------------
.. automodule:: layout_window
:members:
:undoc-members:
:show-inheritance:
reset_corsie.py
---------------
.. automodule:: reset_corsie
:members:
:undoc-members:
:show-inheritance:
view_celle_multiple.py
----------------------
.. automodule:: view_celle_multiple
:members:
:undoc-members:
:show-inheritance:
search_pallets.py
-----------------
.. automodule:: search_pallets
:members:
:undoc-members:
:show-inheritance:
gestione_pickinglist.py
-----------------------
.. automodule:: gestione_pickinglist
:members:
:undoc-members:
:show-inheritance:
prenota_sprenota_sql.py
-----------------------
.. automodule:: prenota_sprenota_sql
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,51 @@
# Architettura Complessiva
Questa pagina collega i moduli principali del progetto in una vista unica,
partendo dal launcher fino ai moduli GUI e al livello infrastrutturale async/DB.
## Vista architetturale
```{mermaid}
flowchart TD
Main["main.py"] --> Launcher["Launcher"]
Main --> Loop["async_loop_singleton.get_global_loop()"]
Main --> DB["AsyncMSSQLClient"]
Launcher --> Reset["reset_corsie.py"]
Launcher --> Layout["layout_window.py"]
Launcher --> Ghost["view_celle_multiple.py"]
Launcher --> Search["search_pallets.py"]
Launcher --> Picking["gestione_pickinglist.py"]
Reset --> Runner["gestione_aree_frame_async.AsyncRunner"]
Layout --> Runner
Ghost --> Runner
Search --> Runner
Picking --> Runner
Runner --> Loop
Runner --> DB
Picking --> SP["prenota_sprenota_sql.py"]
SP --> DB
DB --> SQL["SQL Server / Mediseawall"]
```
## Flusso applicativo generale
```{mermaid}
flowchart LR
User["Utente"] --> MainWin["Launcher"]
MainWin --> Module["Finestra modulo"]
Module --> AsyncReq["AsyncRunner.run(...)"]
AsyncReq --> DbClient["AsyncMSSQLClient"]
DbClient --> SqlServer["Database SQL Server"]
SqlServer --> Callback["Callback _ok/_err"]
Callback --> Module
```
## Osservazioni
- `main.py` centralizza il loop asincrono e il client database condiviso.
- I moduli GUI si concentrano sulla UI e delegano query e task lunghi a `AsyncRunner`.
- `gestione_pickinglist.py` è l'unico modulo che passa anche da `prenota_sprenota_sql.py` per la logica di prenotazione.
- La cartella `docs/flows/` contiene la vista dettagliata modulo per modulo.

View File

@@ -0,0 +1,27 @@
# Flow Diagrams
Questa cartella contiene schemi di flusso e schemi di chiamata dei moduli
principali avviati da `main.py`.
I diagrammi sono scritti in Mermaid, quindi possono essere:
- letti direttamente nei file Markdown;
- renderizzati da molti editor Git/Markdown;
- inclusi in una futura documentazione Sphinx o MkDocs.
## Indice
- [main](./main_flow.md)
- [layout_window](./layout_window_flow.md)
- [reset_corsie](./reset_corsie_flow.md)
- [view_celle_multiple](./view_celle_multiple_flow.md)
- [search_pallets](./search_pallets_flow.md)
- [gestione_pickinglist](./gestione_pickinglist_flow.md)
- [infrastruttura async/db](./async_db_flow.md)
## Convenzioni
- I diagrammi descrivono il flusso applicativo ad alto livello.
- Non rappresentano ogni singola riga di codice.
- I nodi `AsyncRunner` e `query_json` evidenziano i passaggi asincroni più
importanti tra interfaccia e database.

View File

@@ -0,0 +1,39 @@
# Infrastruttura Async / DB
## Scopo
Questo diagramma descrive il flusso comune usato da tutti i moduli GUI quando
eseguono una query sul database.
## Flusso trasversale
```{mermaid}
flowchart TD
A["Evento UI (click / selezione / ricerca)"] --> B["Metodo finestra"]
B --> C["AsyncRunner.run(awaitable)"]
C --> D["Coroutines sul loop globale"]
D --> E["AsyncMSSQLClient.query_json() / exec()"]
E --> F["SQL Server"]
F --> G["Risultato query"]
G --> H["Future completata"]
H --> I["Callback _ok / _err su thread Tk"]
I --> J["Aggiornamento widget"]
```
## Relazioni principali
```{mermaid}
flowchart LR
Main["main.py"] --> Loop["get_global_loop()"]
Main --> DB["AsyncMSSQLClient"]
Windows["Moduli GUI"] --> Runner["AsyncRunner"]
Runner --> Loop
Runner --> DB
DB --> SQL["SQL Server Mediseawall"]
```
## Note
- Il loop asincrono è condiviso tra tutte le finestre.
- Il client DB è condiviso e creato una sola volta nel launcher.
- I callback che aggiornano la UI rientrano sempre sul thread Tk.

View File

@@ -0,0 +1,39 @@
# `async_loop_singleton.py`
## Scopo
Questo modulo mantiene un loop asyncio globale e condiviso, eseguito su un
thread dedicato.
## Flusso
```{mermaid}
flowchart TD
A["Chiamata a get_global_loop()"] --> B{"Loop gia presente?"}
B -- Si --> C["Ritorna loop esistente"]
B -- No --> D["Crea Event ready"]
D --> E["Avvia thread daemon"]
E --> F["_run()"]
F --> G["new_event_loop()"]
G --> H["set_event_loop(loop)"]
H --> I["ready.set()"]
I --> J["loop.run_forever()"]
J --> K["Ritorna loop al chiamante"]
```
## Chiusura
```{mermaid}
flowchart TD
A["stop_global_loop()"] --> B{"Loop attivo?"}
B -- No --> C["Nessuna azione"]
B -- Si --> D["call_soon_threadsafe(loop.stop)"]
D --> E["join del thread"]
E --> F["Azzera riferimenti globali"]
```
## Note
- E un helper minimale usato da `main.py`.
- Il modulo esiste separato da `gestione_aree_frame_async.py`, ma concettualmente
svolge lo stesso ruolo di gestione del loop condiviso.

View File

@@ -0,0 +1,41 @@
# `async_msssql_query.py`
## Scopo
Questo modulo centralizza la costruzione del DSN SQL Server e l'accesso
asincrono al database tramite `AsyncMSSQLClient`.
## Flusso di utilizzo
```{mermaid}
flowchart TD
A["main.py o modulo chiamante"] --> B["make_mssql_dsn(...)"]
B --> C["Crea stringa mssql+aioodbc"]
C --> D["AsyncMSSQLClient(dsn)"]
D --> E["query_json(...) o exec(...)"]
E --> F["_ensure_engine()"]
F --> G{"Engine gia creato?"}
G -- No --> H["create_async_engine(..., NullPool, loop corrente)"]
G -- Si --> I["Riusa engine esistente"]
H --> J["execute(text(sql), params)"]
I --> J
J --> K["Normalizza rows/columns"]
K --> L["Ritorna payload JSON-friendly"]
```
## Schema di chiamata
```{mermaid}
flowchart LR
DSN["make_mssql_dsn"] --> Client["AsyncMSSQLClient.__init__"]
Client --> Ensure["_ensure_engine"]
Ensure --> Query["query_json"]
Ensure --> Exec["exec"]
Client --> Dispose["dispose"]
```
## Note
- `NullPool` evita problemi di riuso connessioni tra loop diversi.
- L'engine viene creato solo al primo utilizzo reale.
- `query_json()` restituisce un formato gia pronto per le callback GUI.

View File

@@ -0,0 +1,45 @@
# `gestione_aree_frame_async.py`
## Scopo
Questo modulo fornisce l'infrastruttura async usata dalle finestre GUI:
- loop asincrono globale;
- overlay di attesa;
- runner che collega coroutine e callback Tk.
## Flusso infrastrutturale
```{mermaid}
flowchart TD
A["Metodo finestra GUI"] --> B["AsyncRunner.run(awaitable)"]
B --> C{"busy overlay richiesto?"}
C -- Si --> D["BusyOverlay.show()"]
C -- No --> E["Salta overlay"]
D --> F["run_coroutine_threadsafe(awaitable, loop globale)"]
E --> F
F --> G["Polling del Future"]
G --> H{"Future completato?"}
H -- No --> G
H -- Si --> I{"Successo o errore?"}
I -- Successo --> J["widget.after(..., on_success)"]
I -- Errore --> K["widget.after(..., on_error)"]
J --> L["BusyOverlay.hide()"]
K --> L
```
## Schema di componenti
```{mermaid}
flowchart LR
Holder["_LoopHolder"] --> Loop["get_global_loop"]
Loop --> Runner["AsyncRunner"]
Overlay["BusyOverlay"] --> Runner
Runner --> GUI["Moduli GUI"]
```
## Note
- Il modulo fa da ponte tra thread Tk e thread del loop asincrono.
- `BusyOverlay` e riusato da piu finestre, quindi e un componente condiviso.
- `AsyncRunner` evita che i moduli GUI gestiscano direttamente i `Future`.

View File

@@ -0,0 +1,69 @@
# `gestione_pickinglist.py`
## Scopo
Questo modulo gestisce la vista master/detail delle picking list e permette di:
- caricare l'elenco dei documenti;
- vedere il dettaglio UDC della riga selezionata;
- prenotare e s-prenotare una picking list;
- mantenere una UI fluida con spinner e refresh differiti.
## Flusso di apertura
```{mermaid}
flowchart TD
A["open_pickinglist_window() da main.py"] --> B["create_pickinglist_frame()"]
B --> C["GestionePickingListFrame.__init__()"]
C --> D["_build_layout()"]
D --> E["after_idle(_first_show)"]
E --> F["reload_from_db(first=True)"]
F --> G["query_json SQL_PL"]
G --> H["_refresh_mid_rows()"]
H --> I["Render tabella master"]
```
## Flusso master/detail
```{mermaid}
flowchart TD
A["Utente seleziona checkbox riga"] --> B["on_row_checked()"]
B --> C["Deseleziona altre righe"]
C --> D["Salva detail_doc"]
D --> E["query_json SQL_PL_DETAILS"]
E --> F["_refresh_details()"]
F --> G["Render tabella dettaglio"]
```
## Prenotazione / s-prenotazione
```{mermaid}
flowchart TD
A["Click Prenota o S-prenota"] --> B["Verifica riga selezionata"]
B --> C["Determina documento e stato atteso"]
C --> D["Chiama sp_xExePackingListPallet_async()"]
D --> E["Aggiorna Celle e LogPackingList sul DB"]
E --> F["SPResult"]
F --> G{"rc == 0?"}
G -- Si --> H["_recolor_row_by_documento()"]
G -- No --> I["Messaggio di errore"]
```
## Schema di chiamata
```{mermaid}
flowchart LR
Init["__init__"] --> Build["_build_layout"]
Init --> First["_first_show"]
First --> Reload["reload_from_db"]
Reload --> Mid["_refresh_mid_rows"]
Check["on_row_checked"] --> Details["_refresh_details"]
Pren["on_prenota"] --> SP["sp_xExePackingListPallet_async"]
Spren["on_sprenota"] --> SP
```
## Note
- Il modulo usa `AsyncRunner`, `BusyOverlay` e `ToolbarSpinner`.
- Il caricamento iniziale è differito con `after_idle` per ridurre lo sfarfallio.
- La riga selezionata viene tenuta separata dal dettaglio tramite `detail_doc`.

View File

@@ -0,0 +1,20 @@
Flow Diagrams
=============
Questa sezione raccoglie i diagrammi Mermaid dei moduli applicativi e
infrastrutturali.
.. toctree::
:maxdepth: 1
README.md
main_flow.md
layout_window_flow.md
reset_corsie_flow.md
view_celle_multiple_flow.md
search_pallets_flow.md
gestione_pickinglist_flow.md
async_db_flow.md
async_msssql_query_flow.md
gestione_aree_frame_async_flow.md
async_loop_singleton_flow.md

View File

@@ -0,0 +1,61 @@
# `layout_window.py`
## Scopo
Questo modulo visualizza il layout delle corsie come matrice di celle, mostra
lo stato di occupazione, consente di cercare una UDC e permette l'export della
matrice.
## Flusso operativo
```{mermaid}
flowchart TD
A["open_layout_window()"] --> B["Crea o riporta in primo piano LayoutWindow"]
B --> C["LayoutWindow.__init__()"]
C --> D["Costruisce toolbar, host matrice, statistiche"]
D --> E["_load_corsie()"]
E --> F["AsyncRunner.run(query_json SQL corsie)"]
F --> G["_on_select() sulla corsia iniziale"]
G --> H["_load_matrix(corsia)"]
H --> I["AsyncRunner.run(query_json SQL matrice)"]
I --> J["_rebuild_matrix()"]
J --> K["_refresh_stats()"]
```
## Ricerca UDC
```{mermaid}
flowchart TD
A["Utente inserisce barcode"] --> B["_search_udc()"]
B --> C["query_json ricerca pallet -> corsia/colonna/fila"]
C --> D{"UDC trovata?"}
D -- No --> E["Messaggio informativo"]
D -- Si --> F["Seleziona corsia in listbox"]
F --> G["_load_matrix(corsia)"]
G --> H["_rebuild_matrix()"]
H --> I["_highlight_cell_by_labels()"]
```
## Schema di chiamata essenziale
```{mermaid}
flowchart LR
Init["__init__"] --> Top["_build_top"]
Init --> Host["_build_matrix_host"]
Init --> Stats["_build_stats"]
Init --> LoadCorsie["_load_corsie"]
LoadCorsie --> Select["_on_select"]
Select --> LoadMatrix["_load_matrix"]
LoadMatrix --> Rebuild["_rebuild_matrix"]
Rebuild --> RefreshStats["_refresh_stats"]
Search["_search_udc"] --> LoadMatrix
Export["_export_xlsx"] --> MatrixState["matrix_state / fila_txt / col_txt / udc1"]
```
## Note
- Il modulo usa un token `_req_counter` per evitare che risposte async vecchie
aggiornino la UI fuori ordine.
- La statistica globale viene ricalcolata da query SQL, mentre quella della
corsia corrente usa la matrice già caricata in memoria.
- `destroy()` marca la finestra come non più attiva per evitare callback tardive.

View File

@@ -0,0 +1,45 @@
# `main.py`
## Scopo
`main.py` è il punto di ingresso dell'applicazione desktop. Inizializza il loop
asincrono condiviso, crea il client database condiviso e costruisce il launcher
con i pulsanti che aprono i moduli operativi.
## Flusso principale
```{mermaid}
flowchart TD
A["Avvio di main.py"] --> B["Configura policy asyncio su Windows"]
B --> C["Ottiene loop globale con get_global_loop()"]
C --> D["Imposta il loop come default"]
D --> E["Costruisce DSN SQL Server"]
E --> F["Crea AsyncMSSQLClient condiviso"]
F --> G["Istanzia Launcher"]
G --> H["Mostra finestra principale"]
H --> I{"Click su un pulsante"}
I --> J["open_reset_corsie_window()"]
I --> K["open_layout_window()"]
I --> L["open_celle_multiple_window()"]
I --> M["open_search_window()"]
I --> N["open_pickinglist_window()"]
```
## Schema di chiamata
```{mermaid}
flowchart LR
Launcher["Launcher.__init__"] --> Reset["open_reset_corsie_window"]
Launcher --> Layout["open_layout_window"]
Launcher --> Ghost["open_celle_multiple_window"]
Launcher --> Search["open_search_window"]
Launcher --> Pick["open_pickinglist_window"]
Pick --> PickFactory["create_pickinglist_frame"]
```
## Note
- `db_app` viene creato una sola volta e poi passato a tutte le finestre.
- Alla chiusura del launcher viene chiamato `db_app.dispose()` sul loop globale.
- `open_pickinglist_window()` costruisce la finestra in modo nascosto e la rende
visibile solo a layout pronto, per ridurre lo sfarfallio iniziale.

View File

@@ -0,0 +1,45 @@
# `reset_corsie.py`
## Scopo
Questo modulo mostra il riepilogo di una corsia e permette, dopo doppia
conferma, di cancellare i record di `MagazziniPallet` collegati a quella corsia.
## Flusso operativo
```{mermaid}
flowchart TD
A["open_reset_corsie_window()"] --> B["ResetCorsieWindow.__init__()"]
B --> C["_build_ui()"]
C --> D["_load_corsie()"]
D --> E["query_json SQL_CORSIE"]
E --> F["Seleziona corsia iniziale"]
F --> G["refresh()"]
G --> H["query_json SQL_RIEPILOGO"]
G --> I["query_json SQL_DETTAGLIO"]
H --> J["Aggiorna contatori"]
I --> K["Aggiorna tree celle occupate"]
```
## Flusso distruttivo
```{mermaid}
flowchart TD
A["Click su Svuota corsia"] --> B["_ask_reset()"]
B --> C["query_json SQL_COUNT_DELETE"]
C --> D{"Record da cancellare > 0?"}
D -- No --> E["Messaggio: niente da rimuovere"]
D -- Si --> F["Richiesta conferma testuale"]
F --> G{"Testo corretto?"}
G -- No --> H["Annulla operazione"]
G -- Si --> I["_do_reset(corsia)"]
I --> J["query_json SQL_DELETE"]
J --> K["Messaggio completato"]
K --> L["refresh()"]
```
## Note
- È il modulo più delicato lato operazioni, perché esegue `DELETE`.
- La finestra separa chiaramente fase di ispezione e fase distruttiva.
- Tutte le query passano dal client condiviso tramite `AsyncRunner`.

View File

@@ -0,0 +1,43 @@
# `search_pallets.py`
## Scopo
Questo modulo consente di cercare pallet/UDC, lotti e codici prodotto su tutto
il magazzino e di esportare i risultati.
## Flusso operativo
```{mermaid}
flowchart TD
A["open_search_window()"] --> B["SearchWindow.__init__()"]
B --> C["_build_ui()"]
C --> D["Utente compila filtri"]
D --> E["_do_search()"]
E --> F{"Filtri vuoti?"}
F -- Si --> G["Richiesta conferma ricerca globale"]
F -- No --> H["Prepara parametri SQL"]
G --> H
H --> I["AsyncRunner.run(query_json SQL_SEARCH)"]
I --> J["_ok()"]
J --> K["Popola Treeview"]
K --> L["Eventuale reset campi"]
```
## Ordinamento ed export
```{mermaid}
flowchart TD
A["Doppio click su header"] --> B["_on_heading_double_click()"]
B --> C["_sort_by_column()"]
C --> D["Riordina righe del Treeview"]
E["Click Export XLSX"] --> F["_export_xlsx()"]
F --> G["Legge righe visibili"]
G --> H["Scrive workbook Excel"]
```
## Note
- Il modulo usa `Treeview` come backend principale.
- Le ricerche possono essere molto ampie: per questo, senza filtri, viene chiesta conferma.
- `IDCella = 9999` viene evidenziata con uno stile dedicato.

View File

@@ -0,0 +1,58 @@
# `view_celle_multiple.py`
## Scopo
Questo modulo esplora le celle che contengono più pallet del previsto,
organizzando i risultati in un albero:
- corsia
- cella duplicata
- pallet contenuti nella cella
## Flusso operativo
```{mermaid}
flowchart TD
A["open_celle_multiple_window()"] --> B["CelleMultipleWindow.__init__()"]
B --> C["_build_layout()"]
C --> D["_bind_events()"]
D --> E["refresh_all()"]
E --> F["_load_corsie()"]
E --> G["_load_riepilogo()"]
F --> H["query_json SQL_CORSIE"]
G --> I["query_json SQL_RIEPILOGO_PERCENTUALI"]
H --> J["_fill_corsie()"]
I --> K["_fill_riepilogo()"]
```
## Lazy loading dell'albero
```{mermaid}
flowchart TD
A["Espansione nodo tree"] --> B["_on_open_node()"]
B --> C{"Nodo corsia o nodo cella?"}
C -- Corsia --> D["_load_celle_for_corsia()"]
D --> E["query_json SQL_CELLE_DUP_PER_CORSIA"]
E --> F["_fill_celle()"]
C -- Cella --> G["_load_pallet_for_cella()"]
G --> H["query_json SQL_PALLET_IN_CELLA"]
H --> I["_fill_pallet()"]
```
## Schema di chiamata
```{mermaid}
flowchart LR
Refresh["refresh_all"] --> Corsie["_load_corsie"]
Refresh --> Riep["_load_riepilogo"]
Open["_on_open_node"] --> LoadCelle["_load_celle_for_corsia"]
Open --> LoadPallet["_load_pallet_for_cella"]
Export["export_to_xlsx"] --> Tree["tree dati dettaglio"]
Export --> Sum["sum_tbl riepilogo"]
```
## Note
- L'albero è caricato a richiesta, non tutto in una sola query.
- Questo riduce il costo iniziale e rende il modulo più scalabile.
- L'export legge sia il dettaglio dell'albero sia la tabella di riepilogo.

16
docs/_build/html/_sources/index.rst.txt vendored Normal file
View File

@@ -0,0 +1,16 @@
Warehouse Documentation
=======================
Questa documentazione raccoglie:
- riferimento API generato dal codice Python;
- diagrammi di flusso in Markdown/Mermaid;
- vista architetturale complessiva del progetto.
.. toctree::
:maxdepth: 2
:caption: Contenuti
architecture
api_reference
flows/index

663
docs/_build/html/_static/alabaster.css vendored Normal file
View File

@@ -0,0 +1,663 @@
/* -- page layout ----------------------------------------------------------- */
body {
font-family: Georgia, serif;
font-size: 17px;
background-color: #fff;
color: #000;
margin: 0;
padding: 0;
}
div.document {
width: 940px;
margin: 30px auto 0 auto;
}
div.documentwrapper {
float: left;
width: 100%;
}
div.bodywrapper {
margin: 0 0 0 220px;
}
div.sphinxsidebar {
width: 220px;
font-size: 14px;
line-height: 1.5;
}
hr {
border: 1px solid #B1B4B6;
}
div.body {
background-color: #fff;
color: #3E4349;
padding: 0 30px 0 30px;
}
div.body > .section {
text-align: left;
}
div.footer {
width: 940px;
margin: 20px auto 30px auto;
font-size: 14px;
color: #888;
text-align: right;
}
div.footer a {
color: #888;
}
p.caption {
font-family: inherit;
font-size: inherit;
}
div.relations {
display: none;
}
div.sphinxsidebar {
max-height: 100%;
overflow-y: auto;
}
div.sphinxsidebar a {
color: #444;
text-decoration: none;
border-bottom: 1px dotted #999;
}
div.sphinxsidebar a:hover {
border-bottom: 1px solid #999;
}
div.sphinxsidebarwrapper {
padding: 18px 10px;
}
div.sphinxsidebarwrapper p.logo {
padding: 0;
margin: -10px 0 0 0px;
text-align: center;
}
div.sphinxsidebarwrapper h1.logo {
margin-top: -10px;
text-align: center;
margin-bottom: 5px;
text-align: left;
}
div.sphinxsidebarwrapper h1.logo-name {
margin-top: 0px;
}
div.sphinxsidebarwrapper p.blurb {
margin-top: 0;
font-style: normal;
}
div.sphinxsidebar h3,
div.sphinxsidebar h4 {
font-family: Georgia, serif;
color: #444;
font-size: 24px;
font-weight: normal;
margin: 0 0 5px 0;
padding: 0;
}
div.sphinxsidebar h4 {
font-size: 20px;
}
div.sphinxsidebar h3 a {
color: #444;
}
div.sphinxsidebar p.logo a,
div.sphinxsidebar h3 a,
div.sphinxsidebar p.logo a:hover,
div.sphinxsidebar h3 a:hover {
border: none;
}
div.sphinxsidebar p {
color: #555;
margin: 10px 0;
}
div.sphinxsidebar ul {
margin: 10px 0;
padding: 0;
color: #000;
}
div.sphinxsidebar ul li.toctree-l1 > a {
font-size: 120%;
}
div.sphinxsidebar ul li.toctree-l2 > a {
font-size: 110%;
}
div.sphinxsidebar input {
border: 1px solid #CCC;
font-family: Georgia, serif;
font-size: 1em;
}
div.sphinxsidebar #searchbox {
margin: 1em 0;
}
div.sphinxsidebar .search > div {
display: table-cell;
}
div.sphinxsidebar hr {
border: none;
height: 1px;
color: #AAA;
background: #AAA;
text-align: left;
margin-left: 0;
width: 50%;
}
div.sphinxsidebar .badge {
border-bottom: none;
}
div.sphinxsidebar .badge:hover {
border-bottom: none;
}
/* To address an issue with donation coming after search */
div.sphinxsidebar h3.donation {
margin-top: 10px;
}
/* -- body styles ----------------------------------------------------------- */
a {
color: #004B6B;
text-decoration: underline;
}
a:hover {
color: #6D4100;
text-decoration: underline;
}
div.body h1,
div.body h2,
div.body h3,
div.body h4,
div.body h5,
div.body h6 {
font-family: Georgia, serif;
font-weight: normal;
margin: 30px 0px 10px 0px;
padding: 0;
}
div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; }
div.body h2 { font-size: 180%; }
div.body h3 { font-size: 150%; }
div.body h4 { font-size: 130%; }
div.body h5 { font-size: 100%; }
div.body h6 { font-size: 100%; }
a.headerlink {
color: #DDD;
padding: 0 4px;
text-decoration: none;
}
a.headerlink:hover {
color: #444;
background: #EAEAEA;
}
div.body p, div.body dd, div.body li {
line-height: 1.4em;
}
div.admonition {
margin: 20px 0px;
padding: 10px 30px;
background-color: #EEE;
border: 1px solid #CCC;
}
div.admonition tt.xref, div.admonition code.xref, div.admonition a tt {
background-color: #FBFBFB;
border-bottom: 1px solid #fafafa;
}
div.admonition p.admonition-title {
font-family: Georgia, serif;
font-weight: normal;
font-size: 24px;
margin: 0 0 10px 0;
padding: 0;
line-height: 1;
}
div.admonition p.last {
margin-bottom: 0;
}
dt:target, .highlight {
background: #FAF3E8;
}
div.warning {
background-color: #FCC;
border: 1px solid #FAA;
}
div.danger {
background-color: #FCC;
border: 1px solid #FAA;
-moz-box-shadow: 2px 2px 4px #D52C2C;
-webkit-box-shadow: 2px 2px 4px #D52C2C;
box-shadow: 2px 2px 4px #D52C2C;
}
div.error {
background-color: #FCC;
border: 1px solid #FAA;
-moz-box-shadow: 2px 2px 4px #D52C2C;
-webkit-box-shadow: 2px 2px 4px #D52C2C;
box-shadow: 2px 2px 4px #D52C2C;
}
div.caution {
background-color: #FCC;
border: 1px solid #FAA;
}
div.attention {
background-color: #FCC;
border: 1px solid #FAA;
}
div.important {
background-color: #EEE;
border: 1px solid #CCC;
}
div.note {
background-color: #EEE;
border: 1px solid #CCC;
}
div.tip {
background-color: #EEE;
border: 1px solid #CCC;
}
div.hint {
background-color: #EEE;
border: 1px solid #CCC;
}
div.seealso {
background-color: #EEE;
border: 1px solid #CCC;
}
div.topic {
background-color: #EEE;
}
p.admonition-title {
display: inline;
}
p.admonition-title:after {
content: ":";
}
pre, tt, code {
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
font-size: 0.9em;
}
.hll {
background-color: #FFC;
margin: 0 -12px;
padding: 0 12px;
display: block;
}
img.screenshot {
}
tt.descname, tt.descclassname, code.descname, code.descclassname {
font-size: 0.95em;
}
tt.descname, code.descname {
padding-right: 0.08em;
}
img.screenshot {
-moz-box-shadow: 2px 2px 4px #EEE;
-webkit-box-shadow: 2px 2px 4px #EEE;
box-shadow: 2px 2px 4px #EEE;
}
table.docutils {
border: 1px solid #888;
-moz-box-shadow: 2px 2px 4px #EEE;
-webkit-box-shadow: 2px 2px 4px #EEE;
box-shadow: 2px 2px 4px #EEE;
}
table.docutils td, table.docutils th {
border: 1px solid #888;
padding: 0.25em 0.7em;
}
table.field-list, table.footnote {
border: none;
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
}
table.footnote {
margin: 15px 0;
width: 100%;
border: 1px solid #EEE;
background: #FDFDFD;
font-size: 0.9em;
}
table.footnote + table.footnote {
margin-top: -15px;
border-top: none;
}
table.field-list th {
padding: 0 0.8em 0 0;
}
table.field-list td {
padding: 0;
}
table.field-list p {
margin-bottom: 0.8em;
}
/* Cloned from
* https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68
*/
.field-name {
-moz-hyphens: manual;
-ms-hyphens: manual;
-webkit-hyphens: manual;
hyphens: manual;
}
table.footnote td.label {
width: .1px;
padding: 0.3em 0 0.3em 0.5em;
}
table.footnote td {
padding: 0.3em 0.5em;
}
dl {
margin-left: 0;
margin-right: 0;
margin-top: 0;
padding: 0;
}
dl dd {
margin-left: 30px;
}
blockquote {
margin: 0 0 0 30px;
padding: 0;
}
ul, ol {
/* Matches the 30px from the narrow-screen "li > ul" selector below */
margin: 10px 0 10px 30px;
padding: 0;
}
pre {
background: unset;
padding: 7px 30px;
margin: 15px 0px;
line-height: 1.3em;
}
div.viewcode-block:target {
background: #ffd;
}
dl pre, blockquote pre, li pre {
margin-left: 0;
padding-left: 30px;
}
tt, code {
background-color: #ecf0f3;
color: #222;
/* padding: 1px 2px; */
}
tt.xref, code.xref, a tt {
background-color: #FBFBFB;
border-bottom: 1px solid #fff;
}
a.reference {
text-decoration: none;
border-bottom: 1px dotted #004B6B;
}
a.reference:hover {
border-bottom: 1px solid #6D4100;
}
/* Don't put an underline on images */
a.image-reference, a.image-reference:hover {
border-bottom: none;
}
a.footnote-reference {
text-decoration: none;
font-size: 0.7em;
vertical-align: top;
border-bottom: 1px dotted #004B6B;
}
a.footnote-reference:hover {
border-bottom: 1px solid #6D4100;
}
a:hover tt, a:hover code {
background: #EEE;
}
@media screen and (max-width: 940px) {
body {
margin: 0;
padding: 20px 30px;
}
div.documentwrapper {
float: none;
background: #fff;
margin-left: 0;
margin-top: 0;
margin-right: 0;
margin-bottom: 0;
}
div.sphinxsidebar {
display: block;
float: none;
width: unset;
margin: 50px -30px -20px -30px;
padding: 10px 20px;
background: #333;
color: #FFF;
}
div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p,
div.sphinxsidebar h3 a {
color: #fff;
}
div.sphinxsidebar a {
color: #AAA;
}
div.sphinxsidebar p.logo {
display: none;
}
div.document {
width: 100%;
margin: 0;
}
div.footer {
display: none;
}
div.bodywrapper {
margin: 0;
}
div.body {
min-height: 0;
min-width: auto; /* fixes width on small screens, breaks .hll */
padding: 0;
}
.hll {
/* "fixes" the breakage */
width: max-content;
}
.rtd_doc_footer {
display: none;
}
.document {
width: auto;
}
.footer {
width: auto;
}
.github {
display: none;
}
ul {
margin-left: 0;
}
li > ul {
/* Matches the 30px from the "ul, ol" selector above */
margin-left: 30px;
}
}
/* misc. */
.revsys-inline {
display: none!important;
}
/* Hide ugly table cell borders in ..bibliography:: directive output */
table.docutils.citation, table.docutils.citation td, table.docutils.citation th {
border: none;
/* Below needed in some edge cases; if not applied, bottom shadows appear */
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
}
/* relbar */
.related {
line-height: 30px;
width: 100%;
font-size: 0.9rem;
}
.related.top {
border-bottom: 1px solid #EEE;
margin-bottom: 20px;
}
.related.bottom {
border-top: 1px solid #EEE;
}
.related ul {
padding: 0;
margin: 0;
list-style: none;
}
.related li {
display: inline;
}
nav#rellinks {
float: right;
}
nav#rellinks li+li:before {
content: "|";
}
nav#breadcrumbs li+li:before {
content: "\00BB";
}
/* Hide certain items when printing */
@media print {
div.related {
display: none;
}
}
img.github {
position: absolute;
top: 0;
border: 0;
right: 0;
}

476
docs/_build/html/_static/base-stemmer.js vendored Normal file
View File

@@ -0,0 +1,476 @@
// @ts-check
/**@constructor*/
BaseStemmer = function() {
/** @protected */
this.current = '';
this.cursor = 0;
this.limit = 0;
this.limit_backward = 0;
this.bra = 0;
this.ket = 0;
/**
* @param {string} value
*/
this.setCurrent = function(value) {
this.current = value;
this.cursor = 0;
this.limit = this.current.length;
this.limit_backward = 0;
this.bra = this.cursor;
this.ket = this.limit;
};
/**
* @return {string}
*/
this.getCurrent = function() {
return this.current;
};
/**
* @param {BaseStemmer} other
*/
this.copy_from = function(other) {
/** @protected */
this.current = other.current;
this.cursor = other.cursor;
this.limit = other.limit;
this.limit_backward = other.limit_backward;
this.bra = other.bra;
this.ket = other.ket;
};
/**
* @param {number[]} s
* @param {number} min
* @param {number} max
* @return {boolean}
*/
this.in_grouping = function(s, min, max) {
/** @protected */
if (this.cursor >= this.limit) return false;
var ch = this.current.charCodeAt(this.cursor);
if (ch > max || ch < min) return false;
ch -= min;
if ((s[ch >>> 3] & (0x1 << (ch & 0x7))) == 0) return false;
this.cursor++;
return true;
};
/**
* @param {number[]} s
* @param {number} min
* @param {number} max
* @return {boolean}
*/
this.go_in_grouping = function(s, min, max) {
/** @protected */
while (this.cursor < this.limit) {
var ch = this.current.charCodeAt(this.cursor);
if (ch > max || ch < min)
return true;
ch -= min;
if ((s[ch >>> 3] & (0x1 << (ch & 0x7))) == 0)
return true;
this.cursor++;
}
return false;
};
/**
* @param {number[]} s
* @param {number} min
* @param {number} max
* @return {boolean}
*/
this.in_grouping_b = function(s, min, max) {
/** @protected */
if (this.cursor <= this.limit_backward) return false;
var ch = this.current.charCodeAt(this.cursor - 1);
if (ch > max || ch < min) return false;
ch -= min;
if ((s[ch >>> 3] & (0x1 << (ch & 0x7))) == 0) return false;
this.cursor--;
return true;
};
/**
* @param {number[]} s
* @param {number} min
* @param {number} max
* @return {boolean}
*/
this.go_in_grouping_b = function(s, min, max) {
/** @protected */
while (this.cursor > this.limit_backward) {
var ch = this.current.charCodeAt(this.cursor - 1);
if (ch > max || ch < min) return true;
ch -= min;
if ((s[ch >>> 3] & (0x1 << (ch & 0x7))) == 0) return true;
this.cursor--;
}
return false;
};
/**
* @param {number[]} s
* @param {number} min
* @param {number} max
* @return {boolean}
*/
this.out_grouping = function(s, min, max) {
/** @protected */
if (this.cursor >= this.limit) return false;
var ch = this.current.charCodeAt(this.cursor);
if (ch > max || ch < min) {
this.cursor++;
return true;
}
ch -= min;
if ((s[ch >>> 3] & (0X1 << (ch & 0x7))) == 0) {
this.cursor++;
return true;
}
return false;
};
/**
* @param {number[]} s
* @param {number} min
* @param {number} max
* @return {boolean}
*/
this.go_out_grouping = function(s, min, max) {
/** @protected */
while (this.cursor < this.limit) {
var ch = this.current.charCodeAt(this.cursor);
if (ch <= max && ch >= min) {
ch -= min;
if ((s[ch >>> 3] & (0X1 << (ch & 0x7))) != 0) {
return true;
}
}
this.cursor++;
}
return false;
};
/**
* @param {number[]} s
* @param {number} min
* @param {number} max
* @return {boolean}
*/
this.out_grouping_b = function(s, min, max) {
/** @protected */
if (this.cursor <= this.limit_backward) return false;
var ch = this.current.charCodeAt(this.cursor - 1);
if (ch > max || ch < min) {
this.cursor--;
return true;
}
ch -= min;
if ((s[ch >>> 3] & (0x1 << (ch & 0x7))) == 0) {
this.cursor--;
return true;
}
return false;
};
/**
* @param {number[]} s
* @param {number} min
* @param {number} max
* @return {boolean}
*/
this.go_out_grouping_b = function(s, min, max) {
/** @protected */
while (this.cursor > this.limit_backward) {
var ch = this.current.charCodeAt(this.cursor - 1);
if (ch <= max && ch >= min) {
ch -= min;
if ((s[ch >>> 3] & (0x1 << (ch & 0x7))) != 0) {
return true;
}
}
this.cursor--;
}
return false;
};
/**
* @param {string} s
* @return {boolean}
*/
this.eq_s = function(s)
{
/** @protected */
if (this.limit - this.cursor < s.length) return false;
if (this.current.slice(this.cursor, this.cursor + s.length) != s)
{
return false;
}
this.cursor += s.length;
return true;
};
/**
* @param {string} s
* @return {boolean}
*/
this.eq_s_b = function(s)
{
/** @protected */
if (this.cursor - this.limit_backward < s.length) return false;
if (this.current.slice(this.cursor - s.length, this.cursor) != s)
{
return false;
}
this.cursor -= s.length;
return true;
};
/**
* @param {Among[]} v
* @return {number}
*/
this.find_among = function(v)
{
/** @protected */
var i = 0;
var j = v.length;
var c = this.cursor;
var l = this.limit;
var common_i = 0;
var common_j = 0;
var first_key_inspected = false;
while (true)
{
var k = i + ((j - i) >>> 1);
var diff = 0;
var common = common_i < common_j ? common_i : common_j; // smaller
// w[0]: string, w[1]: substring_i, w[2]: result, w[3]: function (optional)
var w = v[k];
var i2;
for (i2 = common; i2 < w[0].length; i2++)
{
if (c + common == l)
{
diff = -1;
break;
}
diff = this.current.charCodeAt(c + common) - w[0].charCodeAt(i2);
if (diff != 0) break;
common++;
}
if (diff < 0)
{
j = k;
common_j = common;
}
else
{
i = k;
common_i = common;
}
if (j - i <= 1)
{
if (i > 0) break; // v->s has been inspected
if (j == i) break; // only one item in v
// - but now we need to go round once more to get
// v->s inspected. This looks messy, but is actually
// the optimal approach.
if (first_key_inspected) break;
first_key_inspected = true;
}
}
do {
var w = v[i];
if (common_i >= w[0].length)
{
this.cursor = c + w[0].length;
if (w.length < 4) return w[2];
var res = w[3](this);
this.cursor = c + w[0].length;
if (res) return w[2];
}
i = w[1];
} while (i >= 0);
return 0;
};
// find_among_b is for backwards processing. Same comments apply
/**
* @param {Among[]} v
* @return {number}
*/
this.find_among_b = function(v)
{
/** @protected */
var i = 0;
var j = v.length
var c = this.cursor;
var lb = this.limit_backward;
var common_i = 0;
var common_j = 0;
var first_key_inspected = false;
while (true)
{
var k = i + ((j - i) >> 1);
var diff = 0;
var common = common_i < common_j ? common_i : common_j;
var w = v[k];
var i2;
for (i2 = w[0].length - 1 - common; i2 >= 0; i2--)
{
if (c - common == lb)
{
diff = -1;
break;
}
diff = this.current.charCodeAt(c - 1 - common) - w[0].charCodeAt(i2);
if (diff != 0) break;
common++;
}
if (diff < 0)
{
j = k;
common_j = common;
}
else
{
i = k;
common_i = common;
}
if (j - i <= 1)
{
if (i > 0) break;
if (j == i) break;
if (first_key_inspected) break;
first_key_inspected = true;
}
}
do {
var w = v[i];
if (common_i >= w[0].length)
{
this.cursor = c - w[0].length;
if (w.length < 4) return w[2];
var res = w[3](this);
this.cursor = c - w[0].length;
if (res) return w[2];
}
i = w[1];
} while (i >= 0);
return 0;
};
/* to replace chars between c_bra and c_ket in this.current by the
* chars in s.
*/
/**
* @param {number} c_bra
* @param {number} c_ket
* @param {string} s
* @return {number}
*/
this.replace_s = function(c_bra, c_ket, s)
{
/** @protected */
var adjustment = s.length - (c_ket - c_bra);
this.current = this.current.slice(0, c_bra) + s + this.current.slice(c_ket);
this.limit += adjustment;
if (this.cursor >= c_ket) this.cursor += adjustment;
else if (this.cursor > c_bra) this.cursor = c_bra;
return adjustment;
};
/**
* @return {boolean}
*/
this.slice_check = function()
{
/** @protected */
if (this.bra < 0 ||
this.bra > this.ket ||
this.ket > this.limit ||
this.limit > this.current.length)
{
return false;
}
return true;
};
/**
* @param {number} c_bra
* @return {boolean}
*/
this.slice_from = function(s)
{
/** @protected */
var result = false;
if (this.slice_check())
{
this.replace_s(this.bra, this.ket, s);
result = true;
}
return result;
};
/**
* @return {boolean}
*/
this.slice_del = function()
{
/** @protected */
return this.slice_from("");
};
/**
* @param {number} c_bra
* @param {number} c_ket
* @param {string} s
*/
this.insert = function(c_bra, c_ket, s)
{
/** @protected */
var adjustment = this.replace_s(c_bra, c_ket, s);
if (c_bra <= this.bra) this.bra += adjustment;
if (c_bra <= this.ket) this.ket += adjustment;
};
/**
* @return {string}
*/
this.slice_to = function()
{
/** @protected */
var result = '';
if (this.slice_check())
{
result = this.current.slice(this.bra, this.ket);
}
return result;
};
/**
* @return {string}
*/
this.assign_to = function()
{
/** @protected */
return this.current.slice(0, this.limit);
};
};

906
docs/_build/html/_static/basic.css vendored Normal file
View File

@@ -0,0 +1,906 @@
/*
* Sphinx stylesheet -- basic theme.
*/
/* -- main layout ----------------------------------------------------------- */
div.clearer {
clear: both;
}
div.section::after {
display: block;
content: '';
clear: left;
}
/* -- relbar ---------------------------------------------------------------- */
div.related {
width: 100%;
font-size: 90%;
}
div.related h3 {
display: none;
}
div.related ul {
margin: 0;
padding: 0 0 0 10px;
list-style: none;
}
div.related li {
display: inline;
}
div.related li.right {
float: right;
margin-right: 5px;
}
/* -- sidebar --------------------------------------------------------------- */
div.sphinxsidebarwrapper {
padding: 10px 5px 0 10px;
}
div.sphinxsidebar {
float: left;
width: 230px;
margin-left: -100%;
font-size: 90%;
word-wrap: break-word;
overflow-wrap : break-word;
}
div.sphinxsidebar ul {
list-style: none;
}
div.sphinxsidebar ul ul,
div.sphinxsidebar ul.want-points {
margin-left: 20px;
list-style: square;
}
div.sphinxsidebar ul ul {
margin-top: 0;
margin-bottom: 0;
}
div.sphinxsidebar form {
margin-top: 10px;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
div.sphinxsidebar #searchbox form.search {
overflow: hidden;
}
div.sphinxsidebar #searchbox input[type="text"] {
float: left;
width: 80%;
padding: 0.25em;
box-sizing: border-box;
}
div.sphinxsidebar #searchbox input[type="submit"] {
float: left;
width: 20%;
border-left: none;
padding: 0.25em;
box-sizing: border-box;
}
img {
border: 0;
max-width: 100%;
}
/* -- search page ----------------------------------------------------------- */
ul.search {
margin-top: 10px;
}
ul.search li {
padding: 5px 0;
}
ul.search li a {
font-weight: bold;
}
ul.search li p.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
}
ul.keywordmatches li.goodmatch a {
font-weight: bold;
}
/* -- index page ------------------------------------------------------------ */
table.contentstable {
width: 90%;
margin-left: auto;
margin-right: auto;
}
table.contentstable p.biglink {
line-height: 150%;
}
a.biglink {
font-size: 1.3em;
}
span.linkdescr {
font-style: italic;
padding-top: 5px;
font-size: 90%;
}
/* -- general index --------------------------------------------------------- */
table.indextable {
width: 100%;
}
table.indextable td {
text-align: left;
vertical-align: top;
}
table.indextable ul {
margin-top: 0;
margin-bottom: 0;
list-style-type: none;
}
table.indextable > tbody > tr > td > ul {
padding-left: 0em;
}
table.indextable tr.pcap {
height: 10px;
}
table.indextable tr.cap {
margin-top: 10px;
background-color: #f2f2f2;
}
img.toggler {
margin-right: 3px;
margin-top: 3px;
cursor: pointer;
}
div.modindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
div.genindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
/* -- domain module index --------------------------------------------------- */
table.modindextable td {
padding: 2px;
border-collapse: collapse;
}
/* -- general body styles --------------------------------------------------- */
div.body {
min-width: inherit;
max-width: 800px;
}
div.body p, div.body dd, div.body li, div.body blockquote {
-moz-hyphens: auto;
-ms-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
}
a.headerlink {
visibility: hidden;
}
a:visited {
color: #551A8B;
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
h4:hover > a.headerlink,
h5:hover > a.headerlink,
h6:hover > a.headerlink,
dt:hover > a.headerlink,
caption:hover > a.headerlink,
p.caption:hover > a.headerlink,
div.code-block-caption:hover > a.headerlink {
visibility: visible;
}
div.body p.caption {
text-align: inherit;
}
div.body td {
text-align: left;
}
.first {
margin-top: 0 !important;
}
p.rubric {
margin-top: 30px;
font-weight: bold;
}
img.align-left, figure.align-left, .figure.align-left, object.align-left {
clear: left;
float: left;
margin-right: 1em;
}
img.align-right, figure.align-right, .figure.align-right, object.align-right {
clear: right;
float: right;
margin-left: 1em;
}
img.align-center, figure.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
img.align-default, figure.align-default, .figure.align-default {
display: block;
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.align-default {
text-align: center;
}
.align-right {
text-align: right;
}
/* -- sidebars -------------------------------------------------------------- */
div.sidebar,
aside.sidebar {
margin: 0 0 0.5em 1em;
border: 1px solid #ddb;
padding: 7px;
background-color: #ffe;
width: 40%;
float: right;
clear: right;
overflow-x: auto;
}
p.sidebar-title {
font-weight: bold;
}
nav.contents,
aside.topic,
div.admonition, div.topic, blockquote {
clear: left;
}
/* -- topics ---------------------------------------------------------------- */
nav.contents,
aside.topic,
div.topic {
border: 1px solid #ccc;
padding: 7px;
margin: 10px 0 10px 0;
}
p.topic-title {
font-size: 1.1em;
font-weight: bold;
margin-top: 10px;
}
/* -- admonitions ----------------------------------------------------------- */
div.admonition {
margin-top: 10px;
margin-bottom: 10px;
padding: 7px;
}
div.admonition dt {
font-weight: bold;
}
p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
}
div.body p.centered {
text-align: center;
margin-top: 25px;
}
/* -- content of sidebars/topics/admonitions -------------------------------- */
div.sidebar > :last-child,
aside.sidebar > :last-child,
nav.contents > :last-child,
aside.topic > :last-child,
div.topic > :last-child,
div.admonition > :last-child {
margin-bottom: 0;
}
div.sidebar::after,
aside.sidebar::after,
nav.contents::after,
aside.topic::after,
div.topic::after,
div.admonition::after,
blockquote::after {
display: block;
content: '';
clear: both;
}
/* -- tables ---------------------------------------------------------------- */
table.docutils {
margin-top: 10px;
margin-bottom: 10px;
border: 0;
border-collapse: collapse;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
table.align-default {
margin-left: auto;
margin-right: auto;
}
table caption span.caption-number {
font-style: italic;
}
table caption span.caption-text {
}
table.docutils td, table.docutils th {
padding: 1px 8px 1px 5px;
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid #aaa;
}
th {
text-align: left;
padding-right: 5px;
}
table.citation {
border-left: solid 1px gray;
margin-left: 1px;
}
table.citation td {
border-bottom: none;
}
th > :first-child,
td > :first-child {
margin-top: 0px;
}
th > :last-child,
td > :last-child {
margin-bottom: 0px;
}
/* -- figures --------------------------------------------------------------- */
div.figure, figure {
margin: 0.5em;
padding: 0.5em;
}
div.figure p.caption, figcaption {
padding: 0.3em;
}
div.figure p.caption span.caption-number,
figcaption span.caption-number {
font-style: italic;
}
div.figure p.caption span.caption-text,
figcaption span.caption-text {
}
/* -- field list styles ----------------------------------------------------- */
table.field-list td, table.field-list th {
border: 0 !important;
}
.field-list ul {
margin: 0;
padding-left: 1em;
}
.field-list p {
margin: 0;
}
.field-name {
-moz-hyphens: manual;
-ms-hyphens: manual;
-webkit-hyphens: manual;
hyphens: manual;
}
/* -- hlist styles ---------------------------------------------------------- */
table.hlist {
margin: 1em 0;
}
table.hlist td {
vertical-align: top;
}
/* -- object description styles --------------------------------------------- */
.sig {
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
}
.sig-name, code.descname {
background-color: transparent;
font-weight: bold;
}
.sig-name {
font-size: 1.1em;
}
code.descname {
font-size: 1.2em;
}
.sig-prename, code.descclassname {
background-color: transparent;
}
.optional {
font-size: 1.3em;
}
.sig-paren {
font-size: larger;
}
.sig-param.n {
font-style: italic;
}
/* C++ specific styling */
.sig-inline.c-texpr,
.sig-inline.cpp-texpr {
font-family: unset;
}
.sig.c .k, .sig.c .kt,
.sig.cpp .k, .sig.cpp .kt {
color: #0033B3;
}
.sig.c .m,
.sig.cpp .m {
color: #1750EB;
}
.sig.c .s, .sig.c .sc,
.sig.cpp .s, .sig.cpp .sc {
color: #067D17;
}
/* -- other body styles ----------------------------------------------------- */
ol.arabic {
list-style: decimal;
}
ol.loweralpha {
list-style: lower-alpha;
}
ol.upperalpha {
list-style: upper-alpha;
}
ol.lowerroman {
list-style: lower-roman;
}
ol.upperroman {
list-style: upper-roman;
}
:not(li) > ol > li:first-child > :first-child,
:not(li) > ul > li:first-child > :first-child {
margin-top: 0px;
}
:not(li) > ol > li:last-child > :last-child,
:not(li) > ul > li:last-child > :last-child {
margin-bottom: 0px;
}
ol.simple ol p,
ol.simple ul p,
ul.simple ol p,
ul.simple ul p {
margin-top: 0;
}
ol.simple > li:not(:first-child) > p,
ul.simple > li:not(:first-child) > p {
margin-top: 0;
}
ol.simple p,
ul.simple p {
margin-bottom: 0;
}
aside.footnote > span,
div.citation > span {
float: left;
}
aside.footnote > span:last-of-type,
div.citation > span:last-of-type {
padding-right: 0.5em;
}
aside.footnote > p {
margin-left: 2em;
}
div.citation > p {
margin-left: 4em;
}
aside.footnote > p:last-of-type,
div.citation > p:last-of-type {
margin-bottom: 0em;
}
aside.footnote > p:last-of-type:after,
div.citation > p:last-of-type:after {
content: "";
clear: both;
}
dl.field-list {
display: grid;
grid-template-columns: fit-content(30%) auto;
}
dl.field-list > dt {
font-weight: bold;
word-break: break-word;
padding-left: 0.5em;
padding-right: 5px;
}
dl.field-list > dd {
padding-left: 0.5em;
margin-top: 0em;
margin-left: 0em;
margin-bottom: 0em;
}
dl {
margin-bottom: 15px;
}
dd > :first-child {
margin-top: 0px;
}
dd ul, dd table {
margin-bottom: 10px;
}
dd {
margin-top: 3px;
margin-bottom: 10px;
margin-left: 30px;
}
.sig dd {
margin-top: 0px;
margin-bottom: 0px;
}
.sig dl {
margin-top: 0px;
margin-bottom: 0px;
}
dl > dd:last-child,
dl > dd:last-child > :last-child {
margin-bottom: 0;
}
dt:target, span.highlighted {
background-color: #fbe54e;
}
rect.highlighted {
fill: #fbe54e;
}
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
}
.versionmodified {
font-style: italic;
}
.system-message {
background-color: #fda;
padding: 5px;
border: 3px solid red;
}
.footnote:target {
background-color: #ffa;
}
.line-block {
display: block;
margin-top: 1em;
margin-bottom: 1em;
}
.line-block .line-block {
margin-top: 0;
margin-bottom: 0;
margin-left: 1.5em;
}
.guilabel, .menuselection {
font-family: sans-serif;
}
.accelerator {
text-decoration: underline;
}
.classifier {
font-style: oblique;
}
.classifier:before {
font-style: normal;
margin: 0 0.5em;
content: ":";
display: inline-block;
}
abbr, acronym {
border-bottom: dotted 1px;
cursor: help;
}
/* -- code displays --------------------------------------------------------- */
pre {
overflow: auto;
overflow-y: hidden; /* fixes display issues on Chrome browsers */
}
pre, div[class*="highlight-"] {
clear: both;
}
span.pre {
-moz-hyphens: none;
-ms-hyphens: none;
-webkit-hyphens: none;
hyphens: none;
white-space: nowrap;
}
div[class*="highlight-"] {
margin: 1em 0;
}
td.linenos pre {
border: 0;
background-color: transparent;
color: #aaa;
}
table.highlighttable {
display: block;
}
table.highlighttable tbody {
display: block;
}
table.highlighttable tr {
display: flex;
}
table.highlighttable td {
margin: 0;
padding: 0;
}
table.highlighttable td.linenos {
padding-right: 0.5em;
}
table.highlighttable td.code {
flex: 1;
overflow: hidden;
}
.highlight .hll {
display: block;
}
div.highlight pre,
table.highlighttable pre {
margin: 0;
}
div.code-block-caption + div {
margin-top: 0;
}
div.code-block-caption {
margin-top: 1em;
padding: 2px 5px;
font-size: small;
}
div.code-block-caption code {
background-color: transparent;
}
table.highlighttable td.linenos,
span.linenos,
div.highlight span.gp { /* gp: Generic.Prompt */
user-select: none;
-webkit-user-select: text; /* Safari fallback only */
-webkit-user-select: none; /* Chrome/Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE10+ */
}
div.code-block-caption span.caption-number {
padding: 0.1em 0.3em;
font-style: italic;
}
div.code-block-caption span.caption-text {
}
div.literal-block-wrapper {
margin: 1em 0;
}
code.xref, a code {
background-color: transparent;
font-weight: bold;
}
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
background-color: transparent;
}
.viewcode-link {
float: right;
}
.viewcode-back {
float: right;
font-family: sans-serif;
}
div.viewcode-block:target {
margin: -1px -10px;
padding: 0 10px;
}
/* -- math display ---------------------------------------------------------- */
img.math {
vertical-align: middle;
}
div.body div.math p {
text-align: center;
}
span.eqno {
float: right;
}
span.eqno a.headerlink {
position: absolute;
z-index: 1;
}
div.math:hover a.headerlink {
visibility: visible;
}
/* -- printout stylesheet --------------------------------------------------- */
@media print {
div.document,
div.documentwrapper,
div.bodywrapper {
margin: 0 !important;
width: 100%;
}
div.sphinxsidebar,
div.related,
div.footer,
#top-link {
display: none;
}
}

1
docs/_build/html/_static/custom.css vendored Normal file
View File

@@ -0,0 +1 @@
/* This file intentionally left blank. */

150
docs/_build/html/_static/doctools.js vendored Normal file
View File

@@ -0,0 +1,150 @@
/*
* Base JavaScript utilities for all Sphinx HTML documentation.
*/
"use strict";
const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([
"TEXTAREA",
"INPUT",
"SELECT",
"BUTTON",
]);
const _ready = (callback) => {
if (document.readyState !== "loading") {
callback();
} else {
document.addEventListener("DOMContentLoaded", callback);
}
};
/**
* Small JavaScript module for the documentation.
*/
const Documentation = {
init: () => {
Documentation.initDomainIndexTable();
Documentation.initOnKeyListeners();
},
/**
* i18n support
*/
TRANSLATIONS: {},
PLURAL_EXPR: (n) => (n === 1 ? 0 : 1),
LOCALE: "unknown",
// gettext and ngettext don't access this so that the functions
// can safely bound to a different name (_ = Documentation.gettext)
gettext: (string) => {
const translated = Documentation.TRANSLATIONS[string];
switch (typeof translated) {
case "undefined":
return string; // no translation
case "string":
return translated; // translation exists
default:
return translated[0]; // (singular, plural) translation tuple exists
}
},
ngettext: (singular, plural, n) => {
const translated = Documentation.TRANSLATIONS[singular];
if (typeof translated !== "undefined")
return translated[Documentation.PLURAL_EXPR(n)];
return n === 1 ? singular : plural;
},
addTranslations: (catalog) => {
Object.assign(Documentation.TRANSLATIONS, catalog.messages);
Documentation.PLURAL_EXPR = new Function(
"n",
`return (${catalog.plural_expr})`,
);
Documentation.LOCALE = catalog.locale;
},
/**
* helper function to focus on search bar
*/
focusSearchBar: () => {
document.querySelectorAll("input[name=q]")[0]?.focus();
},
/**
* Initialise the domain index toggle buttons
*/
initDomainIndexTable: () => {
const toggler = (el) => {
const idNumber = el.id.substr(7);
const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`);
if (el.src.substr(-9) === "minus.png") {
el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`;
toggledRows.forEach((el) => (el.style.display = "none"));
} else {
el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`;
toggledRows.forEach((el) => (el.style.display = ""));
}
};
const togglerElements = document.querySelectorAll("img.toggler");
togglerElements.forEach((el) =>
el.addEventListener("click", (event) => toggler(event.currentTarget)),
);
togglerElements.forEach((el) => (el.style.display = ""));
if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler);
},
initOnKeyListeners: () => {
// only install a listener if it is really needed
if (
!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS
&& !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS
)
return;
document.addEventListener("keydown", (event) => {
// bail for input elements
if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName))
return;
// bail with special keys
if (event.altKey || event.ctrlKey || event.metaKey) return;
if (!event.shiftKey) {
switch (event.key) {
case "ArrowLeft":
if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
const prevLink = document.querySelector('link[rel="prev"]');
if (prevLink && prevLink.href) {
window.location.href = prevLink.href;
event.preventDefault();
}
break;
case "ArrowRight":
if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
const nextLink = document.querySelector('link[rel="next"]');
if (nextLink && nextLink.href) {
window.location.href = nextLink.href;
event.preventDefault();
}
break;
}
}
// some keyboard layouts may need Shift to get /
switch (event.key) {
case "/":
if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;
Documentation.focusSearchBar();
event.preventDefault();
}
});
},
};
// quick alias for translations
const _ = Documentation.gettext;
_ready(Documentation.init);

View File

@@ -0,0 +1,13 @@
const DOCUMENTATION_OPTIONS = {
VERSION: '0.0.1',
LANGUAGE: 'en',
COLLAPSE_INDEX: false,
BUILDER: 'html',
FILE_SUFFIX: '.html',
LINK_SUFFIX: '.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt',
NAVIGATION_WITH_KEYS: false,
SHOW_SEARCH_SUMMARY: true,
ENABLE_SEARCH_SHORTCUTS: true,
};

File diff suppressed because it is too large Load Diff

BIN
docs/_build/html/_static/file.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" viewBox="0 0 250 250" fill="#fff">
<path d="M0 0l115 115h15l12 27 108 108V0z" fill="#151513"/>
<path d="M128 109c-15-9-9-19-9-19 3-7 2-11 2-11-1-7 3-2 3-2 4 5 2 11 2 11-3 10 5 15 9 16"/>
<path d="M115 115s4 2 5 0l14-14c3-2 6-3 8-3-8-11-15-24 2-41 5-5 10-7 16-7 1-2 3-7 12-11 0 0 5 3 7 16 4 2 8 5 12 9s7 8 9 12c14 3 17 7 17 7-4 8-9 11-11 11 0 6-2 11-7 16-16 16-30 10-41 2 0 3-1 7-5 11l-12 11c-1 1 1 5 1 5z"/>
</svg>

After

Width:  |  Height:  |  Size: 490 B

File diff suppressed because one or more lines are too long

BIN
docs/_build/html/_static/minus.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

BIN
docs/_build/html/_static/plus.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

84
docs/_build/html/_static/pygments.css vendored Normal file
View File

@@ -0,0 +1,84 @@
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #f8f8f8; }
.highlight .c { color: #8F5902; font-style: italic } /* Comment */
.highlight .err { color: #A40000; border: 1px solid #EF2929 } /* Error */
.highlight .g { color: #000 } /* Generic */
.highlight .k { color: #004461; font-weight: bold } /* Keyword */
.highlight .l { color: #000 } /* Literal */
.highlight .n { color: #000 } /* Name */
.highlight .o { color: #582800 } /* Operator */
.highlight .x { color: #000 } /* Other */
.highlight .p { color: #000; font-weight: bold } /* Punctuation */
.highlight .ch { color: #8F5902; font-style: italic } /* Comment.Hashbang */
.highlight .cm { color: #8F5902; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #8F5902 } /* Comment.Preproc */
.highlight .cpf { color: #8F5902; font-style: italic } /* Comment.PreprocFile */
.highlight .c1 { color: #8F5902; font-style: italic } /* Comment.Single */
.highlight .cs { color: #8F5902; font-style: italic } /* Comment.Special */
.highlight .gd { color: #A40000 } /* Generic.Deleted */
.highlight .ge { color: #000; font-style: italic } /* Generic.Emph */
.highlight .ges { color: #000 } /* Generic.EmphStrong */
.highlight .gr { color: #EF2929 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
.highlight .go { color: #888 } /* Generic.Output */
.highlight .gp { color: #745334 } /* Generic.Prompt */
.highlight .gs { color: #000; font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #A40000; font-weight: bold } /* Generic.Traceback */
.highlight .kc { color: #004461; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #004461; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #004461; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #004461; font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { color: #004461; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #004461; font-weight: bold } /* Keyword.Type */
.highlight .ld { color: #000 } /* Literal.Date */
.highlight .m { color: #900 } /* Literal.Number */
.highlight .s { color: #4E9A06 } /* Literal.String */
.highlight .na { color: #C4A000 } /* Name.Attribute */
.highlight .nb { color: #004461 } /* Name.Builtin */
.highlight .nc { color: #000 } /* Name.Class */
.highlight .no { color: #000 } /* Name.Constant */
.highlight .nd { color: #888 } /* Name.Decorator */
.highlight .ni { color: #CE5C00 } /* Name.Entity */
.highlight .ne { color: #C00; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #000 } /* Name.Function */
.highlight .nl { color: #F57900 } /* Name.Label */
.highlight .nn { color: #000 } /* Name.Namespace */
.highlight .nx { color: #000 } /* Name.Other */
.highlight .py { color: #000 } /* Name.Property */
.highlight .nt { color: #004461; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #000 } /* Name.Variable */
.highlight .ow { color: #004461; font-weight: bold } /* Operator.Word */
.highlight .pm { color: #000; font-weight: bold } /* Punctuation.Marker */
.highlight .w { color: #F8F8F8 } /* Text.Whitespace */
.highlight .mb { color: #900 } /* Literal.Number.Bin */
.highlight .mf { color: #900 } /* Literal.Number.Float */
.highlight .mh { color: #900 } /* Literal.Number.Hex */
.highlight .mi { color: #900 } /* Literal.Number.Integer */
.highlight .mo { color: #900 } /* Literal.Number.Oct */
.highlight .sa { color: #4E9A06 } /* Literal.String.Affix */
.highlight .sb { color: #4E9A06 } /* Literal.String.Backtick */
.highlight .sc { color: #4E9A06 } /* Literal.String.Char */
.highlight .dl { color: #4E9A06 } /* Literal.String.Delimiter */
.highlight .sd { color: #8F5902; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #4E9A06 } /* Literal.String.Double */
.highlight .se { color: #4E9A06 } /* Literal.String.Escape */
.highlight .sh { color: #4E9A06 } /* Literal.String.Heredoc */
.highlight .si { color: #4E9A06 } /* Literal.String.Interpol */
.highlight .sx { color: #4E9A06 } /* Literal.String.Other */
.highlight .sr { color: #4E9A06 } /* Literal.String.Regex */
.highlight .s1 { color: #4E9A06 } /* Literal.String.Single */
.highlight .ss { color: #4E9A06 } /* Literal.String.Symbol */
.highlight .bp { color: #3465A4 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #000 } /* Name.Function.Magic */
.highlight .vc { color: #000 } /* Name.Variable.Class */
.highlight .vg { color: #000 } /* Name.Variable.Global */
.highlight .vi { color: #000 } /* Name.Variable.Instance */
.highlight .vm { color: #000 } /* Name.Variable.Magic */
.highlight .il { color: #900 } /* Literal.Number.Integer.Long */

693
docs/_build/html/_static/searchtools.js vendored Normal file
View File

@@ -0,0 +1,693 @@
/*
* Sphinx JavaScript utilities for the full-text search.
*/
"use strict";
/**
* Simple result scoring code.
*/
if (typeof Scorer === "undefined") {
var Scorer = {
// Implement the following function to further tweak the score for each result
// The function takes a result array [docname, title, anchor, descr, score, filename]
// and returns the new score.
/*
score: result => {
const [docname, title, anchor, descr, score, filename, kind] = result
return score
},
*/
// query matches the full name of an object
objNameMatch: 11,
// or matches in the last dotted part of the object name
objPartialMatch: 6,
// Additive scores depending on the priority of the object
objPrio: {
0: 15, // used to be importantResults
1: 5, // used to be objectResults
2: -5, // used to be unimportantResults
},
// Used when the priority is not in the mapping.
objPrioDefault: 0,
// query found in title
title: 15,
partialTitle: 7,
// query found in terms
term: 5,
partialTerm: 2,
};
}
// Global search result kind enum, used by themes to style search results.
// prettier-ignore
class SearchResultKind {
static get index() { return "index"; }
static get object() { return "object"; }
static get text() { return "text"; }
static get title() { return "title"; }
}
const _removeChildren = (element) => {
while (element && element.lastChild) element.removeChild(element.lastChild);
};
/**
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
*/
const _escapeRegExp = (string) =>
string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
const _escapeHTML = (text) => {
return text
.replaceAll("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll('"', "&quot;")
.replaceAll("'", "&apos;");
};
const _displayItem = (item, searchTerms, highlightTerms) => {
const docBuilder = DOCUMENTATION_OPTIONS.BUILDER;
const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX;
const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX;
const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY;
const contentRoot = document.documentElement.dataset.content_root;
const [docName, title, anchor, descr, score, _filename, kind] = item;
let listItem = document.createElement("li");
// Add a class representing the item's type:
// can be used by a theme's CSS selector for styling
// See SearchResultKind for the class names.
listItem.classList.add(`kind-${kind}`);
let requestUrl;
let linkUrl;
if (docBuilder === "dirhtml") {
// dirhtml builder
let dirname = docName + "/";
if (dirname.match(/\/index\/$/))
dirname = dirname.substring(0, dirname.length - 6);
else if (dirname === "index/") dirname = "";
requestUrl = contentRoot + dirname;
linkUrl = requestUrl;
} else {
// normal html builders
requestUrl = contentRoot + docName + docFileSuffix;
linkUrl = docName + docLinkSuffix;
}
let linkEl = listItem.appendChild(document.createElement("a"));
linkEl.href = linkUrl + anchor;
linkEl.dataset.score = score;
linkEl.innerHTML = _escapeHTML(title);
if (descr) {
listItem.appendChild(document.createElement("span")).innerHTML =
` (${_escapeHTML(descr)})`;
// highlight search terms in the description
if (SPHINX_HIGHLIGHT_ENABLED)
// SPHINX_HIGHLIGHT_ENABLED is set in sphinx_highlight.js
highlightTerms.forEach((term) =>
_highlightText(listItem, term, "highlighted"),
);
} else if (showSearchSummary)
fetch(requestUrl)
.then((responseData) => responseData.text())
.then((data) => {
if (data)
listItem.appendChild(
Search.makeSearchSummary(data, searchTerms, anchor),
);
// highlight search terms in the summary
if (SPHINX_HIGHLIGHT_ENABLED)
// SPHINX_HIGHLIGHT_ENABLED is set in sphinx_highlight.js
highlightTerms.forEach((term) =>
_highlightText(listItem, term, "highlighted"),
);
});
Search.output.appendChild(listItem);
};
const _finishSearch = (resultCount) => {
Search.stopPulse();
Search.title.innerText = _("Search Results");
if (!resultCount)
Search.status.innerText = Documentation.gettext(
"Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories.",
);
else
Search.status.innerText = Documentation.ngettext(
"Search finished, found one page matching the search query.",
"Search finished, found ${resultCount} pages matching the search query.",
resultCount,
).replace("${resultCount}", resultCount);
};
const _displayNextItem = (
results,
resultCount,
searchTerms,
highlightTerms,
) => {
// results left, load the summary and display it
// this is intended to be dynamic (don't sub resultsCount)
if (results.length) {
_displayItem(results.pop(), searchTerms, highlightTerms);
setTimeout(
() => _displayNextItem(results, resultCount, searchTerms, highlightTerms),
5,
);
}
// search finished, update title and status message
else _finishSearch(resultCount);
};
// Helper function used by query() to order search results.
// Each input is an array of [docname, title, anchor, descr, score, filename, kind].
// Order the results by score (in opposite order of appearance, since the
// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically.
const _orderResultsByScoreThenName = (a, b) => {
const leftScore = a[4];
const rightScore = b[4];
if (leftScore === rightScore) {
// same score: sort alphabetically
const leftTitle = a[1].toLowerCase();
const rightTitle = b[1].toLowerCase();
if (leftTitle === rightTitle) return 0;
return leftTitle > rightTitle ? -1 : 1; // inverted is intentional
}
return leftScore > rightScore ? 1 : -1;
};
/**
* Default splitQuery function. Can be overridden in ``sphinx.search`` with a
* custom function per language.
*
* The regular expression works by splitting the string on consecutive characters
* that are not Unicode letters, numbers, underscores, or emoji characters.
* This is the same as ``\W+`` in Python, preserving the surrogate pair area.
*/
if (typeof splitQuery === "undefined") {
var splitQuery = (query) =>
query
.split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu)
.filter((term) => term); // remove remaining empty strings
}
/**
* Search Module
*/
const Search = {
_index: null,
_queued_query: null,
_pulse_status: -1,
htmlToText: (htmlString, anchor) => {
const htmlElement = new DOMParser().parseFromString(
htmlString,
"text/html",
);
for (const removalQuery of [".headerlink", "script", "style"]) {
htmlElement.querySelectorAll(removalQuery).forEach((el) => {
el.remove();
});
}
if (anchor) {
const anchorContent = htmlElement.querySelector(
`[role="main"] ${anchor}`,
);
if (anchorContent) return anchorContent.textContent;
console.warn(
`Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.`,
);
}
// if anchor not specified or not found, fall back to main content
const docContent = htmlElement.querySelector('[role="main"]');
if (docContent) return docContent.textContent;
console.warn(
"Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template.",
);
return "";
},
init: () => {
const query = new URLSearchParams(window.location.search).get("q");
document
.querySelectorAll('input[name="q"]')
.forEach((el) => (el.value = query));
if (query) Search.performSearch(query);
},
loadIndex: (url) =>
(document.body.appendChild(document.createElement("script")).src = url),
setIndex: (index) => {
Search._index = index;
if (Search._queued_query !== null) {
const query = Search._queued_query;
Search._queued_query = null;
Search.query(query);
}
},
hasIndex: () => Search._index !== null,
deferQuery: (query) => (Search._queued_query = query),
stopPulse: () => (Search._pulse_status = -1),
startPulse: () => {
if (Search._pulse_status >= 0) return;
const pulse = () => {
Search._pulse_status = (Search._pulse_status + 1) % 4;
Search.dots.innerText = ".".repeat(Search._pulse_status);
if (Search._pulse_status >= 0) window.setTimeout(pulse, 500);
};
pulse();
},
/**
* perform a search for something (or wait until index is loaded)
*/
performSearch: (query) => {
// create the required interface elements
const searchText = document.createElement("h2");
searchText.textContent = _("Searching");
const searchSummary = document.createElement("p");
searchSummary.classList.add("search-summary");
searchSummary.innerText = "";
const searchList = document.createElement("ul");
searchList.setAttribute("role", "list");
searchList.classList.add("search");
const out = document.getElementById("search-results");
Search.title = out.appendChild(searchText);
Search.dots = Search.title.appendChild(document.createElement("span"));
Search.status = out.appendChild(searchSummary);
Search.output = out.appendChild(searchList);
const searchProgress = document.getElementById("search-progress");
// Some themes don't use the search progress node
if (searchProgress) {
searchProgress.innerText = _("Preparing search...");
}
Search.startPulse();
// index already loaded, the browser was quick!
if (Search.hasIndex()) Search.query(query);
else Search.deferQuery(query);
},
_parseQuery: (query) => {
// stem the search terms and add them to the correct list
const stemmer = new Stemmer();
const searchTerms = new Set();
const excludedTerms = new Set();
const highlightTerms = new Set();
const objectTerms = new Set(splitQuery(query.toLowerCase().trim()));
splitQuery(query.trim()).forEach((queryTerm) => {
const queryTermLower = queryTerm.toLowerCase();
// maybe skip this "word"
// stopwords set is from language_data.js
if (stopwords.has(queryTermLower) || queryTerm.match(/^\d+$/)) return;
// stem the word
let word = stemmer.stemWord(queryTermLower);
// select the correct list
if (word[0] === "-") excludedTerms.add(word.substr(1));
else {
searchTerms.add(word);
highlightTerms.add(queryTermLower);
}
});
if (SPHINX_HIGHLIGHT_ENABLED) {
// SPHINX_HIGHLIGHT_ENABLED is set in sphinx_highlight.js
localStorage.setItem(
"sphinx_highlight_terms",
[...highlightTerms].join(" "),
);
}
// console.debug("SEARCH: searching for:");
// console.info("required: ", [...searchTerms]);
// console.info("excluded: ", [...excludedTerms]);
return [query, searchTerms, excludedTerms, highlightTerms, objectTerms];
},
/**
* execute search (requires search index to be loaded)
*/
_performSearch: (
query,
searchTerms,
excludedTerms,
highlightTerms,
objectTerms,
) => {
const filenames = Search._index.filenames;
const docNames = Search._index.docnames;
const titles = Search._index.titles;
const allTitles = Search._index.alltitles;
const indexEntries = Search._index.indexentries;
// Collect multiple result groups to be sorted separately and then ordered.
// Each is an array of [docname, title, anchor, descr, score, filename, kind].
const normalResults = [];
const nonMainIndexResults = [];
_removeChildren(document.getElementById("search-progress"));
const queryLower = query.toLowerCase().trim();
for (const [title, foundTitles] of Object.entries(allTitles)) {
if (
title.toLowerCase().trim().includes(queryLower)
&& queryLower.length >= title.length / 2
) {
for (const [file, id] of foundTitles) {
const score = Math.round(
(Scorer.title * queryLower.length) / title.length,
);
const boost = titles[file] === title ? 1 : 0; // add a boost for document titles
normalResults.push([
docNames[file],
titles[file] !== title ? `${titles[file]} > ${title}` : title,
id !== null ? "#" + id : "",
null,
score + boost,
filenames[file],
SearchResultKind.title,
]);
}
}
}
// search for explicit entries in index directives
for (const [entry, foundEntries] of Object.entries(indexEntries)) {
if (entry.includes(queryLower) && queryLower.length >= entry.length / 2) {
for (const [file, id, isMain] of foundEntries) {
const score = Math.round((100 * queryLower.length) / entry.length);
const result = [
docNames[file],
titles[file],
id ? "#" + id : "",
null,
score,
filenames[file],
SearchResultKind.index,
];
if (isMain) {
normalResults.push(result);
} else {
nonMainIndexResults.push(result);
}
}
}
}
// lookup as object
objectTerms.forEach((term) =>
normalResults.push(...Search.performObjectSearch(term, objectTerms)),
);
// lookup as search terms in fulltext
normalResults.push(
...Search.performTermsSearch(searchTerms, excludedTerms),
);
// let the scorer override scores with a custom scoring function
if (Scorer.score) {
normalResults.forEach((item) => (item[4] = Scorer.score(item)));
nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item)));
}
// Sort each group of results by score and then alphabetically by name.
normalResults.sort(_orderResultsByScoreThenName);
nonMainIndexResults.sort(_orderResultsByScoreThenName);
// Combine the result groups in (reverse) order.
// Non-main index entries are typically arbitrary cross-references,
// so display them after other results.
let results = [...nonMainIndexResults, ...normalResults];
// remove duplicate search results
// note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept
let seen = new Set();
results = results.reverse().reduce((acc, result) => {
let resultStr = result
.slice(0, 4)
.concat([result[5]])
.map((v) => String(v))
.join(",");
if (!seen.has(resultStr)) {
acc.push(result);
seen.add(resultStr);
}
return acc;
}, []);
return results.reverse();
},
query: (query) => {
const [
searchQuery,
searchTerms,
excludedTerms,
highlightTerms,
objectTerms,
] = Search._parseQuery(query);
const results = Search._performSearch(
searchQuery,
searchTerms,
excludedTerms,
highlightTerms,
objectTerms,
);
// for debugging
//Search.lastresults = results.slice(); // a copy
// console.info("search results:", Search.lastresults);
// print the results
_displayNextItem(results, results.length, searchTerms, highlightTerms);
},
/**
* search for object names
*/
performObjectSearch: (object, objectTerms) => {
const filenames = Search._index.filenames;
const docNames = Search._index.docnames;
const objects = Search._index.objects;
const objNames = Search._index.objnames;
const titles = Search._index.titles;
const results = [];
const objectSearchCallback = (prefix, match) => {
const name = match[4];
const fullname = (prefix ? prefix + "." : "") + name;
const fullnameLower = fullname.toLowerCase();
if (fullnameLower.indexOf(object) < 0) return;
let score = 0;
const parts = fullnameLower.split(".");
// check for different match types: exact matches of full name or
// "last name" (i.e. last dotted part)
if (fullnameLower === object || parts.slice(-1)[0] === object)
score += Scorer.objNameMatch;
else if (parts.slice(-1)[0].indexOf(object) > -1)
score += Scorer.objPartialMatch; // matches in last name
const objName = objNames[match[1]][2];
const title = titles[match[0]];
// If more than one term searched for, we require other words to be
// found in the name/title/description
const otherTerms = new Set(objectTerms);
otherTerms.delete(object);
if (otherTerms.size > 0) {
const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase();
if (
[...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0)
)
return;
}
let anchor = match[3];
if (anchor === "") anchor = fullname;
else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname;
const descr = objName + _(", in ") + title;
// add custom score for some objects according to scorer
if (Scorer.objPrio.hasOwnProperty(match[2]))
score += Scorer.objPrio[match[2]];
else score += Scorer.objPrioDefault;
results.push([
docNames[match[0]],
fullname,
"#" + anchor,
descr,
score,
filenames[match[0]],
SearchResultKind.object,
]);
};
Object.keys(objects).forEach((prefix) =>
objects[prefix].forEach((array) => objectSearchCallback(prefix, array)),
);
return results;
},
/**
* search for full-text terms in the index
*/
performTermsSearch: (searchTerms, excludedTerms) => {
// prepare search
const terms = Search._index.terms;
const titleTerms = Search._index.titleterms;
const filenames = Search._index.filenames;
const docNames = Search._index.docnames;
const titles = Search._index.titles;
const scoreMap = new Map();
const fileMap = new Map();
// perform the search on the required terms
searchTerms.forEach((word) => {
const files = [];
// find documents, if any, containing the query word in their text/title term indices
// use Object.hasOwnProperty to avoid mismatching against prototype properties
const arr = [
{
files: terms.hasOwnProperty(word) ? terms[word] : undefined,
score: Scorer.term,
},
{
files: titleTerms.hasOwnProperty(word) ? titleTerms[word] : undefined,
score: Scorer.title,
},
];
// add support for partial matches
if (word.length > 2) {
const escapedWord = _escapeRegExp(word);
if (!terms.hasOwnProperty(word)) {
Object.keys(terms).forEach((term) => {
if (term.match(escapedWord))
arr.push({ files: terms[term], score: Scorer.partialTerm });
});
}
if (!titleTerms.hasOwnProperty(word)) {
Object.keys(titleTerms).forEach((term) => {
if (term.match(escapedWord))
arr.push({ files: titleTerms[term], score: Scorer.partialTitle });
});
}
}
// no match but word was a required one
if (arr.every((record) => record.files === undefined)) return;
// found search word in contents
arr.forEach((record) => {
if (record.files === undefined) return;
let recordFiles = record.files;
if (recordFiles.length === undefined) recordFiles = [recordFiles];
files.push(...recordFiles);
// set score for the word in each file
recordFiles.forEach((file) => {
if (!scoreMap.has(file)) scoreMap.set(file, new Map());
const fileScores = scoreMap.get(file);
fileScores.set(word, record.score);
});
});
// create the mapping
files.forEach((file) => {
if (!fileMap.has(file)) fileMap.set(file, [word]);
else if (fileMap.get(file).indexOf(word) === -1)
fileMap.get(file).push(word);
});
});
// now check if the files don't contain excluded terms
const results = [];
for (const [file, wordList] of fileMap) {
// check if all requirements are matched
// as search terms with length < 3 are discarded
const filteredTermCount = [...searchTerms].filter(
(term) => term.length > 2,
).length;
if (
wordList.length !== searchTerms.size
&& wordList.length !== filteredTermCount
)
continue;
// ensure that none of the excluded terms is in the search result
if (
[...excludedTerms].some(
(term) =>
terms[term] === file
|| titleTerms[term] === file
|| (terms[term] || []).includes(file)
|| (titleTerms[term] || []).includes(file),
)
)
break;
// select one (max) score for the file.
const score = Math.max(...wordList.map((w) => scoreMap.get(file).get(w)));
// add result to the result list
results.push([
docNames[file],
titles[file],
"",
null,
score,
filenames[file],
SearchResultKind.text,
]);
}
return results;
},
/**
* helper function to return a node containing the
* search summary for a given text. keywords is a list
* of stemmed words.
*/
makeSearchSummary: (htmlText, keywords, anchor) => {
const text = Search.htmlToText(htmlText, anchor);
if (text === "") return null;
const textLower = text.toLowerCase();
const actualStartPosition = [...keywords]
.map((k) => textLower.indexOf(k.toLowerCase()))
.filter((i) => i > -1)
.slice(-1)[0];
const startWithContext = Math.max(actualStartPosition - 120, 0);
const top = startWithContext === 0 ? "" : "...";
const tail = startWithContext + 240 < text.length ? "..." : "";
let summary = document.createElement("p");
summary.classList.add("context");
summary.textContent =
top + text.substr(startWithContext, 240).trim() + tail;
return summary;
},
};
_ready(Search.init);

View File

@@ -0,0 +1,159 @@
/* Highlighting utilities for Sphinx HTML documentation. */
"use strict";
const SPHINX_HIGHLIGHT_ENABLED = true;
/**
* highlight a given string on a node by wrapping it in
* span elements with the given class name.
*/
const _highlight = (node, addItems, text, className) => {
if (node.nodeType === Node.TEXT_NODE) {
const val = node.nodeValue;
const parent = node.parentNode;
const pos = val.toLowerCase().indexOf(text);
if (
pos >= 0
&& !parent.classList.contains(className)
&& !parent.classList.contains("nohighlight")
) {
let span;
const closestNode = parent.closest("body, svg, foreignObject");
const isInSVG = closestNode && closestNode.matches("svg");
if (isInSVG) {
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
} else {
span = document.createElement("span");
span.classList.add(className);
}
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
const rest = document.createTextNode(val.substr(pos + text.length));
parent.insertBefore(span, parent.insertBefore(rest, node.nextSibling));
node.nodeValue = val.substr(0, pos);
/* There may be more occurrences of search term in this node. So call this
* function recursively on the remaining fragment.
*/
_highlight(rest, addItems, text, className);
if (isInSVG) {
const rect = document.createElementNS(
"http://www.w3.org/2000/svg",
"rect",
);
const bbox = parent.getBBox();
rect.x.baseVal.value = bbox.x;
rect.y.baseVal.value = bbox.y;
rect.width.baseVal.value = bbox.width;
rect.height.baseVal.value = bbox.height;
rect.setAttribute("class", className);
addItems.push({ parent: parent, target: rect });
}
}
} else if (node.matches && !node.matches("button, select, textarea")) {
node.childNodes.forEach((el) => _highlight(el, addItems, text, className));
}
};
const _highlightText = (thisNode, text, className) => {
let addItems = [];
_highlight(thisNode, addItems, text, className);
addItems.forEach((obj) =>
obj.parent.insertAdjacentElement("beforebegin", obj.target),
);
};
/**
* Small JavaScript module for the documentation.
*/
const SphinxHighlight = {
/**
* highlight the search words provided in localstorage in the text
*/
highlightSearchWords: () => {
if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight
// get and clear terms from localstorage
const url = new URL(window.location);
const highlight =
localStorage.getItem("sphinx_highlight_terms")
|| url.searchParams.get("highlight")
|| "";
localStorage.removeItem("sphinx_highlight_terms");
// Update history only if '?highlight' is present; otherwise it
// clears text fragments (not set in window.location by the browser)
if (url.searchParams.has("highlight")) {
url.searchParams.delete("highlight");
window.history.replaceState({}, "", url);
}
// get individual terms from highlight string
const terms = highlight
.toLowerCase()
.split(/\s+/)
.filter((x) => x);
if (terms.length === 0) return; // nothing to do
// There should never be more than one element matching "div.body"
const divBody = document.querySelectorAll("div.body");
const body = divBody.length ? divBody[0] : document.querySelector("body");
window.setTimeout(() => {
terms.forEach((term) => _highlightText(body, term, "highlighted"));
}, 10);
const searchBox = document.getElementById("searchbox");
if (searchBox === null) return;
searchBox.appendChild(
document
.createRange()
.createContextualFragment(
'<p class="highlight-link">'
+ '<a href="javascript:SphinxHighlight.hideSearchWords()">'
+ _("Hide Search Matches")
+ "</a></p>",
),
);
},
/**
* helper function to hide the search marks again
*/
hideSearchWords: () => {
document
.querySelectorAll("#searchbox .highlight-link")
.forEach((el) => el.remove());
document
.querySelectorAll("span.highlighted")
.forEach((el) => el.classList.remove("highlighted"));
localStorage.removeItem("sphinx_highlight_terms");
},
initEscapeListener: () => {
// only install a listener if it is really needed
if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return;
document.addEventListener("keydown", (event) => {
// bail for input elements
if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName))
return;
// bail with special keys
if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey)
return;
if (
DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS
&& event.key === "Escape"
) {
SphinxHighlight.hideSearchWords();
event.preventDefault();
}
});
},
};
_ready(() => {
/* Do not call highlightSearchWords() when we are on the search page.
* It will highlight words from the *previous* search query.
*/
if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords();
SphinxHighlight.initEscapeListener();
});

801
docs/_build/html/api_reference.html vendored Normal file
View File

@@ -0,0 +1,801 @@
<!DOCTYPE html>
<html lang="en" data-content_root="./">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Riferimento API &#8212; warehouse 0.0.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=5ecbeea2" />
<link rel="stylesheet" type="text/css" href="_static/basic.css?v=b08954a9" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=27fed22d" />
<script src="_static/documentation_options.js?v=d45e8c67"></script>
<script src="_static/doctools.js?v=fd6eb6e6"></script>
<script src="_static/sphinx_highlight.js?v=6ffebe34"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Flow Diagrams" href="flows/index.html" />
<link rel="prev" title="Architettura Complessiva" href="architecture.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="riferimento-api">
<h1>Riferimento API<a class="headerlink" href="#riferimento-api" title="Link to this heading"></a></h1>
<p>La sezione seguente usa <code class="docutils literal notranslate"><span class="pre">autodoc</span></code> per estrarre docstring direttamente dai
moduli Python principali del progetto.</p>
<section id="module-main">
<span id="main-py"></span><h2>main.py<a class="headerlink" href="#module-main" title="Link to this heading"></a></h2>
<p>Application entry point for the warehouse desktop tool.</p>
<p>This module wires together the shared async database client, the global
background event loop and the different Tk/CustomTkinter windows exposed by the
project.</p>
<dl class="py function">
<dt class="sig sig-object py" id="main.open_pickinglist_window">
<span class="sig-prename descclassname"><span class="pre">main.</span></span><span class="sig-name descname"><span class="pre">open_pickinglist_window</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">parent</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">db_client</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#main.open_pickinglist_window" title="Link to this definition"></a></dt>
<dd><p>Open the picking list window while minimizing initial flicker.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>parent</strong> (<em>Misc</em>)</p></li>
<li><p><strong>db_client</strong> (<a class="reference internal" href="#async_msssql_query.AsyncMSSQLClient" title="async_msssql_query.AsyncMSSQLClient"><em>AsyncMSSQLClient</em></a>)</p></li>
</ul>
</dd>
</dl>
</dd></dl>
<dl class="py class">
<dt class="sig sig-object py" id="main.Launcher">
<span class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></span><span class="sig-prename descclassname"><span class="pre">main.</span></span><span class="sig-name descname"><span class="pre">Launcher</span></span><a class="headerlink" href="#main.Launcher" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">CTk</span></code></p>
<p>Main launcher window that exposes the available warehouse tools.</p>
</dd></dl>
</section>
<section id="module-async_msssql_query">
<span id="async-msssql-query-py"></span><h2>async_msssql_query.py<a class="headerlink" href="#module-async_msssql_query" title="Link to this heading"></a></h2>
<p>Async SQL Server access layer used by the warehouse application.</p>
<p>The module centralizes DSN creation and exposes <a class="reference internal" href="#async_msssql_query.AsyncMSSQLClient" title="async_msssql_query.AsyncMSSQLClient"><code class="xref py py-class docutils literal notranslate"><span class="pre">AsyncMSSQLClient</span></code></a>,
which lazily binds a SQLAlchemy async engine to the running event loop. The
implementation intentionally avoids pooling because the GUI schedules work on a
single shared background loop and pooled connections were a source of
cross-loop errors.</p>
<dl class="py function">
<dt class="sig sig-object py" id="async_msssql_query.make_mssql_dsn">
<span class="sig-prename descclassname"><span class="pre">async_msssql_query.</span></span><span class="sig-name descname"><span class="pre">make_mssql_dsn</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="keyword-only-separator o"><abbr title="Keyword-only parameters separator (PEP 3102)"><span class="pre">*</span></abbr></span></em>, <em class="sig-param"><span class="n"><span class="pre">server</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">database</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">user</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">password</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">driver</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">'ODBC</span> <span class="pre">Driver</span> <span class="pre">17</span> <span class="pre">for</span> <span class="pre">SQL</span> <span class="pre">Server'</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">trust_server_certificate</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">encrypt</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">extra_odbc_kv</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#async_msssql_query.make_mssql_dsn" title="Link to this definition"></a></dt>
<dd><p>Build a SQLAlchemy <code class="docutils literal notranslate"><span class="pre">mssql+aioodbc</span></code> DSN from SQL Server parameters.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>server</strong> (<em>str</em>)</p></li>
<li><p><strong>database</strong> (<em>str</em>)</p></li>
<li><p><strong>user</strong> (<em>str</em><em> | </em><em>None</em>)</p></li>
<li><p><strong>password</strong> (<em>str</em><em> | </em><em>None</em>)</p></li>
<li><p><strong>driver</strong> (<em>str</em>)</p></li>
<li><p><strong>trust_server_certificate</strong> (<em>bool</em>)</p></li>
<li><p><strong>encrypt</strong> (<em>str</em><em> | </em><em>None</em>)</p></li>
<li><p><strong>extra_odbc_kv</strong> (<em>Dict</em><em>[</em><em>str</em><em>, </em><em>str</em><em>] </em><em>| </em><em>None</em>)</p></li>
</ul>
</dd>
<dt class="field-even">Return type<span class="colon">:</span></dt>
<dd class="field-even"><p>str</p>
</dd>
</dl>
</dd></dl>
<dl class="py class">
<dt class="sig sig-object py" id="async_msssql_query.AsyncMSSQLClient">
<span class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></span><span class="sig-prename descclassname"><span class="pre">async_msssql_query.</span></span><span class="sig-name descname"><span class="pre">AsyncMSSQLClient</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">dsn</span></span></em>, <em class="sig-param"><span class="keyword-only-separator o"><abbr title="Keyword-only parameters separator (PEP 3102)"><span class="pre">*</span></abbr></span></em>, <em class="sig-param"><span class="n"><span class="pre">echo</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">log</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">True</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#async_msssql_query.AsyncMSSQLClient" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<p>Thin async query client for SQL Server.</p>
<p>The engine is created lazily on the currently running event loop and uses
<code class="xref py py-class docutils literal notranslate"><span class="pre">sqlalchemy.pool.NullPool</span></code> to avoid recycling connections across
loops or threads.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>dsn</strong> (<em>str</em>)</p></li>
<li><p><strong>echo</strong> (<em>bool</em>)</p></li>
<li><p><strong>log</strong> (<em>bool</em>)</p></li>
</ul>
</dd>
</dl>
<dl class="py method">
<dt class="sig sig-object py" id="async_msssql_query.AsyncMSSQLClient.dispose">
<span class="property"><span class="k"><span class="pre">async</span></span><span class="w"> </span></span><span class="sig-name descname"><span class="pre">dispose</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#async_msssql_query.AsyncMSSQLClient.dispose" title="Link to this definition"></a></dt>
<dd><p>Dispose the engine on the loop where it was created.</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="async_msssql_query.AsyncMSSQLClient.query_json">
<span class="property"><span class="k"><span class="pre">async</span></span><span class="w"> </span></span><span class="sig-name descname"><span class="pre">query_json</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">sql</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">params</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="keyword-only-separator o"><abbr title="Keyword-only parameters separator (PEP 3102)"><span class="pre">*</span></abbr></span></em>, <em class="sig-param"><span class="n"><span class="pre">as_dict_rows</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#async_msssql_query.AsyncMSSQLClient.query_json" title="Link to this definition"></a></dt>
<dd><p>Execute a query and return a JSON-friendly payload.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>sql</strong> (<em>str</em>) SQL statement to execute.</p></li>
<li><p><strong>params</strong> (<em>Dict</em><em>[</em><em>str</em><em>, </em><em>Any</em><em>] </em><em>| </em><em>None</em>) Optional named parameters bound to the statement.</p></li>
<li><p><strong>as_dict_rows</strong> (<em>bool</em>) When <code class="docutils literal notranslate"><span class="pre">True</span></code> returns rows as dictionaries keyed by
column name; otherwise rows are returned as lists.</p></li>
</ul>
</dd>
<dt class="field-even">Returns<span class="colon">:</span></dt>
<dd class="field-even"><p>A dictionary containing column names, rows and elapsed execution
time in milliseconds.</p>
</dd>
<dt class="field-odd">Return type<span class="colon">:</span></dt>
<dd class="field-odd"><p><em>Dict</em>[str, <em>Any</em>]</p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="async_msssql_query.AsyncMSSQLClient.exec">
<span class="property"><span class="k"><span class="pre">async</span></span><span class="w"> </span></span><span class="sig-name descname"><span class="pre">exec</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">sql</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">params</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="keyword-only-separator o"><abbr title="Keyword-only parameters separator (PEP 3102)"><span class="pre">*</span></abbr></span></em>, <em class="sig-param"><span class="n"><span class="pre">commit</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#async_msssql_query.AsyncMSSQLClient.exec" title="Link to this definition"></a></dt>
<dd><p>Execute a DML statement and return its row count.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>sql</strong> (<em>str</em>)</p></li>
<li><p><strong>params</strong> (<em>Dict</em><em>[</em><em>str</em><em>, </em><em>Any</em><em>] </em><em>| </em><em>None</em>)</p></li>
<li><p><strong>commit</strong> (<em>bool</em>)</p></li>
</ul>
</dd>
<dt class="field-even">Return type<span class="colon">:</span></dt>
<dd class="field-even"><p>int</p>
</dd>
</dl>
</dd></dl>
</dd></dl>
</section>
<section id="module-gestione_aree_frame_async">
<span id="gestione-aree-frame-async-py"></span><h2>gestione_aree_frame_async.py<a class="headerlink" href="#module-gestione_aree_frame_async" title="Link to this heading"></a></h2>
<p>Shared Tk/async helpers used by multiple warehouse windows.</p>
<p>The module bundles three concerns used throughout the GUI:</p>
<ul class="simple">
<li><p>lifecycle of the shared background asyncio loop;</p></li>
<li><p>a modal-like busy overlay shown during long-running tasks;</p></li>
<li><p>an <code class="docutils literal notranslate"><span class="pre">AsyncRunner</span></code> that schedules coroutines and re-enters Tk safely.</p></li>
</ul>
<dl class="py function">
<dt class="sig sig-object py" id="gestione_aree_frame_async.get_global_loop">
<span class="sig-prename descclassname"><span class="pre">gestione_aree_frame_async.</span></span><span class="sig-name descname"><span class="pre">get_global_loop</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#gestione_aree_frame_async.get_global_loop" title="Link to this definition"></a></dt>
<dd><p>Return the shared background event loop, creating it if needed.</p>
<dl class="field-list simple">
<dt class="field-odd">Return type<span class="colon">:</span></dt>
<dd class="field-odd"><p><em>AbstractEventLoop</em></p>
</dd>
</dl>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="gestione_aree_frame_async.stop_global_loop">
<span class="sig-prename descclassname"><span class="pre">gestione_aree_frame_async.</span></span><span class="sig-name descname"><span class="pre">stop_global_loop</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#gestione_aree_frame_async.stop_global_loop" title="Link to this definition"></a></dt>
<dd><p>Stop the shared event loop and release thread references.</p>
</dd></dl>
<dl class="py class">
<dt class="sig sig-object py" id="gestione_aree_frame_async.BusyOverlay">
<span class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></span><span class="sig-prename descclassname"><span class="pre">gestione_aree_frame_async.</span></span><span class="sig-name descname"><span class="pre">BusyOverlay</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">parent</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#gestione_aree_frame_async.BusyOverlay" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<p>Semi-transparent overlay used to block interaction during async tasks.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>parent</strong> (<em>tk.Misc</em>)</p>
</dd>
</dl>
<dl class="py method">
<dt class="sig sig-object py" id="gestione_aree_frame_async.BusyOverlay.show">
<span class="sig-name descname"><span class="pre">show</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">message</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">'Attendere...'</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#gestione_aree_frame_async.BusyOverlay.show" title="Link to this definition"></a></dt>
<dd><p>Display the overlay or just update its message if already visible.</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="gestione_aree_frame_async.BusyOverlay.hide">
<span class="sig-name descname"><span class="pre">hide</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#gestione_aree_frame_async.BusyOverlay.hide" title="Link to this definition"></a></dt>
<dd><p>Dismiss the overlay and unregister resize bindings.</p>
</dd></dl>
</dd></dl>
<dl class="py class">
<dt class="sig sig-object py" id="gestione_aree_frame_async.AsyncRunner">
<span class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></span><span class="sig-prename descclassname"><span class="pre">gestione_aree_frame_async.</span></span><span class="sig-name descname"><span class="pre">AsyncRunner</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">widget</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#gestione_aree_frame_async.AsyncRunner" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<p>Run awaitables on the shared loop and callback on Tks main thread.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>widget</strong> (<em>tk.Misc</em>)</p>
</dd>
</dl>
<dl class="py method">
<dt class="sig sig-object py" id="gestione_aree_frame_async.AsyncRunner.run">
<span class="sig-name descname"><span class="pre">run</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">awaitable</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">on_success</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">on_error</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">busy</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">message</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">'Operazione</span> <span class="pre">in</span> <span class="pre">corso...'</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#gestione_aree_frame_async.AsyncRunner.run" title="Link to this definition"></a></dt>
<dd><p>Schedule <code class="docutils literal notranslate"><span class="pre">awaitable</span></code> and dispatch completion callbacks in Tk.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>on_success</strong> (<em>Callable</em><em>[</em><em>[</em><em>Any</em><em>]</em><em>, </em><em>None</em><em>]</em>)</p></li>
<li><p><strong>on_error</strong> (<em>Callable</em><em>[</em><em>[</em><em>BaseException</em><em>]</em><em>, </em><em>None</em><em>] </em><em>| </em><em>None</em>)</p></li>
<li><p><strong>busy</strong> (<a class="reference internal" href="#gestione_aree_frame_async.BusyOverlay" title="gestione_aree_frame_async.BusyOverlay"><em>BusyOverlay</em></a><em> | </em><em>None</em>)</p></li>
<li><p><strong>message</strong> (<em>str</em>)</p></li>
</ul>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="gestione_aree_frame_async.AsyncRunner.close">
<span class="sig-name descname"><span class="pre">close</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#gestione_aree_frame_async.AsyncRunner.close" title="Link to this definition"></a></dt>
<dd><p>No-op kept for API compatibility with older callers.</p>
</dd></dl>
</dd></dl>
</section>
<section id="module-layout_window">
<span id="layout-window-py"></span><h2>layout_window.py<a class="headerlink" href="#module-layout_window" title="Link to this heading"></a></h2>
<p>Graphical aisle layout viewer for warehouse cells and pallet occupancy.</p>
<dl class="py function">
<dt class="sig sig-object py" id="layout_window.pct_text">
<span class="sig-prename descclassname"><span class="pre">layout_window.</span></span><span class="sig-name descname"><span class="pre">pct_text</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">p_full</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">p_double</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#layout_window.pct_text" title="Link to this definition"></a></dt>
<dd><p>Format occupancy percentages for the progress-bar labels.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>p_full</strong> (<em>float</em>)</p></li>
<li><p><strong>p_double</strong> (<em>float</em><em> | </em><em>None</em>)</p></li>
</ul>
</dd>
<dt class="field-even">Return type<span class="colon">:</span></dt>
<dd class="field-even"><p>str</p>
</dd>
</dl>
</dd></dl>
<dl class="py class">
<dt class="sig sig-object py" id="layout_window.LayoutWindow">
<span class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></span><span class="sig-prename descclassname"><span class="pre">layout_window.</span></span><span class="sig-name descname"><span class="pre">LayoutWindow</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">parent</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">db_app</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#layout_window.LayoutWindow" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">CTkToplevel</span></code></p>
<p>Visualizzazione layout corsie con matrice di celle.
- Ogni cella è un pulsante colorato (vuota/piena/doppia)
- Etichetta su DUE righe:</p>
<blockquote>
<div><ol class="arabic simple">
<li><p>“Corsia.Colonna.Fila” (una sola riga, senza andare a capo)</p></li>
<li><p>barcode UDC (primo, se presente)</p></li>
</ol>
</div></blockquote>
<ul class="simple">
<li><p>Ricerca per barcode UDC con cambio automatico corsia + highlight cella</p></li>
<li><p>Statistiche: globale e corsia selezionata</p></li>
<li><p>Export XLSX</p></li>
</ul>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>parent</strong> (<em>tk.Widget</em>)</p>
</dd>
</dl>
<dl class="py method">
<dt class="sig sig-object py" id="layout_window.LayoutWindow.destroy">
<span class="sig-name descname"><span class="pre">destroy</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#layout_window.LayoutWindow.destroy" title="Link to this definition"></a></dt>
<dd><p>Mark the window as closed and release dynamic widgets safely.</p>
</dd></dl>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="layout_window.open_layout_window">
<span class="sig-prename descclassname"><span class="pre">layout_window.</span></span><span class="sig-name descname"><span class="pre">open_layout_window</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">parent</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">db_app</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#layout_window.open_layout_window" title="Link to this definition"></a></dt>
<dd><p>Open the layout window as a singleton-like child of <code class="docutils literal notranslate"><span class="pre">parent</span></code>.</p>
</dd></dl>
</section>
<section id="module-reset_corsie">
<span id="reset-corsie-py"></span><h2>reset_corsie.py<a class="headerlink" href="#module-reset_corsie" title="Link to this heading"></a></h2>
<p>Window used to inspect and empty an entire warehouse aisle.</p>
<p>The module exposes a destructive maintenance tool: it summarizes the occupancy
state of a selected aisle and, after explicit confirmation, deletes matching
rows from <code class="docutils literal notranslate"><span class="pre">MagazziniPallet</span></code>.</p>
<dl class="py class">
<dt class="sig sig-object py" id="reset_corsie.ResetCorsieWindow">
<span class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></span><span class="sig-prename descclassname"><span class="pre">reset_corsie.</span></span><span class="sig-name descname"><span class="pre">ResetCorsieWindow</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">parent</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">db_client</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#reset_corsie.ResetCorsieWindow" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">CTkToplevel</span></code></p>
<p>Toplevel used to inspect and clear the pallets assigned to an aisle.</p>
<dl class="py method">
<dt class="sig sig-object py" id="reset_corsie.ResetCorsieWindow.refresh">
<span class="sig-name descname"><span class="pre">refresh</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#reset_corsie.ResetCorsieWindow.refresh" title="Link to this definition"></a></dt>
<dd><p>Refresh both the summary counters and the occupied-cell list.</p>
</dd></dl>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="reset_corsie.open_reset_corsie_window">
<span class="sig-prename descclassname"><span class="pre">reset_corsie.</span></span><span class="sig-name descname"><span class="pre">open_reset_corsie_window</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">parent</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">db_app</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#reset_corsie.open_reset_corsie_window" title="Link to this definition"></a></dt>
<dd><p>Create, focus and return the aisle reset window.</p>
</dd></dl>
</section>
<section id="module-view_celle_multiple">
<span id="view-celle-multiple-py"></span><h2>view_celle_multiple.py<a class="headerlink" href="#module-view_celle_multiple" title="Link to this heading"></a></h2>
<p>Exploration window for cells containing more than one pallet.</p>
<dl class="py class">
<dt class="sig sig-object py" id="view_celle_multiple.CelleMultipleWindow">
<span class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></span><span class="sig-prename descclassname"><span class="pre">view_celle_multiple.</span></span><span class="sig-name descname"><span class="pre">CelleMultipleWindow</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">root</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">db_client</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">runner</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#view_celle_multiple.CelleMultipleWindow" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">CTkToplevel</span></code></p>
<p>Tree-based explorer for duplicated pallet allocations.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>runner</strong> (<a class="reference internal" href="#gestione_aree_frame_async.AsyncRunner" title="gestione_aree_frame_async.AsyncRunner"><em>AsyncRunner</em></a><em> | </em><em>None</em>)</p>
</dd>
</dl>
<dl class="py method">
<dt class="sig sig-object py" id="view_celle_multiple.CelleMultipleWindow.refresh_all">
<span class="sig-name descname"><span class="pre">refresh_all</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#view_celle_multiple.CelleMultipleWindow.refresh_all" title="Link to this definition"></a></dt>
<dd><p>Reload both the duplication tree and the summary percentage table.</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="view_celle_multiple.CelleMultipleWindow.expand_all">
<span class="sig-name descname"><span class="pre">expand_all</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#view_celle_multiple.CelleMultipleWindow.expand_all" title="Link to this definition"></a></dt>
<dd><p>Expand all aisle roots and trigger lazy loading where needed.</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="view_celle_multiple.CelleMultipleWindow.collapse_all">
<span class="sig-name descname"><span class="pre">collapse_all</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#view_celle_multiple.CelleMultipleWindow.collapse_all" title="Link to this definition"></a></dt>
<dd><p>Collapse all root nodes in the duplication tree.</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="view_celle_multiple.CelleMultipleWindow.export_to_xlsx">
<span class="sig-name descname"><span class="pre">export_to_xlsx</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#view_celle_multiple.CelleMultipleWindow.export_to_xlsx" title="Link to this definition"></a></dt>
<dd><p>Export both the detailed tree and the summary table to Excel.</p>
</dd></dl>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="view_celle_multiple.open_celle_multiple_window">
<span class="sig-prename descclassname"><span class="pre">view_celle_multiple.</span></span><span class="sig-name descname"><span class="pre">open_celle_multiple_window</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">root</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">db_client</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">runner</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#view_celle_multiple.open_celle_multiple_window" title="Link to this definition"></a></dt>
<dd><p>Create, focus and return the duplicated-cells explorer.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>root</strong> (<em>Tk</em>)</p></li>
<li><p><strong>runner</strong> (<a class="reference internal" href="#gestione_aree_frame_async.AsyncRunner" title="gestione_aree_frame_async.AsyncRunner"><em>AsyncRunner</em></a><em> | </em><em>None</em>)</p></li>
</ul>
</dd>
</dl>
</dd></dl>
</section>
<section id="module-search_pallets">
<span id="search-pallets-py"></span><h2>search_pallets.py<a class="headerlink" href="#module-search_pallets" title="Link to this heading"></a></h2>
<p>Search window for pallets, lots and product codes across the warehouse.</p>
<dl class="py class">
<dt class="sig sig-object py" id="search_pallets.SearchWindow">
<span class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></span><span class="sig-prename descclassname"><span class="pre">search_pallets.</span></span><span class="sig-name descname"><span class="pre">SearchWindow</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">parent</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">db_app</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#search_pallets.SearchWindow" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">CTkToplevel</span></code></p>
<p>Window that searches pallets by barcode, lot or product code.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>parent</strong> (<em>tk.Widget</em>)</p>
</dd>
</dl>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="search_pallets.open_search_window">
<span class="sig-prename descclassname"><span class="pre">search_pallets.</span></span><span class="sig-name descname"><span class="pre">open_search_window</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">parent</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">db_app</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#search_pallets.open_search_window" title="Link to this definition"></a></dt>
<dd><p>Open a singleton-like search window tied to the launcher instance.</p>
</dd></dl>
</section>
<section id="module-gestione_pickinglist">
<span id="gestione-pickinglist-py"></span><h2>gestione_pickinglist.py<a class="headerlink" href="#module-gestione_pickinglist" title="Link to this heading"></a></h2>
<p>Picking list management window.</p>
<p>The module presents a master/detail UI for packing lists, supports reservation
and unreservation through an async stored-procedure port and keeps rendering
smooth by relying on deferred updates and lightweight progress indicators.</p>
<dl class="py class">
<dt class="sig sig-object py" id="gestione_pickinglist.ColSpec">
<span class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></span><span class="sig-prename descclassname"><span class="pre">gestione_pickinglist.</span></span><span class="sig-name descname"><span class="pre">ColSpec</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">title</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">key</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">width</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">anchor</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#gestione_pickinglist.ColSpec" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<p>Describe one logical column rendered in a <code class="docutils literal notranslate"><span class="pre">ScrollTable</span></code>.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>title</strong> (<em>str</em>)</p></li>
<li><p><strong>key</strong> (<em>str</em>)</p></li>
<li><p><strong>width</strong> (<em>int</em>)</p></li>
<li><p><strong>anchor</strong> (<em>str</em>)</p></li>
</ul>
</dd>
</dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="gestione_pickinglist.ColSpec.title">
<span class="sig-name descname"><span class="pre">title</span></span><span class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">str</span></span><a class="headerlink" href="#gestione_pickinglist.ColSpec.title" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="gestione_pickinglist.ColSpec.key">
<span class="sig-name descname"><span class="pre">key</span></span><span class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">str</span></span><a class="headerlink" href="#gestione_pickinglist.ColSpec.key" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="gestione_pickinglist.ColSpec.width">
<span class="sig-name descname"><span class="pre">width</span></span><span class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">int</span></span><a class="headerlink" href="#gestione_pickinglist.ColSpec.width" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="gestione_pickinglist.ColSpec.anchor">
<span class="sig-name descname"><span class="pre">anchor</span></span><span class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">str</span></span><a class="headerlink" href="#gestione_pickinglist.ColSpec.anchor" title="Link to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
<dl class="py class">
<dt class="sig sig-object py" id="gestione_pickinglist.ToolbarSpinner">
<span class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></span><span class="sig-prename descclassname"><span class="pre">gestione_pickinglist.</span></span><span class="sig-name descname"><span class="pre">ToolbarSpinner</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">parent</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#gestione_pickinglist.ToolbarSpinner" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<p>Micro-animazione leggerissima per indicare attività:
mostra una label con frame: ◐ ◓ ◑ ◒ … finché è attivo.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>parent</strong> (<em>tk.Widget</em>)</p>
</dd>
</dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="gestione_pickinglist.ToolbarSpinner.FRAMES">
<span class="sig-name descname"><span class="pre">FRAMES</span></span><span class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">('◐',</span> <span class="pre">'◓',</span> <span class="pre">'◑',</span> <span class="pre">'◒')</span></span><a class="headerlink" href="#gestione_pickinglist.ToolbarSpinner.FRAMES" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="gestione_pickinglist.ToolbarSpinner.widget">
<span class="sig-name descname"><span class="pre">widget</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#gestione_pickinglist.ToolbarSpinner.widget" title="Link to this definition"></a></dt>
<dd><p>Return the label widget hosting the spinner animation.</p>
<dl class="field-list simple">
<dt class="field-odd">Return type<span class="colon">:</span></dt>
<dd class="field-odd"><p><em>CTkLabel</em></p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="gestione_pickinglist.ToolbarSpinner.start">
<span class="sig-name descname"><span class="pre">start</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">text</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">''</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#gestione_pickinglist.ToolbarSpinner.start" title="Link to this definition"></a></dt>
<dd><p>Start the animation and optionally show a short status message.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>text</strong> (<em>str</em>)</p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="gestione_pickinglist.ToolbarSpinner.stop">
<span class="sig-name descname"><span class="pre">stop</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#gestione_pickinglist.ToolbarSpinner.stop" title="Link to this definition"></a></dt>
<dd><p>Stop the animation and clear the label text.</p>
</dd></dl>
</dd></dl>
<dl class="py class">
<dt class="sig sig-object py" id="gestione_pickinglist.ScrollTable">
<span class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></span><span class="sig-prename descclassname"><span class="pre">gestione_pickinglist.</span></span><span class="sig-name descname"><span class="pre">ScrollTable</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">master</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">columns</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#gestione_pickinglist.ScrollTable" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">CTkFrame</span></code></p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>columns</strong> (<em>List</em><em>[</em><a class="reference internal" href="#gestione_pickinglist.ColSpec" title="gestione_pickinglist.ColSpec"><em>ColSpec</em></a><em>]</em>)</p>
</dd>
</dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="gestione_pickinglist.ScrollTable.GRID_COLOR">
<span class="sig-name descname"><span class="pre">GRID_COLOR</span></span><span class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">'#D0D5DD'</span></span><a class="headerlink" href="#gestione_pickinglist.ScrollTable.GRID_COLOR" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="gestione_pickinglist.ScrollTable.PADX_L">
<span class="sig-name descname"><span class="pre">PADX_L</span></span><span class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">8</span></span><a class="headerlink" href="#gestione_pickinglist.ScrollTable.PADX_L" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="gestione_pickinglist.ScrollTable.PADX_R">
<span class="sig-name descname"><span class="pre">PADX_R</span></span><span class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">8</span></span><a class="headerlink" href="#gestione_pickinglist.ScrollTable.PADX_R" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="gestione_pickinglist.ScrollTable.PADY">
<span class="sig-name descname"><span class="pre">PADY</span></span><span class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">2</span></span><a class="headerlink" href="#gestione_pickinglist.ScrollTable.PADY" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="gestione_pickinglist.ScrollTable.clear_rows">
<span class="sig-name descname"><span class="pre">clear_rows</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#gestione_pickinglist.ScrollTable.clear_rows" title="Link to this definition"></a></dt>
<dd><p>Remove all rendered body rows.</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="gestione_pickinglist.ScrollTable.add_row">
<span class="sig-name descname"><span class="pre">add_row</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">values</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">row_index</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">anchors</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">checkbox_builder</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#gestione_pickinglist.ScrollTable.add_row" title="Link to this definition"></a></dt>
<dd><p>Append one row to the table body.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>values</strong> (<em>List</em><em>[</em><em>str</em><em>]</em>)</p></li>
<li><p><strong>row_index</strong> (<em>int</em>)</p></li>
<li><p><strong>anchors</strong> (<em>List</em><em>[</em><em>str</em><em>] </em><em>| </em><em>None</em>)</p></li>
<li><p><strong>checkbox_builder</strong> (<em>Callable</em><em>[</em><em>[</em><em>Widget</em><em>]</em><em>, </em><em>CTkCheckBox</em><em>] </em><em>| </em><em>None</em>)</p></li>
</ul>
</dd>
</dl>
</dd></dl>
</dd></dl>
<dl class="py class">
<dt class="sig sig-object py" id="gestione_pickinglist.PLRow">
<span class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></span><span class="sig-prename descclassname"><span class="pre">gestione_pickinglist.</span></span><span class="sig-name descname"><span class="pre">PLRow</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">pl</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">on_check</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#gestione_pickinglist.PLRow" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<p>State holder for one picking list row and its selection checkbox.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>pl</strong> (<em>Dict</em><em>[</em><em>str</em><em>, </em><em>Any</em><em>]</em>)</p>
</dd>
</dl>
<dl class="py method">
<dt class="sig sig-object py" id="gestione_pickinglist.PLRow.is_checked">
<span class="sig-name descname"><span class="pre">is_checked</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#gestione_pickinglist.PLRow.is_checked" title="Link to this definition"></a></dt>
<dd><p>Return whether the row is currently selected.</p>
<dl class="field-list simple">
<dt class="field-odd">Return type<span class="colon">:</span></dt>
<dd class="field-odd"><p>bool</p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="gestione_pickinglist.PLRow.set_checked">
<span class="sig-name descname"><span class="pre">set_checked</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">val</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#gestione_pickinglist.PLRow.set_checked" title="Link to this definition"></a></dt>
<dd><p>Programmatically update the checkbox state.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>val</strong> (<em>bool</em>)</p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="gestione_pickinglist.PLRow.build_checkbox">
<span class="sig-name descname"><span class="pre">build_checkbox</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">parent</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#gestione_pickinglist.PLRow.build_checkbox" title="Link to this definition"></a></dt>
<dd><p>Create the checkbox widget bound to this row model.</p>
<dl class="field-list simple">
<dt class="field-odd">Return type<span class="colon">:</span></dt>
<dd class="field-odd"><p><em>CTkCheckBox</em></p>
</dd>
</dl>
</dd></dl>
</dd></dl>
<dl class="py class">
<dt class="sig sig-object py" id="gestione_pickinglist.GestionePickingListFrame">
<span class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></span><span class="sig-prename descclassname"><span class="pre">gestione_pickinglist.</span></span><span class="sig-name descname"><span class="pre">GestionePickingListFrame</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">master</span></span></em>, <em class="sig-param"><span class="keyword-only-separator o"><abbr title="Keyword-only parameters separator (PEP 3102)"><span class="pre">*</span></abbr></span></em>, <em class="sig-param"><span class="n"><span class="pre">db_client</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">conn_str</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#gestione_pickinglist.GestionePickingListFrame" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">CTkFrame</span></code></p>
<dl class="py attribute">
<dt class="sig sig-object py" id="gestione_pickinglist.GestionePickingListFrame.rows_models">
<span class="sig-name descname"><span class="pre">rows_models</span></span><span class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">list</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="#gestione_pickinglist.PLRow" title="gestione_pickinglist.PLRow"><span class="pre">PLRow</span></a><span class="p"><span class="pre">]</span></span></span><a class="headerlink" href="#gestione_pickinglist.GestionePickingListFrame.rows_models" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="gestione_pickinglist.GestionePickingListFrame.on_row_checked">
<span class="sig-name descname"><span class="pre">on_row_checked</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">model</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">is_checked</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#gestione_pickinglist.GestionePickingListFrame.on_row_checked" title="Link to this definition"></a></dt>
<dd><p>Handle row selection changes and refresh the detail section.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>model</strong> (<a class="reference internal" href="#gestione_pickinglist.PLRow" title="gestione_pickinglist.PLRow"><em>PLRow</em></a>)</p></li>
<li><p><strong>is_checked</strong> (<em>bool</em>)</p></li>
</ul>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="gestione_pickinglist.GestionePickingListFrame.reload_from_db">
<span class="sig-name descname"><span class="pre">reload_from_db</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">first</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#gestione_pickinglist.GestionePickingListFrame.reload_from_db" title="Link to this definition"></a></dt>
<dd><p>Load or reload the picking list summary table from the database.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>first</strong> (<em>bool</em>)</p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="gestione_pickinglist.GestionePickingListFrame.on_prenota">
<span class="sig-name descname"><span class="pre">on_prenota</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#gestione_pickinglist.GestionePickingListFrame.on_prenota" title="Link to this definition"></a></dt>
<dd><p>Reserve the selected picking list.</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="gestione_pickinglist.GestionePickingListFrame.on_sprenota">
<span class="sig-name descname"><span class="pre">on_sprenota</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#gestione_pickinglist.GestionePickingListFrame.on_sprenota" title="Link to this definition"></a></dt>
<dd><p>Unreserve the selected picking list.</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="gestione_pickinglist.GestionePickingListFrame.on_export">
<span class="sig-name descname"><span class="pre">on_export</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#gestione_pickinglist.GestionePickingListFrame.on_export" title="Link to this definition"></a></dt>
<dd><p>Placeholder for a future export implementation.</p>
</dd></dl>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="gestione_pickinglist.create_frame">
<span class="sig-prename descclassname"><span class="pre">gestione_pickinglist.</span></span><span class="sig-name descname"><span class="pre">create_frame</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">parent</span></span></em>, <em class="sig-param"><span class="keyword-only-separator o"><abbr title="Keyword-only parameters separator (PEP 3102)"><span class="pre">*</span></abbr></span></em>, <em class="sig-param"><span class="n"><span class="pre">db_client</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">conn_str</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#gestione_pickinglist.create_frame" title="Link to this definition"></a></dt>
<dd><p>Factory used by the launcher to build the picking list frame.</p>
<dl class="field-list simple">
<dt class="field-odd">Return type<span class="colon">:</span></dt>
<dd class="field-odd"><p><a class="reference internal" href="#gestione_pickinglist.GestionePickingListFrame" title="gestione_pickinglist.GestionePickingListFrame"><em>GestionePickingListFrame</em></a></p>
</dd>
</dl>
</dd></dl>
</section>
<section id="module-prenota_sprenota_sql">
<span id="prenota-sprenota-sql-py"></span><h2>prenota_sprenota_sql.py<a class="headerlink" href="#module-prenota_sprenota_sql" title="Link to this heading"></a></h2>
<p>Async port of the packing list reservation stored procedure.</p>
<dl class="py class">
<dt class="sig sig-object py" id="prenota_sprenota_sql.SPResult">
<span class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></span><span class="sig-prename descclassname"><span class="pre">prenota_sprenota_sql.</span></span><span class="sig-name descname"><span class="pre">SPResult</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">rc</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">0</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">message</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">''</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">id_result</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#prenota_sprenota_sql.SPResult" title="Link to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<p>Container returned by the async stored-procedure port.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>rc</strong> (<em>int</em>)</p></li>
<li><p><strong>message</strong> (<em>str</em><em> | </em><em>None</em>)</p></li>
<li><p><strong>id_result</strong> (<em>int</em><em> | </em><em>None</em>)</p></li>
</ul>
</dd>
</dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="prenota_sprenota_sql.SPResult.rc">
<span class="sig-name descname"><span class="pre">rc</span></span><span class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">int</span></span><span class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">0</span></span><a class="headerlink" href="#prenota_sprenota_sql.SPResult.rc" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="prenota_sprenota_sql.SPResult.message">
<span class="sig-name descname"><span class="pre">message</span></span><span class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">str</span><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><span class="pre">None</span></span><span class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">''</span></span><a class="headerlink" href="#prenota_sprenota_sql.SPResult.message" title="Link to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="prenota_sprenota_sql.SPResult.id_result">
<span class="sig-name descname"><span class="pre">id_result</span></span><span class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">int</span><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><span class="pre">None</span></span><span class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">None</span></span><a class="headerlink" href="#prenota_sprenota_sql.SPResult.id_result" title="Link to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="prenota_sprenota_sql.sp_xExePackingListPallet_async">
<span class="property"><span class="k"><span class="pre">async</span></span><span class="w"> </span></span><span class="sig-prename descclassname"><span class="pre">prenota_sprenota_sql.</span></span><span class="sig-name descname"><span class="pre">sp_xExePackingListPallet_async</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">db</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">IDOperatore</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">Documento</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#prenota_sprenota_sql.sp_xExePackingListPallet_async" title="Link to this definition"></a></dt>
<dd><p>Toggle the reservation state of all cells belonging to a packing list.</p>
<p>The implementation mirrors the original SQL stored procedure while using
the shared async DB client already managed by the application.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>IDOperatore</strong> (<em>int</em>)</p></li>
<li><p><strong>Documento</strong> (<em>str</em>)</p></li>
</ul>
</dd>
<dt class="field-even">Return type<span class="colon">:</span></dt>
<dd class="field-even"><p><a class="reference internal" href="#prenota_sprenota_sql.SPResult" title="prenota_sprenota_sql.SPResult"><em>SPResult</em></a></p>
</dd>
</dl>
</dd></dl>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">warehouse</a></h1>
<search id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Search"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="architecture.html">Architettura Complessiva</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Riferimento API</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#module-main">main.py</a></li>
<li class="toctree-l2"><a class="reference internal" href="#module-async_msssql_query">async_msssql_query.py</a></li>
<li class="toctree-l2"><a class="reference internal" href="#module-gestione_aree_frame_async">gestione_aree_frame_async.py</a></li>
<li class="toctree-l2"><a class="reference internal" href="#module-layout_window">layout_window.py</a></li>
<li class="toctree-l2"><a class="reference internal" href="#module-reset_corsie">reset_corsie.py</a></li>
<li class="toctree-l2"><a class="reference internal" href="#module-view_celle_multiple">view_celle_multiple.py</a></li>
<li class="toctree-l2"><a class="reference internal" href="#module-search_pallets">search_pallets.py</a></li>
<li class="toctree-l2"><a class="reference internal" href="#module-gestione_pickinglist">gestione_pickinglist.py</a></li>
<li class="toctree-l2"><a class="reference internal" href="#module-prenota_sprenota_sql">prenota_sprenota_sql.py</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="flows/index.html">Flow Diagrams</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
<li>Previous: <a href="architecture.html" title="previous chapter">Architettura Complessiva</a></li>
<li>Next: <a href="flows/index.html" title="next chapter">Flow Diagrams</a></li>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 9.1.0</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 1.0.0</a>
|
<a href="_sources/api_reference.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

600
docs/_build/html/architecture.html vendored Normal file
View File

@@ -0,0 +1,600 @@
<!DOCTYPE html>
<html lang="en" data-content_root="./">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Architettura Complessiva &#8212; warehouse 0.0.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=5ecbeea2" />
<link rel="stylesheet" type="text/css" href="_static/basic.css?v=b08954a9" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=27fed22d" />
<script src="_static/documentation_options.js?v=d45e8c67"></script>
<script src="_static/doctools.js?v=fd6eb6e6"></script>
<script src="_static/sphinx_highlight.js?v=6ffebe34"></script>
<script src="https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js"></script>
<script type="module">import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11.12.1/dist/mermaid.esm.min.mjs";
const initStyles = () => {
const defaultStyle = document.createElement('style');
defaultStyle.textContent = `pre.mermaid {
/* Same as .mermaid-container > pre */
display: block;
width: 100%;
}
pre.mermaid > svg {
/* Same as .mermaid-container > pre > svg */
height: 500px;
width: 100%;
max-width: 100% !important;
}`;
document.head.appendChild(defaultStyle);
const fullscreenStyle = document.createElement('style');
fullscreenStyle.textContent = `.mermaid-container {
display: flex;
flex-direction: row;
width: 100%;
}
.mermaid-container > pre {
display: block;
width: 100%;
}
.mermaid-container > pre > svg {
height: 500px;
width: 100%;
max-width: 100% !important;
}
.mermaid-fullscreen-btn {
width: 28px;
height: 28px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
font-size: 14px;
line-height: 1;
padding: 0;
color: #333;
}
.mermaid-fullscreen-btn:hover {
opacity: 100% !important;
background: rgba(255, 255, 255, 1);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
transform: scale(1.1);
}
.mermaid-fullscreen-btn.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.3);
color: #e0e0e0;
}
.mermaid-fullscreen-btn.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 3px 10px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal {
display: none;
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 95vw;
height: 100vh;
background: rgba(255, 255, 255, 0.98);
z-index: 9999;
padding: 20px;
overflow: auto;
}
.mermaid-fullscreen-modal.dark-theme {
background: rgba(0, 0, 0, 0.98);
}
.mermaid-fullscreen-modal.active {
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen {
position: relative;
width: 95vw;
height: 90vh;
max-width: 95vw;
max-height: 90vh;
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
overflow: auto;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen.dark-theme {
background: #1a1a1a;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);
}
.mermaid-container-fullscreen pre.mermaid {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen .mermaid svg {
height: 100% !important;
width: 100% !important;
cursor: grab;
}
.mermaid-fullscreen-close {
position: fixed !important;
top: 20px !important;
right: 20px !important;
width: 40px;
height: 40px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 50%;
cursor: pointer;
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
transition: all 0.2s;
font-size: 24px;
line-height: 1;
color: #333;
}
.mermaid-fullscreen-close:hover {
background: white;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
transform: scale(1.1);
}
.mermaid-fullscreen-close.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.2);
color: #e0e0e0;
}
.mermaid-fullscreen-close.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 6px 16px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal .mermaid-fullscreen-btn {
display: none !important;
}`;
document.head.appendChild(fullscreenStyle);
}
// Detect if page has dark background
const isDarkTheme = () => {
// We use a set of heuristics:
// 1. Check for common dark mode classes or attributes
// 2. Check computed background color brightness
if (document.documentElement.classList.contains('dark') ||
document.documentElement.getAttribute('data-theme') === 'dark' ||
document.body.classList.contains('dark') ||
document.body.getAttribute('data-theme') === 'dark') {
// console.log("Dark theme detected via class/attribute");
return true;
}
if (document.documentElement.classList.contains('light') ||
document.documentElement.getAttribute('data-theme') === 'light' ||
document.body.classList.contains('light') ||
document.body.getAttribute('data-theme') === 'light') {
// console.log("Light theme detected via class/attribute");
return false;
}
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
// console.log("Dark theme detected via prefers-color-scheme");
return true;
}
const bgColor = window.getComputedStyle(document.body).backgroundColor;
const match = bgColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)/);
if (match) {
const r = parseInt(match[1]);
const g = parseInt(match[2]);
const b = parseInt(match[3]);
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
// console.log("Background color brightness:", brightness);
return brightness < 128;
}
// console.log("No dark or light theme detected, defaulting to light theme");
return false;
};
let darkTheme = isDarkTheme();
let modal = null;
let modalContent = null;
let previousScrollOffset = [window.scrollX, window.scrollY];
const runMermaid = async (rerun) => {
console.log("Running mermaid diagrams, rerun =", rerun);
// clear all existing mermaid charts
let all_mermaids = document.querySelectorAll(".mermaid");
if (rerun) {
all_mermaids.forEach((el) => {
if(!el.hasAttribute("data-original-code")) {
// store original code
// console.log(`Storing original code for first run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
if(el.getAttribute("data-processed") === "true") {
// remove and restore original
el.removeAttribute("data-processed");
// console.log(`Restoring original code for re-run: `, el.getAttribute('data-original-code'));
el.innerHTML = el.getAttribute('data-original-code');
} else {
// store original code
// console.log(`Storing original code for re-run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
});
await mermaid.run();
}
all_mermaids = document.querySelectorAll(".mermaid");
const mermaids_processed = document.querySelectorAll(".mermaid[data-processed='true']");
if ("False" === "True") {
const mermaids_to_add_zoom = -1 === -1 ? all_mermaids.length : -1;
if(mermaids_to_add_zoom > 0) {
var svgs = d3.selectAll("");
if(all_mermaids.length !== mermaids_processed.length) {
setTimeout(() => runMermaid(false), 200);
return;
} else if(svgs.size() !== mermaids_to_add_zoom) {
setTimeout(() => runMermaid(false), 200);
return;
} else {
svgs.each(function() {
var svg = d3.select(this);
svg.html("<g class='wrapper'>" + svg.html() + "</g>");
var inner = svg.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svg.call(zoom);
});
}
}
} else if(all_mermaids.length !== mermaids_processed.length) {
// Wait for mermaid to process all diagrams
setTimeout(() => runMermaid(false), 200);
return;
}
// Stop here if not adding fullscreen capability
if ("True" !== "True") return;
if (modal !== null ) {
// Destroy existing modal
modal.remove();
modal = null;
modalContent = null;
}
modal = document.createElement('div');
modal.className = 'mermaid-fullscreen-modal' + (darkTheme ? ' dark-theme' : '');
modal.setAttribute('role', 'dialog');
modal.setAttribute('aria-modal', 'true');
modal.setAttribute('aria-label', 'Fullscreen diagram viewer');
modal.innerHTML = `
<button class="mermaid-fullscreen-close${darkTheme ? ' dark-theme' : ''}" aria-label="Close fullscreen">✕</button>
<div class="mermaid-container-fullscreen${darkTheme ? ' dark-theme' : ''}"></div>
`;
document.body.appendChild(modal);
modalContent = modal.querySelector('.mermaid-container-fullscreen');
const closeBtn = modal.querySelector('.mermaid-fullscreen-close');
const closeModal = () => {
modal.classList.remove('active');
modalContent.innerHTML = '';
document.body.style.overflow = ''
window.scrollTo({left: previousScrollOffset[0], top: previousScrollOffset[1], behavior: 'instant'});
};
closeBtn.addEventListener('click', closeModal);
modal.addEventListener('click', (e) => {
if (e.target === modal) closeModal();
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && modal.classList.contains('active')) {
closeModal();
}
});
document.querySelectorAll('.mermaid').forEach((mermaidDiv) => {
if (mermaidDiv.parentNode.classList.contains('mermaid-container') ||
mermaidDiv.closest('.mermaid-fullscreen-modal')) {
// Already processed, adjust button class if needed
const existingBtn = mermaidDiv.parentNode.querySelector('.mermaid-fullscreen-btn');
if (existingBtn) {
existingBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
}
return;
}
const container = document.createElement('div');
container.className = 'mermaid-container';
mermaidDiv.parentNode.insertBefore(container, mermaidDiv);
container.appendChild(mermaidDiv);
const fullscreenBtn = document.createElement('button');
fullscreenBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
fullscreenBtn.setAttribute('aria-label', 'View diagram in fullscreen');
fullscreenBtn.textContent = '⛶';
fullscreenBtn.style.opacity = '50%';
// Calculate dynamic position based on diagram's margin and padding
const diagramStyle = window.getComputedStyle(mermaidDiv);
const marginTop = parseFloat(diagramStyle.marginTop) || 0;
const marginRight = parseFloat(diagramStyle.marginRight) || 0;
const paddingTop = parseFloat(diagramStyle.paddingTop) || 0;
const paddingRight = parseFloat(diagramStyle.paddingRight) || 0;
fullscreenBtn.style.top = `${marginTop + paddingTop + 4}px`;
fullscreenBtn.style.right = `${marginRight + paddingRight + 4}px`;
fullscreenBtn.addEventListener('click', () => {
previousScrollOffset = [window.scroll, window.scrollY];
const clone = mermaidDiv.cloneNode(true);
modalContent.innerHTML = '';
modalContent.appendChild(clone);
const svg = clone.querySelector('svg');
if (svg) {
svg.removeAttribute('width');
svg.removeAttribute('height');
svg.style.width = '100%';
svg.style.height = 'auto';
svg.style.maxWidth = '100%';
svg.style.sdisplay = 'block';
if ("False" === "True") {
setTimeout(() => {
const g = svg.querySelector('g');
if (g) {
var svgD3 = d3.select(svg);
svgD3.html("<g class='wrapper'>" + svgD3.html() + "</g>");
var inner = svgD3.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svgD3.call(zoom);
}
}, 100);
}
}
modal.classList.add('active');
document.body.style.overflow = 'hidden';
});
container.appendChild(fullscreenBtn);
});
};
const load = async () => {
initStyles();
await runMermaid(true);
const reRunIfThemeChanges = async () => {
const newDarkTheme = isDarkTheme();
if (newDarkTheme !== darkTheme) {
darkTheme = newDarkTheme;
console.log("Theme change detected, re-running mermaid with", darkTheme ? "dark" : "default", "theme");
await mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
await runMermaid(true);
}
};
// Update theme classes when theme changes
const themeObserver = new MutationObserver(reRunIfThemeChanges);
themeObserver.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
themeObserver.observe(document.body, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
};
console.log("Initializing mermaid with", darkTheme ? "dark" : "default", "theme");
mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
window.addEventListener("load", load);
window.runMermaid = runMermaid;</script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Riferimento API" href="api_reference.html" />
<link rel="prev" title="Warehouse Documentation" href="index.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="architettura-complessiva">
<h1>Architettura Complessiva<a class="headerlink" href="#architettura-complessiva" title="Link to this heading"></a></h1>
<p>Questa pagina collega i moduli principali del progetto in una vista unica,
partendo dal launcher fino ai moduli GUI e al livello infrastrutturale async/DB.</p>
<section id="vista-architetturale">
<h2>Vista architetturale<a class="headerlink" href="#vista-architetturale" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart TD
Main[&quot;main.py&quot;] --&gt; Launcher[&quot;Launcher&quot;]
Main --&gt; Loop[&quot;async_loop_singleton.get_global_loop()&quot;]
Main --&gt; DB[&quot;AsyncMSSQLClient&quot;]
Launcher --&gt; Reset[&quot;reset_corsie.py&quot;]
Launcher --&gt; Layout[&quot;layout_window.py&quot;]
Launcher --&gt; Ghost[&quot;view_celle_multiple.py&quot;]
Launcher --&gt; Search[&quot;search_pallets.py&quot;]
Launcher --&gt; Picking[&quot;gestione_pickinglist.py&quot;]
Reset --&gt; Runner[&quot;gestione_aree_frame_async.AsyncRunner&quot;]
Layout --&gt; Runner
Ghost --&gt; Runner
Search --&gt; Runner
Picking --&gt; Runner
Runner --&gt; Loop
Runner --&gt; DB
Picking --&gt; SP[&quot;prenota_sprenota_sql.py&quot;]
SP --&gt; DB
DB --&gt; SQL[&quot;SQL Server / Mediseawall&quot;]
</pre></section>
<section id="flusso-applicativo-generale">
<h2>Flusso applicativo generale<a class="headerlink" href="#flusso-applicativo-generale" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart LR
User[&quot;Utente&quot;] --&gt; MainWin[&quot;Launcher&quot;]
MainWin --&gt; Module[&quot;Finestra modulo&quot;]
Module --&gt; AsyncReq[&quot;AsyncRunner.run(...)&quot;]
AsyncReq --&gt; DbClient[&quot;AsyncMSSQLClient&quot;]
DbClient --&gt; SqlServer[&quot;Database SQL Server&quot;]
SqlServer --&gt; Callback[&quot;Callback _ok/_err&quot;]
Callback --&gt; Module
</pre></section>
<section id="osservazioni">
<h2>Osservazioni<a class="headerlink" href="#osservazioni" title="Link to this heading"></a></h2>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">main.py</span></code> centralizza il loop asincrono e il client database condiviso.</p></li>
<li><p>I moduli GUI si concentrano sulla UI e delegano query e task lunghi a <code class="docutils literal notranslate"><span class="pre">AsyncRunner</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">gestione_pickinglist.py</span></code> è lunico modulo che passa anche da <code class="docutils literal notranslate"><span class="pre">prenota_sprenota_sql.py</span></code> per la logica di prenotazione.</p></li>
<li><p>La cartella <code class="docutils literal notranslate"><span class="pre">docs/flows/</span></code> contiene la vista dettagliata modulo per modulo.</p></li>
</ul>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">warehouse</a></h1>
<search id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Search"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul class="current">
<li class="toctree-l1 current"><a class="current reference internal" href="#">Architettura Complessiva</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#vista-architetturale">Vista architetturale</a></li>
<li class="toctree-l2"><a class="reference internal" href="#flusso-applicativo-generale">Flusso applicativo generale</a></li>
<li class="toctree-l2"><a class="reference internal" href="#osservazioni">Osservazioni</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="api_reference.html">Riferimento API</a></li>
<li class="toctree-l1"><a class="reference internal" href="flows/index.html">Flow Diagrams</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
<li>Previous: <a href="index.html" title="previous chapter">Warehouse Documentation</a></li>
<li>Next: <a href="api_reference.html" title="next chapter">Riferimento API</a></li>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 9.1.0</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 1.0.0</a>
|
<a href="_sources/architecture.md.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

154
docs/_build/html/flows/README.html vendored Normal file
View File

@@ -0,0 +1,154 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Flow Diagrams &#8212; warehouse 0.0.1 documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=5ecbeea2" />
<link rel="stylesheet" type="text/css" href="../_static/basic.css?v=b08954a9" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=27fed22d" />
<script src="../_static/documentation_options.js?v=d45e8c67"></script>
<script src="../_static/doctools.js?v=fd6eb6e6"></script>
<script src="../_static/sphinx_highlight.js?v=6ffebe34"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="main.py" href="main_flow.html" />
<link rel="prev" title="Flow Diagrams" href="index.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="flow-diagrams">
<h1>Flow Diagrams<a class="headerlink" href="#flow-diagrams" title="Link to this heading"></a></h1>
<p>Questa cartella contiene schemi di flusso e schemi di chiamata dei moduli
principali avviati da <code class="docutils literal notranslate"><span class="pre">main.py</span></code>.</p>
<p>I diagrammi sono scritti in Mermaid, quindi possono essere:</p>
<ul class="simple">
<li><p>letti direttamente nei file Markdown;</p></li>
<li><p>renderizzati da molti editor Git/Markdown;</p></li>
<li><p>inclusi in una futura documentazione Sphinx o MkDocs.</p></li>
</ul>
<section id="indice">
<h2>Indice<a class="headerlink" href="#indice" title="Link to this heading"></a></h2>
<ul class="simple">
<li><p><a class="reference internal" href="main_flow.html"><span class="std std-doc">main</span></a></p></li>
<li><p><a class="reference internal" href="layout_window_flow.html"><span class="std std-doc">layout_window</span></a></p></li>
<li><p><a class="reference internal" href="reset_corsie_flow.html"><span class="std std-doc">reset_corsie</span></a></p></li>
<li><p><a class="reference internal" href="view_celle_multiple_flow.html"><span class="std std-doc">view_celle_multiple</span></a></p></li>
<li><p><a class="reference internal" href="search_pallets_flow.html"><span class="std std-doc">search_pallets</span></a></p></li>
<li><p><a class="reference internal" href="gestione_pickinglist_flow.html"><span class="std std-doc">gestione_pickinglist</span></a></p></li>
<li><p><a class="reference internal" href="async_db_flow.html"><span class="std std-doc">infrastruttura async/db</span></a></p></li>
</ul>
</section>
<section id="convenzioni">
<h2>Convenzioni<a class="headerlink" href="#convenzioni" title="Link to this heading"></a></h2>
<ul class="simple">
<li><p>I diagrammi descrivono il flusso applicativo ad alto livello.</p></li>
<li><p>Non rappresentano ogni singola riga di codice.</p></li>
<li><p>I nodi <code class="docutils literal notranslate"><span class="pre">AsyncRunner</span></code> e <code class="docutils literal notranslate"><span class="pre">query_json</span></code> evidenziano i passaggi asincroni più
importanti tra interfaccia e database.</p></li>
</ul>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">warehouse</a></h1>
<search id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Search"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../architecture.html">Architettura Complessiva</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api_reference.html">Riferimento API</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Flow Diagrams</a><ul class="current">
<li class="toctree-l2 current"><a class="current reference internal" href="#">Flow Diagrams</a></li>
<li class="toctree-l2"><a class="reference internal" href="main_flow.html"><code class="docutils literal notranslate"><span class="pre">main.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="layout_window_flow.html"><code class="docutils literal notranslate"><span class="pre">layout_window.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="reset_corsie_flow.html"><code class="docutils literal notranslate"><span class="pre">reset_corsie.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="view_celle_multiple_flow.html"><code class="docutils literal notranslate"><span class="pre">view_celle_multiple.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="search_pallets_flow.html"><code class="docutils literal notranslate"><span class="pre">search_pallets.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_pickinglist_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_pickinglist.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_db_flow.html">Infrastruttura Async / DB</a></li>
<li class="toctree-l2"><a class="reference internal" href="async_msssql_query_flow.html"><code class="docutils literal notranslate"><span class="pre">async_msssql_query.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_aree_frame_async_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_aree_frame_async.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_loop_singleton_flow.html"><code class="docutils literal notranslate"><span class="pre">async_loop_singleton.py</span></code></a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
<li><a href="index.html">Flow Diagrams</a><ul>
<li>Previous: <a href="index.html" title="previous chapter">Flow Diagrams</a></li>
<li>Next: <a href="main_flow.html" title="next chapter"><code class="docutils literal notranslate"><span class="pre">main.py</span></code></a></li>
</ul></li>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 9.1.0</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 1.0.0</a>
|
<a href="../_sources/flows/README.md.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@@ -0,0 +1,599 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Infrastruttura Async / DB &#8212; warehouse 0.0.1 documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=5ecbeea2" />
<link rel="stylesheet" type="text/css" href="../_static/basic.css?v=b08954a9" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=27fed22d" />
<script src="../_static/documentation_options.js?v=d45e8c67"></script>
<script src="../_static/doctools.js?v=fd6eb6e6"></script>
<script src="../_static/sphinx_highlight.js?v=6ffebe34"></script>
<script src="https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js"></script>
<script type="module">import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11.12.1/dist/mermaid.esm.min.mjs";
const initStyles = () => {
const defaultStyle = document.createElement('style');
defaultStyle.textContent = `pre.mermaid {
/* Same as .mermaid-container > pre */
display: block;
width: 100%;
}
pre.mermaid > svg {
/* Same as .mermaid-container > pre > svg */
height: 500px;
width: 100%;
max-width: 100% !important;
}`;
document.head.appendChild(defaultStyle);
const fullscreenStyle = document.createElement('style');
fullscreenStyle.textContent = `.mermaid-container {
display: flex;
flex-direction: row;
width: 100%;
}
.mermaid-container > pre {
display: block;
width: 100%;
}
.mermaid-container > pre > svg {
height: 500px;
width: 100%;
max-width: 100% !important;
}
.mermaid-fullscreen-btn {
width: 28px;
height: 28px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
font-size: 14px;
line-height: 1;
padding: 0;
color: #333;
}
.mermaid-fullscreen-btn:hover {
opacity: 100% !important;
background: rgba(255, 255, 255, 1);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
transform: scale(1.1);
}
.mermaid-fullscreen-btn.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.3);
color: #e0e0e0;
}
.mermaid-fullscreen-btn.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 3px 10px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal {
display: none;
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 95vw;
height: 100vh;
background: rgba(255, 255, 255, 0.98);
z-index: 9999;
padding: 20px;
overflow: auto;
}
.mermaid-fullscreen-modal.dark-theme {
background: rgba(0, 0, 0, 0.98);
}
.mermaid-fullscreen-modal.active {
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen {
position: relative;
width: 95vw;
height: 90vh;
max-width: 95vw;
max-height: 90vh;
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
overflow: auto;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen.dark-theme {
background: #1a1a1a;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);
}
.mermaid-container-fullscreen pre.mermaid {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen .mermaid svg {
height: 100% !important;
width: 100% !important;
cursor: grab;
}
.mermaid-fullscreen-close {
position: fixed !important;
top: 20px !important;
right: 20px !important;
width: 40px;
height: 40px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 50%;
cursor: pointer;
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
transition: all 0.2s;
font-size: 24px;
line-height: 1;
color: #333;
}
.mermaid-fullscreen-close:hover {
background: white;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
transform: scale(1.1);
}
.mermaid-fullscreen-close.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.2);
color: #e0e0e0;
}
.mermaid-fullscreen-close.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 6px 16px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal .mermaid-fullscreen-btn {
display: none !important;
}`;
document.head.appendChild(fullscreenStyle);
}
// Detect if page has dark background
const isDarkTheme = () => {
// We use a set of heuristics:
// 1. Check for common dark mode classes or attributes
// 2. Check computed background color brightness
if (document.documentElement.classList.contains('dark') ||
document.documentElement.getAttribute('data-theme') === 'dark' ||
document.body.classList.contains('dark') ||
document.body.getAttribute('data-theme') === 'dark') {
// console.log("Dark theme detected via class/attribute");
return true;
}
if (document.documentElement.classList.contains('light') ||
document.documentElement.getAttribute('data-theme') === 'light' ||
document.body.classList.contains('light') ||
document.body.getAttribute('data-theme') === 'light') {
// console.log("Light theme detected via class/attribute");
return false;
}
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
// console.log("Dark theme detected via prefers-color-scheme");
return true;
}
const bgColor = window.getComputedStyle(document.body).backgroundColor;
const match = bgColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)/);
if (match) {
const r = parseInt(match[1]);
const g = parseInt(match[2]);
const b = parseInt(match[3]);
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
// console.log("Background color brightness:", brightness);
return brightness < 128;
}
// console.log("No dark or light theme detected, defaulting to light theme");
return false;
};
let darkTheme = isDarkTheme();
let modal = null;
let modalContent = null;
let previousScrollOffset = [window.scrollX, window.scrollY];
const runMermaid = async (rerun) => {
console.log("Running mermaid diagrams, rerun =", rerun);
// clear all existing mermaid charts
let all_mermaids = document.querySelectorAll(".mermaid");
if (rerun) {
all_mermaids.forEach((el) => {
if(!el.hasAttribute("data-original-code")) {
// store original code
// console.log(`Storing original code for first run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
if(el.getAttribute("data-processed") === "true") {
// remove and restore original
el.removeAttribute("data-processed");
// console.log(`Restoring original code for re-run: `, el.getAttribute('data-original-code'));
el.innerHTML = el.getAttribute('data-original-code');
} else {
// store original code
// console.log(`Storing original code for re-run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
});
await mermaid.run();
}
all_mermaids = document.querySelectorAll(".mermaid");
const mermaids_processed = document.querySelectorAll(".mermaid[data-processed='true']");
if ("False" === "True") {
const mermaids_to_add_zoom = -1 === -1 ? all_mermaids.length : -1;
if(mermaids_to_add_zoom > 0) {
var svgs = d3.selectAll("");
if(all_mermaids.length !== mermaids_processed.length) {
setTimeout(() => runMermaid(false), 200);
return;
} else if(svgs.size() !== mermaids_to_add_zoom) {
setTimeout(() => runMermaid(false), 200);
return;
} else {
svgs.each(function() {
var svg = d3.select(this);
svg.html("<g class='wrapper'>" + svg.html() + "</g>");
var inner = svg.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svg.call(zoom);
});
}
}
} else if(all_mermaids.length !== mermaids_processed.length) {
// Wait for mermaid to process all diagrams
setTimeout(() => runMermaid(false), 200);
return;
}
// Stop here if not adding fullscreen capability
if ("True" !== "True") return;
if (modal !== null ) {
// Destroy existing modal
modal.remove();
modal = null;
modalContent = null;
}
modal = document.createElement('div');
modal.className = 'mermaid-fullscreen-modal' + (darkTheme ? ' dark-theme' : '');
modal.setAttribute('role', 'dialog');
modal.setAttribute('aria-modal', 'true');
modal.setAttribute('aria-label', 'Fullscreen diagram viewer');
modal.innerHTML = `
<button class="mermaid-fullscreen-close${darkTheme ? ' dark-theme' : ''}" aria-label="Close fullscreen">✕</button>
<div class="mermaid-container-fullscreen${darkTheme ? ' dark-theme' : ''}"></div>
`;
document.body.appendChild(modal);
modalContent = modal.querySelector('.mermaid-container-fullscreen');
const closeBtn = modal.querySelector('.mermaid-fullscreen-close');
const closeModal = () => {
modal.classList.remove('active');
modalContent.innerHTML = '';
document.body.style.overflow = ''
window.scrollTo({left: previousScrollOffset[0], top: previousScrollOffset[1], behavior: 'instant'});
};
closeBtn.addEventListener('click', closeModal);
modal.addEventListener('click', (e) => {
if (e.target === modal) closeModal();
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && modal.classList.contains('active')) {
closeModal();
}
});
document.querySelectorAll('.mermaid').forEach((mermaidDiv) => {
if (mermaidDiv.parentNode.classList.contains('mermaid-container') ||
mermaidDiv.closest('.mermaid-fullscreen-modal')) {
// Already processed, adjust button class if needed
const existingBtn = mermaidDiv.parentNode.querySelector('.mermaid-fullscreen-btn');
if (existingBtn) {
existingBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
}
return;
}
const container = document.createElement('div');
container.className = 'mermaid-container';
mermaidDiv.parentNode.insertBefore(container, mermaidDiv);
container.appendChild(mermaidDiv);
const fullscreenBtn = document.createElement('button');
fullscreenBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
fullscreenBtn.setAttribute('aria-label', 'View diagram in fullscreen');
fullscreenBtn.textContent = '⛶';
fullscreenBtn.style.opacity = '50%';
// Calculate dynamic position based on diagram's margin and padding
const diagramStyle = window.getComputedStyle(mermaidDiv);
const marginTop = parseFloat(diagramStyle.marginTop) || 0;
const marginRight = parseFloat(diagramStyle.marginRight) || 0;
const paddingTop = parseFloat(diagramStyle.paddingTop) || 0;
const paddingRight = parseFloat(diagramStyle.paddingRight) || 0;
fullscreenBtn.style.top = `${marginTop + paddingTop + 4}px`;
fullscreenBtn.style.right = `${marginRight + paddingRight + 4}px`;
fullscreenBtn.addEventListener('click', () => {
previousScrollOffset = [window.scroll, window.scrollY];
const clone = mermaidDiv.cloneNode(true);
modalContent.innerHTML = '';
modalContent.appendChild(clone);
const svg = clone.querySelector('svg');
if (svg) {
svg.removeAttribute('width');
svg.removeAttribute('height');
svg.style.width = '100%';
svg.style.height = 'auto';
svg.style.maxWidth = '100%';
svg.style.sdisplay = 'block';
if ("False" === "True") {
setTimeout(() => {
const g = svg.querySelector('g');
if (g) {
var svgD3 = d3.select(svg);
svgD3.html("<g class='wrapper'>" + svgD3.html() + "</g>");
var inner = svgD3.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svgD3.call(zoom);
}
}, 100);
}
}
modal.classList.add('active');
document.body.style.overflow = 'hidden';
});
container.appendChild(fullscreenBtn);
});
};
const load = async () => {
initStyles();
await runMermaid(true);
const reRunIfThemeChanges = async () => {
const newDarkTheme = isDarkTheme();
if (newDarkTheme !== darkTheme) {
darkTheme = newDarkTheme;
console.log("Theme change detected, re-running mermaid with", darkTheme ? "dark" : "default", "theme");
await mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
await runMermaid(true);
}
};
// Update theme classes when theme changes
const themeObserver = new MutationObserver(reRunIfThemeChanges);
themeObserver.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
themeObserver.observe(document.body, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
};
console.log("Initializing mermaid with", darkTheme ? "dark" : "default", "theme");
mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
window.addEventListener("load", load);
window.runMermaid = runMermaid;</script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="async_msssql_query.py" href="async_msssql_query_flow.html" />
<link rel="prev" title="gestione_pickinglist.py" href="gestione_pickinglist_flow.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="infrastruttura-async-db">
<h1>Infrastruttura Async / DB<a class="headerlink" href="#infrastruttura-async-db" title="Link to this heading"></a></h1>
<section id="scopo">
<h2>Scopo<a class="headerlink" href="#scopo" title="Link to this heading"></a></h2>
<p>Questo diagramma descrive il flusso comune usato da tutti i moduli GUI quando
eseguono una query sul database.</p>
</section>
<section id="flusso-trasversale">
<h2>Flusso trasversale<a class="headerlink" href="#flusso-trasversale" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart TD
A[&quot;Evento UI (click / selezione / ricerca)&quot;] --&gt; B[&quot;Metodo finestra&quot;]
B --&gt; C[&quot;AsyncRunner.run(awaitable)&quot;]
C --&gt; D[&quot;Coroutines sul loop globale&quot;]
D --&gt; E[&quot;AsyncMSSQLClient.query_json() / exec()&quot;]
E --&gt; F[&quot;SQL Server&quot;]
F --&gt; G[&quot;Risultato query&quot;]
G --&gt; H[&quot;Future completata&quot;]
H --&gt; I[&quot;Callback _ok / _err su thread Tk&quot;]
I --&gt; J[&quot;Aggiornamento widget&quot;]
</pre></section>
<section id="relazioni-principali">
<h2>Relazioni principali<a class="headerlink" href="#relazioni-principali" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart LR
Main[&quot;main.py&quot;] --&gt; Loop[&quot;get_global_loop()&quot;]
Main --&gt; DB[&quot;AsyncMSSQLClient&quot;]
Windows[&quot;Moduli GUI&quot;] --&gt; Runner[&quot;AsyncRunner&quot;]
Runner --&gt; Loop
Runner --&gt; DB
DB --&gt; SQL[&quot;SQL Server Mediseawall&quot;]
</pre></section>
<section id="note">
<h2>Note<a class="headerlink" href="#note" title="Link to this heading"></a></h2>
<ul class="simple">
<li><p>Il loop asincrono è condiviso tra tutte le finestre.</p></li>
<li><p>Il client DB è condiviso e creato una sola volta nel launcher.</p></li>
<li><p>I callback che aggiornano la UI rientrano sempre sul thread Tk.</p></li>
</ul>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">warehouse</a></h1>
<search id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Search"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../architecture.html">Architettura Complessiva</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api_reference.html">Riferimento API</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Flow Diagrams</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="README.html">Flow Diagrams</a></li>
<li class="toctree-l2"><a class="reference internal" href="main_flow.html"><code class="docutils literal notranslate"><span class="pre">main.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="layout_window_flow.html"><code class="docutils literal notranslate"><span class="pre">layout_window.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="reset_corsie_flow.html"><code class="docutils literal notranslate"><span class="pre">reset_corsie.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="view_celle_multiple_flow.html"><code class="docutils literal notranslate"><span class="pre">view_celle_multiple.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="search_pallets_flow.html"><code class="docutils literal notranslate"><span class="pre">search_pallets.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_pickinglist_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_pickinglist.py</span></code></a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Infrastruttura Async / DB</a></li>
<li class="toctree-l2"><a class="reference internal" href="async_msssql_query_flow.html"><code class="docutils literal notranslate"><span class="pre">async_msssql_query.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_aree_frame_async_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_aree_frame_async.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_loop_singleton_flow.html"><code class="docutils literal notranslate"><span class="pre">async_loop_singleton.py</span></code></a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
<li><a href="index.html">Flow Diagrams</a><ul>
<li>Previous: <a href="gestione_pickinglist_flow.html" title="previous chapter"><code class="docutils literal notranslate"><span class="pre">gestione_pickinglist.py</span></code></a></li>
<li>Next: <a href="async_msssql_query_flow.html" title="next chapter"><code class="docutils literal notranslate"><span class="pre">async_msssql_query.py</span></code></a></li>
</ul></li>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 9.1.0</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 1.0.0</a>
|
<a href="../_sources/flows/async_db_flow.md.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@@ -0,0 +1,597 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>async_loop_singleton.py &#8212; warehouse 0.0.1 documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=5ecbeea2" />
<link rel="stylesheet" type="text/css" href="../_static/basic.css?v=b08954a9" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=27fed22d" />
<script src="../_static/documentation_options.js?v=d45e8c67"></script>
<script src="../_static/doctools.js?v=fd6eb6e6"></script>
<script src="../_static/sphinx_highlight.js?v=6ffebe34"></script>
<script src="https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js"></script>
<script type="module">import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11.12.1/dist/mermaid.esm.min.mjs";
const initStyles = () => {
const defaultStyle = document.createElement('style');
defaultStyle.textContent = `pre.mermaid {
/* Same as .mermaid-container > pre */
display: block;
width: 100%;
}
pre.mermaid > svg {
/* Same as .mermaid-container > pre > svg */
height: 500px;
width: 100%;
max-width: 100% !important;
}`;
document.head.appendChild(defaultStyle);
const fullscreenStyle = document.createElement('style');
fullscreenStyle.textContent = `.mermaid-container {
display: flex;
flex-direction: row;
width: 100%;
}
.mermaid-container > pre {
display: block;
width: 100%;
}
.mermaid-container > pre > svg {
height: 500px;
width: 100%;
max-width: 100% !important;
}
.mermaid-fullscreen-btn {
width: 28px;
height: 28px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
font-size: 14px;
line-height: 1;
padding: 0;
color: #333;
}
.mermaid-fullscreen-btn:hover {
opacity: 100% !important;
background: rgba(255, 255, 255, 1);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
transform: scale(1.1);
}
.mermaid-fullscreen-btn.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.3);
color: #e0e0e0;
}
.mermaid-fullscreen-btn.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 3px 10px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal {
display: none;
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 95vw;
height: 100vh;
background: rgba(255, 255, 255, 0.98);
z-index: 9999;
padding: 20px;
overflow: auto;
}
.mermaid-fullscreen-modal.dark-theme {
background: rgba(0, 0, 0, 0.98);
}
.mermaid-fullscreen-modal.active {
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen {
position: relative;
width: 95vw;
height: 90vh;
max-width: 95vw;
max-height: 90vh;
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
overflow: auto;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen.dark-theme {
background: #1a1a1a;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);
}
.mermaid-container-fullscreen pre.mermaid {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen .mermaid svg {
height: 100% !important;
width: 100% !important;
cursor: grab;
}
.mermaid-fullscreen-close {
position: fixed !important;
top: 20px !important;
right: 20px !important;
width: 40px;
height: 40px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 50%;
cursor: pointer;
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
transition: all 0.2s;
font-size: 24px;
line-height: 1;
color: #333;
}
.mermaid-fullscreen-close:hover {
background: white;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
transform: scale(1.1);
}
.mermaid-fullscreen-close.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.2);
color: #e0e0e0;
}
.mermaid-fullscreen-close.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 6px 16px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal .mermaid-fullscreen-btn {
display: none !important;
}`;
document.head.appendChild(fullscreenStyle);
}
// Detect if page has dark background
const isDarkTheme = () => {
// We use a set of heuristics:
// 1. Check for common dark mode classes or attributes
// 2. Check computed background color brightness
if (document.documentElement.classList.contains('dark') ||
document.documentElement.getAttribute('data-theme') === 'dark' ||
document.body.classList.contains('dark') ||
document.body.getAttribute('data-theme') === 'dark') {
// console.log("Dark theme detected via class/attribute");
return true;
}
if (document.documentElement.classList.contains('light') ||
document.documentElement.getAttribute('data-theme') === 'light' ||
document.body.classList.contains('light') ||
document.body.getAttribute('data-theme') === 'light') {
// console.log("Light theme detected via class/attribute");
return false;
}
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
// console.log("Dark theme detected via prefers-color-scheme");
return true;
}
const bgColor = window.getComputedStyle(document.body).backgroundColor;
const match = bgColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)/);
if (match) {
const r = parseInt(match[1]);
const g = parseInt(match[2]);
const b = parseInt(match[3]);
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
// console.log("Background color brightness:", brightness);
return brightness < 128;
}
// console.log("No dark or light theme detected, defaulting to light theme");
return false;
};
let darkTheme = isDarkTheme();
let modal = null;
let modalContent = null;
let previousScrollOffset = [window.scrollX, window.scrollY];
const runMermaid = async (rerun) => {
console.log("Running mermaid diagrams, rerun =", rerun);
// clear all existing mermaid charts
let all_mermaids = document.querySelectorAll(".mermaid");
if (rerun) {
all_mermaids.forEach((el) => {
if(!el.hasAttribute("data-original-code")) {
// store original code
// console.log(`Storing original code for first run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
if(el.getAttribute("data-processed") === "true") {
// remove and restore original
el.removeAttribute("data-processed");
// console.log(`Restoring original code for re-run: `, el.getAttribute('data-original-code'));
el.innerHTML = el.getAttribute('data-original-code');
} else {
// store original code
// console.log(`Storing original code for re-run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
});
await mermaid.run();
}
all_mermaids = document.querySelectorAll(".mermaid");
const mermaids_processed = document.querySelectorAll(".mermaid[data-processed='true']");
if ("False" === "True") {
const mermaids_to_add_zoom = -1 === -1 ? all_mermaids.length : -1;
if(mermaids_to_add_zoom > 0) {
var svgs = d3.selectAll("");
if(all_mermaids.length !== mermaids_processed.length) {
setTimeout(() => runMermaid(false), 200);
return;
} else if(svgs.size() !== mermaids_to_add_zoom) {
setTimeout(() => runMermaid(false), 200);
return;
} else {
svgs.each(function() {
var svg = d3.select(this);
svg.html("<g class='wrapper'>" + svg.html() + "</g>");
var inner = svg.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svg.call(zoom);
});
}
}
} else if(all_mermaids.length !== mermaids_processed.length) {
// Wait for mermaid to process all diagrams
setTimeout(() => runMermaid(false), 200);
return;
}
// Stop here if not adding fullscreen capability
if ("True" !== "True") return;
if (modal !== null ) {
// Destroy existing modal
modal.remove();
modal = null;
modalContent = null;
}
modal = document.createElement('div');
modal.className = 'mermaid-fullscreen-modal' + (darkTheme ? ' dark-theme' : '');
modal.setAttribute('role', 'dialog');
modal.setAttribute('aria-modal', 'true');
modal.setAttribute('aria-label', 'Fullscreen diagram viewer');
modal.innerHTML = `
<button class="mermaid-fullscreen-close${darkTheme ? ' dark-theme' : ''}" aria-label="Close fullscreen">✕</button>
<div class="mermaid-container-fullscreen${darkTheme ? ' dark-theme' : ''}"></div>
`;
document.body.appendChild(modal);
modalContent = modal.querySelector('.mermaid-container-fullscreen');
const closeBtn = modal.querySelector('.mermaid-fullscreen-close');
const closeModal = () => {
modal.classList.remove('active');
modalContent.innerHTML = '';
document.body.style.overflow = ''
window.scrollTo({left: previousScrollOffset[0], top: previousScrollOffset[1], behavior: 'instant'});
};
closeBtn.addEventListener('click', closeModal);
modal.addEventListener('click', (e) => {
if (e.target === modal) closeModal();
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && modal.classList.contains('active')) {
closeModal();
}
});
document.querySelectorAll('.mermaid').forEach((mermaidDiv) => {
if (mermaidDiv.parentNode.classList.contains('mermaid-container') ||
mermaidDiv.closest('.mermaid-fullscreen-modal')) {
// Already processed, adjust button class if needed
const existingBtn = mermaidDiv.parentNode.querySelector('.mermaid-fullscreen-btn');
if (existingBtn) {
existingBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
}
return;
}
const container = document.createElement('div');
container.className = 'mermaid-container';
mermaidDiv.parentNode.insertBefore(container, mermaidDiv);
container.appendChild(mermaidDiv);
const fullscreenBtn = document.createElement('button');
fullscreenBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
fullscreenBtn.setAttribute('aria-label', 'View diagram in fullscreen');
fullscreenBtn.textContent = '⛶';
fullscreenBtn.style.opacity = '50%';
// Calculate dynamic position based on diagram's margin and padding
const diagramStyle = window.getComputedStyle(mermaidDiv);
const marginTop = parseFloat(diagramStyle.marginTop) || 0;
const marginRight = parseFloat(diagramStyle.marginRight) || 0;
const paddingTop = parseFloat(diagramStyle.paddingTop) || 0;
const paddingRight = parseFloat(diagramStyle.paddingRight) || 0;
fullscreenBtn.style.top = `${marginTop + paddingTop + 4}px`;
fullscreenBtn.style.right = `${marginRight + paddingRight + 4}px`;
fullscreenBtn.addEventListener('click', () => {
previousScrollOffset = [window.scroll, window.scrollY];
const clone = mermaidDiv.cloneNode(true);
modalContent.innerHTML = '';
modalContent.appendChild(clone);
const svg = clone.querySelector('svg');
if (svg) {
svg.removeAttribute('width');
svg.removeAttribute('height');
svg.style.width = '100%';
svg.style.height = 'auto';
svg.style.maxWidth = '100%';
svg.style.sdisplay = 'block';
if ("False" === "True") {
setTimeout(() => {
const g = svg.querySelector('g');
if (g) {
var svgD3 = d3.select(svg);
svgD3.html("<g class='wrapper'>" + svgD3.html() + "</g>");
var inner = svgD3.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svgD3.call(zoom);
}
}, 100);
}
}
modal.classList.add('active');
document.body.style.overflow = 'hidden';
});
container.appendChild(fullscreenBtn);
});
};
const load = async () => {
initStyles();
await runMermaid(true);
const reRunIfThemeChanges = async () => {
const newDarkTheme = isDarkTheme();
if (newDarkTheme !== darkTheme) {
darkTheme = newDarkTheme;
console.log("Theme change detected, re-running mermaid with", darkTheme ? "dark" : "default", "theme");
await mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
await runMermaid(true);
}
};
// Update theme classes when theme changes
const themeObserver = new MutationObserver(reRunIfThemeChanges);
themeObserver.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
themeObserver.observe(document.body, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
};
console.log("Initializing mermaid with", darkTheme ? "dark" : "default", "theme");
mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
window.addEventListener("load", load);
window.runMermaid = runMermaid;</script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="prev" title="gestione_aree_frame_async.py" href="gestione_aree_frame_async_flow.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="async-loop-singleton-py">
<h1><code class="docutils literal notranslate"><span class="pre">async_loop_singleton.py</span></code><a class="headerlink" href="#async-loop-singleton-py" title="Link to this heading"></a></h1>
<section id="scopo">
<h2>Scopo<a class="headerlink" href="#scopo" title="Link to this heading"></a></h2>
<p>Questo modulo mantiene un loop asyncio globale e condiviso, eseguito su un
thread dedicato.</p>
</section>
<section id="flusso">
<h2>Flusso<a class="headerlink" href="#flusso" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart TD
A[&quot;Chiamata a get_global_loop()&quot;] --&gt; B{&quot;Loop gia presente?&quot;}
B -- Si --&gt; C[&quot;Ritorna loop esistente&quot;]
B -- No --&gt; D[&quot;Crea Event ready&quot;]
D --&gt; E[&quot;Avvia thread daemon&quot;]
E --&gt; F[&quot;_run()&quot;]
F --&gt; G[&quot;new_event_loop()&quot;]
G --&gt; H[&quot;set_event_loop(loop)&quot;]
H --&gt; I[&quot;ready.set()&quot;]
I --&gt; J[&quot;loop.run_forever()&quot;]
J --&gt; K[&quot;Ritorna loop al chiamante&quot;]
</pre></section>
<section id="chiusura">
<h2>Chiusura<a class="headerlink" href="#chiusura" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart TD
A[&quot;stop_global_loop()&quot;] --&gt; B{&quot;Loop attivo?&quot;}
B -- No --&gt; C[&quot;Nessuna azione&quot;]
B -- Si --&gt; D[&quot;call_soon_threadsafe(loop.stop)&quot;]
D --&gt; E[&quot;join del thread&quot;]
E --&gt; F[&quot;Azzera riferimenti globali&quot;]
</pre></section>
<section id="note">
<h2>Note<a class="headerlink" href="#note" title="Link to this heading"></a></h2>
<ul class="simple">
<li><p>E un helper minimale usato da <code class="docutils literal notranslate"><span class="pre">main.py</span></code>.</p></li>
<li><p>Il modulo esiste separato da <code class="docutils literal notranslate"><span class="pre">gestione_aree_frame_async.py</span></code>, ma concettualmente
svolge lo stesso ruolo di gestione del loop condiviso.</p></li>
</ul>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">warehouse</a></h1>
<search id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Search"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../architecture.html">Architettura Complessiva</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api_reference.html">Riferimento API</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Flow Diagrams</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="README.html">Flow Diagrams</a></li>
<li class="toctree-l2"><a class="reference internal" href="main_flow.html"><code class="docutils literal notranslate"><span class="pre">main.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="layout_window_flow.html"><code class="docutils literal notranslate"><span class="pre">layout_window.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="reset_corsie_flow.html"><code class="docutils literal notranslate"><span class="pre">reset_corsie.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="view_celle_multiple_flow.html"><code class="docutils literal notranslate"><span class="pre">view_celle_multiple.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="search_pallets_flow.html"><code class="docutils literal notranslate"><span class="pre">search_pallets.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_pickinglist_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_pickinglist.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_db_flow.html">Infrastruttura Async / DB</a></li>
<li class="toctree-l2"><a class="reference internal" href="async_msssql_query_flow.html"><code class="docutils literal notranslate"><span class="pre">async_msssql_query.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_aree_frame_async_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_aree_frame_async.py</span></code></a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#"><code class="docutils literal notranslate"><span class="pre">async_loop_singleton.py</span></code></a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
<li><a href="index.html">Flow Diagrams</a><ul>
<li>Previous: <a href="gestione_aree_frame_async_flow.html" title="previous chapter"><code class="docutils literal notranslate"><span class="pre">gestione_aree_frame_async.py</span></code></a></li>
</ul></li>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 9.1.0</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 1.0.0</a>
|
<a href="../_sources/flows/async_loop_singleton_flow.md.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@@ -0,0 +1,601 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>async_msssql_query.py &#8212; warehouse 0.0.1 documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=5ecbeea2" />
<link rel="stylesheet" type="text/css" href="../_static/basic.css?v=b08954a9" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=27fed22d" />
<script src="../_static/documentation_options.js?v=d45e8c67"></script>
<script src="../_static/doctools.js?v=fd6eb6e6"></script>
<script src="../_static/sphinx_highlight.js?v=6ffebe34"></script>
<script src="https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js"></script>
<script type="module">import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11.12.1/dist/mermaid.esm.min.mjs";
const initStyles = () => {
const defaultStyle = document.createElement('style');
defaultStyle.textContent = `pre.mermaid {
/* Same as .mermaid-container > pre */
display: block;
width: 100%;
}
pre.mermaid > svg {
/* Same as .mermaid-container > pre > svg */
height: 500px;
width: 100%;
max-width: 100% !important;
}`;
document.head.appendChild(defaultStyle);
const fullscreenStyle = document.createElement('style');
fullscreenStyle.textContent = `.mermaid-container {
display: flex;
flex-direction: row;
width: 100%;
}
.mermaid-container > pre {
display: block;
width: 100%;
}
.mermaid-container > pre > svg {
height: 500px;
width: 100%;
max-width: 100% !important;
}
.mermaid-fullscreen-btn {
width: 28px;
height: 28px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
font-size: 14px;
line-height: 1;
padding: 0;
color: #333;
}
.mermaid-fullscreen-btn:hover {
opacity: 100% !important;
background: rgba(255, 255, 255, 1);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
transform: scale(1.1);
}
.mermaid-fullscreen-btn.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.3);
color: #e0e0e0;
}
.mermaid-fullscreen-btn.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 3px 10px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal {
display: none;
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 95vw;
height: 100vh;
background: rgba(255, 255, 255, 0.98);
z-index: 9999;
padding: 20px;
overflow: auto;
}
.mermaid-fullscreen-modal.dark-theme {
background: rgba(0, 0, 0, 0.98);
}
.mermaid-fullscreen-modal.active {
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen {
position: relative;
width: 95vw;
height: 90vh;
max-width: 95vw;
max-height: 90vh;
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
overflow: auto;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen.dark-theme {
background: #1a1a1a;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);
}
.mermaid-container-fullscreen pre.mermaid {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen .mermaid svg {
height: 100% !important;
width: 100% !important;
cursor: grab;
}
.mermaid-fullscreen-close {
position: fixed !important;
top: 20px !important;
right: 20px !important;
width: 40px;
height: 40px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 50%;
cursor: pointer;
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
transition: all 0.2s;
font-size: 24px;
line-height: 1;
color: #333;
}
.mermaid-fullscreen-close:hover {
background: white;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
transform: scale(1.1);
}
.mermaid-fullscreen-close.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.2);
color: #e0e0e0;
}
.mermaid-fullscreen-close.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 6px 16px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal .mermaid-fullscreen-btn {
display: none !important;
}`;
document.head.appendChild(fullscreenStyle);
}
// Detect if page has dark background
const isDarkTheme = () => {
// We use a set of heuristics:
// 1. Check for common dark mode classes or attributes
// 2. Check computed background color brightness
if (document.documentElement.classList.contains('dark') ||
document.documentElement.getAttribute('data-theme') === 'dark' ||
document.body.classList.contains('dark') ||
document.body.getAttribute('data-theme') === 'dark') {
// console.log("Dark theme detected via class/attribute");
return true;
}
if (document.documentElement.classList.contains('light') ||
document.documentElement.getAttribute('data-theme') === 'light' ||
document.body.classList.contains('light') ||
document.body.getAttribute('data-theme') === 'light') {
// console.log("Light theme detected via class/attribute");
return false;
}
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
// console.log("Dark theme detected via prefers-color-scheme");
return true;
}
const bgColor = window.getComputedStyle(document.body).backgroundColor;
const match = bgColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)/);
if (match) {
const r = parseInt(match[1]);
const g = parseInt(match[2]);
const b = parseInt(match[3]);
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
// console.log("Background color brightness:", brightness);
return brightness < 128;
}
// console.log("No dark or light theme detected, defaulting to light theme");
return false;
};
let darkTheme = isDarkTheme();
let modal = null;
let modalContent = null;
let previousScrollOffset = [window.scrollX, window.scrollY];
const runMermaid = async (rerun) => {
console.log("Running mermaid diagrams, rerun =", rerun);
// clear all existing mermaid charts
let all_mermaids = document.querySelectorAll(".mermaid");
if (rerun) {
all_mermaids.forEach((el) => {
if(!el.hasAttribute("data-original-code")) {
// store original code
// console.log(`Storing original code for first run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
if(el.getAttribute("data-processed") === "true") {
// remove and restore original
el.removeAttribute("data-processed");
// console.log(`Restoring original code for re-run: `, el.getAttribute('data-original-code'));
el.innerHTML = el.getAttribute('data-original-code');
} else {
// store original code
// console.log(`Storing original code for re-run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
});
await mermaid.run();
}
all_mermaids = document.querySelectorAll(".mermaid");
const mermaids_processed = document.querySelectorAll(".mermaid[data-processed='true']");
if ("False" === "True") {
const mermaids_to_add_zoom = -1 === -1 ? all_mermaids.length : -1;
if(mermaids_to_add_zoom > 0) {
var svgs = d3.selectAll("");
if(all_mermaids.length !== mermaids_processed.length) {
setTimeout(() => runMermaid(false), 200);
return;
} else if(svgs.size() !== mermaids_to_add_zoom) {
setTimeout(() => runMermaid(false), 200);
return;
} else {
svgs.each(function() {
var svg = d3.select(this);
svg.html("<g class='wrapper'>" + svg.html() + "</g>");
var inner = svg.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svg.call(zoom);
});
}
}
} else if(all_mermaids.length !== mermaids_processed.length) {
// Wait for mermaid to process all diagrams
setTimeout(() => runMermaid(false), 200);
return;
}
// Stop here if not adding fullscreen capability
if ("True" !== "True") return;
if (modal !== null ) {
// Destroy existing modal
modal.remove();
modal = null;
modalContent = null;
}
modal = document.createElement('div');
modal.className = 'mermaid-fullscreen-modal' + (darkTheme ? ' dark-theme' : '');
modal.setAttribute('role', 'dialog');
modal.setAttribute('aria-modal', 'true');
modal.setAttribute('aria-label', 'Fullscreen diagram viewer');
modal.innerHTML = `
<button class="mermaid-fullscreen-close${darkTheme ? ' dark-theme' : ''}" aria-label="Close fullscreen">✕</button>
<div class="mermaid-container-fullscreen${darkTheme ? ' dark-theme' : ''}"></div>
`;
document.body.appendChild(modal);
modalContent = modal.querySelector('.mermaid-container-fullscreen');
const closeBtn = modal.querySelector('.mermaid-fullscreen-close');
const closeModal = () => {
modal.classList.remove('active');
modalContent.innerHTML = '';
document.body.style.overflow = ''
window.scrollTo({left: previousScrollOffset[0], top: previousScrollOffset[1], behavior: 'instant'});
};
closeBtn.addEventListener('click', closeModal);
modal.addEventListener('click', (e) => {
if (e.target === modal) closeModal();
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && modal.classList.contains('active')) {
closeModal();
}
});
document.querySelectorAll('.mermaid').forEach((mermaidDiv) => {
if (mermaidDiv.parentNode.classList.contains('mermaid-container') ||
mermaidDiv.closest('.mermaid-fullscreen-modal')) {
// Already processed, adjust button class if needed
const existingBtn = mermaidDiv.parentNode.querySelector('.mermaid-fullscreen-btn');
if (existingBtn) {
existingBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
}
return;
}
const container = document.createElement('div');
container.className = 'mermaid-container';
mermaidDiv.parentNode.insertBefore(container, mermaidDiv);
container.appendChild(mermaidDiv);
const fullscreenBtn = document.createElement('button');
fullscreenBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
fullscreenBtn.setAttribute('aria-label', 'View diagram in fullscreen');
fullscreenBtn.textContent = '⛶';
fullscreenBtn.style.opacity = '50%';
// Calculate dynamic position based on diagram's margin and padding
const diagramStyle = window.getComputedStyle(mermaidDiv);
const marginTop = parseFloat(diagramStyle.marginTop) || 0;
const marginRight = parseFloat(diagramStyle.marginRight) || 0;
const paddingTop = parseFloat(diagramStyle.paddingTop) || 0;
const paddingRight = parseFloat(diagramStyle.paddingRight) || 0;
fullscreenBtn.style.top = `${marginTop + paddingTop + 4}px`;
fullscreenBtn.style.right = `${marginRight + paddingRight + 4}px`;
fullscreenBtn.addEventListener('click', () => {
previousScrollOffset = [window.scroll, window.scrollY];
const clone = mermaidDiv.cloneNode(true);
modalContent.innerHTML = '';
modalContent.appendChild(clone);
const svg = clone.querySelector('svg');
if (svg) {
svg.removeAttribute('width');
svg.removeAttribute('height');
svg.style.width = '100%';
svg.style.height = 'auto';
svg.style.maxWidth = '100%';
svg.style.sdisplay = 'block';
if ("False" === "True") {
setTimeout(() => {
const g = svg.querySelector('g');
if (g) {
var svgD3 = d3.select(svg);
svgD3.html("<g class='wrapper'>" + svgD3.html() + "</g>");
var inner = svgD3.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svgD3.call(zoom);
}
}, 100);
}
}
modal.classList.add('active');
document.body.style.overflow = 'hidden';
});
container.appendChild(fullscreenBtn);
});
};
const load = async () => {
initStyles();
await runMermaid(true);
const reRunIfThemeChanges = async () => {
const newDarkTheme = isDarkTheme();
if (newDarkTheme !== darkTheme) {
darkTheme = newDarkTheme;
console.log("Theme change detected, re-running mermaid with", darkTheme ? "dark" : "default", "theme");
await mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
await runMermaid(true);
}
};
// Update theme classes when theme changes
const themeObserver = new MutationObserver(reRunIfThemeChanges);
themeObserver.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
themeObserver.observe(document.body, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
};
console.log("Initializing mermaid with", darkTheme ? "dark" : "default", "theme");
mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
window.addEventListener("load", load);
window.runMermaid = runMermaid;</script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="gestione_aree_frame_async.py" href="gestione_aree_frame_async_flow.html" />
<link rel="prev" title="Infrastruttura Async / DB" href="async_db_flow.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="async-msssql-query-py">
<h1><code class="docutils literal notranslate"><span class="pre">async_msssql_query.py</span></code><a class="headerlink" href="#async-msssql-query-py" title="Link to this heading"></a></h1>
<section id="scopo">
<h2>Scopo<a class="headerlink" href="#scopo" title="Link to this heading"></a></h2>
<p>Questo modulo centralizza la costruzione del DSN SQL Server e laccesso
asincrono al database tramite <code class="docutils literal notranslate"><span class="pre">AsyncMSSQLClient</span></code>.</p>
</section>
<section id="flusso-di-utilizzo">
<h2>Flusso di utilizzo<a class="headerlink" href="#flusso-di-utilizzo" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart TD
A[&quot;main.py o modulo chiamante&quot;] --&gt; B[&quot;make_mssql_dsn(...)&quot;]
B --&gt; C[&quot;Crea stringa mssql+aioodbc&quot;]
C --&gt; D[&quot;AsyncMSSQLClient(dsn)&quot;]
D --&gt; E[&quot;query_json(...) o exec(...)&quot;]
E --&gt; F[&quot;_ensure_engine()&quot;]
F --&gt; G{&quot;Engine gia creato?&quot;}
G -- No --&gt; H[&quot;create_async_engine(..., NullPool, loop corrente)&quot;]
G -- Si --&gt; I[&quot;Riusa engine esistente&quot;]
H --&gt; J[&quot;execute(text(sql), params)&quot;]
I --&gt; J
J --&gt; K[&quot;Normalizza rows/columns&quot;]
K --&gt; L[&quot;Ritorna payload JSON-friendly&quot;]
</pre></section>
<section id="schema-di-chiamata">
<h2>Schema di chiamata<a class="headerlink" href="#schema-di-chiamata" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart LR
DSN[&quot;make_mssql_dsn&quot;] --&gt; Client[&quot;AsyncMSSQLClient.__init__&quot;]
Client --&gt; Ensure[&quot;_ensure_engine&quot;]
Ensure --&gt; Query[&quot;query_json&quot;]
Ensure --&gt; Exec[&quot;exec&quot;]
Client --&gt; Dispose[&quot;dispose&quot;]
</pre></section>
<section id="note">
<h2>Note<a class="headerlink" href="#note" title="Link to this heading"></a></h2>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">NullPool</span></code> evita problemi di riuso connessioni tra loop diversi.</p></li>
<li><p>Lengine viene creato solo al primo utilizzo reale.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">query_json()</span></code> restituisce un formato gia pronto per le callback GUI.</p></li>
</ul>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">warehouse</a></h1>
<search id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Search"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../architecture.html">Architettura Complessiva</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api_reference.html">Riferimento API</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Flow Diagrams</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="README.html">Flow Diagrams</a></li>
<li class="toctree-l2"><a class="reference internal" href="main_flow.html"><code class="docutils literal notranslate"><span class="pre">main.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="layout_window_flow.html"><code class="docutils literal notranslate"><span class="pre">layout_window.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="reset_corsie_flow.html"><code class="docutils literal notranslate"><span class="pre">reset_corsie.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="view_celle_multiple_flow.html"><code class="docutils literal notranslate"><span class="pre">view_celle_multiple.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="search_pallets_flow.html"><code class="docutils literal notranslate"><span class="pre">search_pallets.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_pickinglist_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_pickinglist.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_db_flow.html">Infrastruttura Async / DB</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#"><code class="docutils literal notranslate"><span class="pre">async_msssql_query.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_aree_frame_async_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_aree_frame_async.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_loop_singleton_flow.html"><code class="docutils literal notranslate"><span class="pre">async_loop_singleton.py</span></code></a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
<li><a href="index.html">Flow Diagrams</a><ul>
<li>Previous: <a href="async_db_flow.html" title="previous chapter">Infrastruttura Async / DB</a></li>
<li>Next: <a href="gestione_aree_frame_async_flow.html" title="next chapter"><code class="docutils literal notranslate"><span class="pre">gestione_aree_frame_async.py</span></code></a></li>
</ul></li>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 9.1.0</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 1.0.0</a>
|
<a href="../_sources/flows/async_msssql_query_flow.md.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@@ -0,0 +1,606 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>gestione_aree_frame_async.py &#8212; warehouse 0.0.1 documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=5ecbeea2" />
<link rel="stylesheet" type="text/css" href="../_static/basic.css?v=b08954a9" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=27fed22d" />
<script src="../_static/documentation_options.js?v=d45e8c67"></script>
<script src="../_static/doctools.js?v=fd6eb6e6"></script>
<script src="../_static/sphinx_highlight.js?v=6ffebe34"></script>
<script src="https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js"></script>
<script type="module">import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11.12.1/dist/mermaid.esm.min.mjs";
const initStyles = () => {
const defaultStyle = document.createElement('style');
defaultStyle.textContent = `pre.mermaid {
/* Same as .mermaid-container > pre */
display: block;
width: 100%;
}
pre.mermaid > svg {
/* Same as .mermaid-container > pre > svg */
height: 500px;
width: 100%;
max-width: 100% !important;
}`;
document.head.appendChild(defaultStyle);
const fullscreenStyle = document.createElement('style');
fullscreenStyle.textContent = `.mermaid-container {
display: flex;
flex-direction: row;
width: 100%;
}
.mermaid-container > pre {
display: block;
width: 100%;
}
.mermaid-container > pre > svg {
height: 500px;
width: 100%;
max-width: 100% !important;
}
.mermaid-fullscreen-btn {
width: 28px;
height: 28px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
font-size: 14px;
line-height: 1;
padding: 0;
color: #333;
}
.mermaid-fullscreen-btn:hover {
opacity: 100% !important;
background: rgba(255, 255, 255, 1);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
transform: scale(1.1);
}
.mermaid-fullscreen-btn.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.3);
color: #e0e0e0;
}
.mermaid-fullscreen-btn.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 3px 10px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal {
display: none;
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 95vw;
height: 100vh;
background: rgba(255, 255, 255, 0.98);
z-index: 9999;
padding: 20px;
overflow: auto;
}
.mermaid-fullscreen-modal.dark-theme {
background: rgba(0, 0, 0, 0.98);
}
.mermaid-fullscreen-modal.active {
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen {
position: relative;
width: 95vw;
height: 90vh;
max-width: 95vw;
max-height: 90vh;
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
overflow: auto;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen.dark-theme {
background: #1a1a1a;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);
}
.mermaid-container-fullscreen pre.mermaid {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen .mermaid svg {
height: 100% !important;
width: 100% !important;
cursor: grab;
}
.mermaid-fullscreen-close {
position: fixed !important;
top: 20px !important;
right: 20px !important;
width: 40px;
height: 40px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 50%;
cursor: pointer;
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
transition: all 0.2s;
font-size: 24px;
line-height: 1;
color: #333;
}
.mermaid-fullscreen-close:hover {
background: white;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
transform: scale(1.1);
}
.mermaid-fullscreen-close.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.2);
color: #e0e0e0;
}
.mermaid-fullscreen-close.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 6px 16px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal .mermaid-fullscreen-btn {
display: none !important;
}`;
document.head.appendChild(fullscreenStyle);
}
// Detect if page has dark background
const isDarkTheme = () => {
// We use a set of heuristics:
// 1. Check for common dark mode classes or attributes
// 2. Check computed background color brightness
if (document.documentElement.classList.contains('dark') ||
document.documentElement.getAttribute('data-theme') === 'dark' ||
document.body.classList.contains('dark') ||
document.body.getAttribute('data-theme') === 'dark') {
// console.log("Dark theme detected via class/attribute");
return true;
}
if (document.documentElement.classList.contains('light') ||
document.documentElement.getAttribute('data-theme') === 'light' ||
document.body.classList.contains('light') ||
document.body.getAttribute('data-theme') === 'light') {
// console.log("Light theme detected via class/attribute");
return false;
}
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
// console.log("Dark theme detected via prefers-color-scheme");
return true;
}
const bgColor = window.getComputedStyle(document.body).backgroundColor;
const match = bgColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)/);
if (match) {
const r = parseInt(match[1]);
const g = parseInt(match[2]);
const b = parseInt(match[3]);
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
// console.log("Background color brightness:", brightness);
return brightness < 128;
}
// console.log("No dark or light theme detected, defaulting to light theme");
return false;
};
let darkTheme = isDarkTheme();
let modal = null;
let modalContent = null;
let previousScrollOffset = [window.scrollX, window.scrollY];
const runMermaid = async (rerun) => {
console.log("Running mermaid diagrams, rerun =", rerun);
// clear all existing mermaid charts
let all_mermaids = document.querySelectorAll(".mermaid");
if (rerun) {
all_mermaids.forEach((el) => {
if(!el.hasAttribute("data-original-code")) {
// store original code
// console.log(`Storing original code for first run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
if(el.getAttribute("data-processed") === "true") {
// remove and restore original
el.removeAttribute("data-processed");
// console.log(`Restoring original code for re-run: `, el.getAttribute('data-original-code'));
el.innerHTML = el.getAttribute('data-original-code');
} else {
// store original code
// console.log(`Storing original code for re-run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
});
await mermaid.run();
}
all_mermaids = document.querySelectorAll(".mermaid");
const mermaids_processed = document.querySelectorAll(".mermaid[data-processed='true']");
if ("False" === "True") {
const mermaids_to_add_zoom = -1 === -1 ? all_mermaids.length : -1;
if(mermaids_to_add_zoom > 0) {
var svgs = d3.selectAll("");
if(all_mermaids.length !== mermaids_processed.length) {
setTimeout(() => runMermaid(false), 200);
return;
} else if(svgs.size() !== mermaids_to_add_zoom) {
setTimeout(() => runMermaid(false), 200);
return;
} else {
svgs.each(function() {
var svg = d3.select(this);
svg.html("<g class='wrapper'>" + svg.html() + "</g>");
var inner = svg.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svg.call(zoom);
});
}
}
} else if(all_mermaids.length !== mermaids_processed.length) {
// Wait for mermaid to process all diagrams
setTimeout(() => runMermaid(false), 200);
return;
}
// Stop here if not adding fullscreen capability
if ("True" !== "True") return;
if (modal !== null ) {
// Destroy existing modal
modal.remove();
modal = null;
modalContent = null;
}
modal = document.createElement('div');
modal.className = 'mermaid-fullscreen-modal' + (darkTheme ? ' dark-theme' : '');
modal.setAttribute('role', 'dialog');
modal.setAttribute('aria-modal', 'true');
modal.setAttribute('aria-label', 'Fullscreen diagram viewer');
modal.innerHTML = `
<button class="mermaid-fullscreen-close${darkTheme ? ' dark-theme' : ''}" aria-label="Close fullscreen">✕</button>
<div class="mermaid-container-fullscreen${darkTheme ? ' dark-theme' : ''}"></div>
`;
document.body.appendChild(modal);
modalContent = modal.querySelector('.mermaid-container-fullscreen');
const closeBtn = modal.querySelector('.mermaid-fullscreen-close');
const closeModal = () => {
modal.classList.remove('active');
modalContent.innerHTML = '';
document.body.style.overflow = ''
window.scrollTo({left: previousScrollOffset[0], top: previousScrollOffset[1], behavior: 'instant'});
};
closeBtn.addEventListener('click', closeModal);
modal.addEventListener('click', (e) => {
if (e.target === modal) closeModal();
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && modal.classList.contains('active')) {
closeModal();
}
});
document.querySelectorAll('.mermaid').forEach((mermaidDiv) => {
if (mermaidDiv.parentNode.classList.contains('mermaid-container') ||
mermaidDiv.closest('.mermaid-fullscreen-modal')) {
// Already processed, adjust button class if needed
const existingBtn = mermaidDiv.parentNode.querySelector('.mermaid-fullscreen-btn');
if (existingBtn) {
existingBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
}
return;
}
const container = document.createElement('div');
container.className = 'mermaid-container';
mermaidDiv.parentNode.insertBefore(container, mermaidDiv);
container.appendChild(mermaidDiv);
const fullscreenBtn = document.createElement('button');
fullscreenBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
fullscreenBtn.setAttribute('aria-label', 'View diagram in fullscreen');
fullscreenBtn.textContent = '⛶';
fullscreenBtn.style.opacity = '50%';
// Calculate dynamic position based on diagram's margin and padding
const diagramStyle = window.getComputedStyle(mermaidDiv);
const marginTop = parseFloat(diagramStyle.marginTop) || 0;
const marginRight = parseFloat(diagramStyle.marginRight) || 0;
const paddingTop = parseFloat(diagramStyle.paddingTop) || 0;
const paddingRight = parseFloat(diagramStyle.paddingRight) || 0;
fullscreenBtn.style.top = `${marginTop + paddingTop + 4}px`;
fullscreenBtn.style.right = `${marginRight + paddingRight + 4}px`;
fullscreenBtn.addEventListener('click', () => {
previousScrollOffset = [window.scroll, window.scrollY];
const clone = mermaidDiv.cloneNode(true);
modalContent.innerHTML = '';
modalContent.appendChild(clone);
const svg = clone.querySelector('svg');
if (svg) {
svg.removeAttribute('width');
svg.removeAttribute('height');
svg.style.width = '100%';
svg.style.height = 'auto';
svg.style.maxWidth = '100%';
svg.style.sdisplay = 'block';
if ("False" === "True") {
setTimeout(() => {
const g = svg.querySelector('g');
if (g) {
var svgD3 = d3.select(svg);
svgD3.html("<g class='wrapper'>" + svgD3.html() + "</g>");
var inner = svgD3.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svgD3.call(zoom);
}
}, 100);
}
}
modal.classList.add('active');
document.body.style.overflow = 'hidden';
});
container.appendChild(fullscreenBtn);
});
};
const load = async () => {
initStyles();
await runMermaid(true);
const reRunIfThemeChanges = async () => {
const newDarkTheme = isDarkTheme();
if (newDarkTheme !== darkTheme) {
darkTheme = newDarkTheme;
console.log("Theme change detected, re-running mermaid with", darkTheme ? "dark" : "default", "theme");
await mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
await runMermaid(true);
}
};
// Update theme classes when theme changes
const themeObserver = new MutationObserver(reRunIfThemeChanges);
themeObserver.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
themeObserver.observe(document.body, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
};
console.log("Initializing mermaid with", darkTheme ? "dark" : "default", "theme");
mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
window.addEventListener("load", load);
window.runMermaid = runMermaid;</script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="async_loop_singleton.py" href="async_loop_singleton_flow.html" />
<link rel="prev" title="async_msssql_query.py" href="async_msssql_query_flow.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="gestione-aree-frame-async-py">
<h1><code class="docutils literal notranslate"><span class="pre">gestione_aree_frame_async.py</span></code><a class="headerlink" href="#gestione-aree-frame-async-py" title="Link to this heading"></a></h1>
<section id="scopo">
<h2>Scopo<a class="headerlink" href="#scopo" title="Link to this heading"></a></h2>
<p>Questo modulo fornisce linfrastruttura async usata dalle finestre GUI:</p>
<ul class="simple">
<li><p>loop asincrono globale;</p></li>
<li><p>overlay di attesa;</p></li>
<li><p>runner che collega coroutine e callback Tk.</p></li>
</ul>
</section>
<section id="flusso-infrastrutturale">
<h2>Flusso infrastrutturale<a class="headerlink" href="#flusso-infrastrutturale" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart TD
A[&quot;Metodo finestra GUI&quot;] --&gt; B[&quot;AsyncRunner.run(awaitable)&quot;]
B --&gt; C{&quot;busy overlay richiesto?&quot;}
C -- Si --&gt; D[&quot;BusyOverlay.show()&quot;]
C -- No --&gt; E[&quot;Salta overlay&quot;]
D --&gt; F[&quot;run_coroutine_threadsafe(awaitable, loop globale)&quot;]
E --&gt; F
F --&gt; G[&quot;Polling del Future&quot;]
G --&gt; H{&quot;Future completato?&quot;}
H -- No --&gt; G
H -- Si --&gt; I{&quot;Successo o errore?&quot;}
I -- Successo --&gt; J[&quot;widget.after(..., on_success)&quot;]
I -- Errore --&gt; K[&quot;widget.after(..., on_error)&quot;]
J --&gt; L[&quot;BusyOverlay.hide()&quot;]
K --&gt; L
</pre></section>
<section id="schema-di-componenti">
<h2>Schema di componenti<a class="headerlink" href="#schema-di-componenti" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart LR
Holder[&quot;_LoopHolder&quot;] --&gt; Loop[&quot;get_global_loop&quot;]
Loop --&gt; Runner[&quot;AsyncRunner&quot;]
Overlay[&quot;BusyOverlay&quot;] --&gt; Runner
Runner --&gt; GUI[&quot;Moduli GUI&quot;]
</pre></section>
<section id="note">
<h2>Note<a class="headerlink" href="#note" title="Link to this heading"></a></h2>
<ul class="simple">
<li><p>Il modulo fa da ponte tra thread Tk e thread del loop asincrono.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">BusyOverlay</span></code> e riusato da piu finestre, quindi e un componente condiviso.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">AsyncRunner</span></code> evita che i moduli GUI gestiscano direttamente i <code class="docutils literal notranslate"><span class="pre">Future</span></code>.</p></li>
</ul>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">warehouse</a></h1>
<search id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Search"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../architecture.html">Architettura Complessiva</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api_reference.html">Riferimento API</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Flow Diagrams</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="README.html">Flow Diagrams</a></li>
<li class="toctree-l2"><a class="reference internal" href="main_flow.html"><code class="docutils literal notranslate"><span class="pre">main.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="layout_window_flow.html"><code class="docutils literal notranslate"><span class="pre">layout_window.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="reset_corsie_flow.html"><code class="docutils literal notranslate"><span class="pre">reset_corsie.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="view_celle_multiple_flow.html"><code class="docutils literal notranslate"><span class="pre">view_celle_multiple.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="search_pallets_flow.html"><code class="docutils literal notranslate"><span class="pre">search_pallets.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_pickinglist_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_pickinglist.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_db_flow.html">Infrastruttura Async / DB</a></li>
<li class="toctree-l2"><a class="reference internal" href="async_msssql_query_flow.html"><code class="docutils literal notranslate"><span class="pre">async_msssql_query.py</span></code></a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#"><code class="docutils literal notranslate"><span class="pre">gestione_aree_frame_async.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_loop_singleton_flow.html"><code class="docutils literal notranslate"><span class="pre">async_loop_singleton.py</span></code></a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
<li><a href="index.html">Flow Diagrams</a><ul>
<li>Previous: <a href="async_msssql_query_flow.html" title="previous chapter"><code class="docutils literal notranslate"><span class="pre">async_msssql_query.py</span></code></a></li>
<li>Next: <a href="async_loop_singleton_flow.html" title="next chapter"><code class="docutils literal notranslate"><span class="pre">async_loop_singleton.py</span></code></a></li>
</ul></li>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 9.1.0</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 1.0.0</a>
|
<a href="../_sources/flows/gestione_aree_frame_async_flow.md.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@@ -0,0 +1,628 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>gestione_pickinglist.py &#8212; warehouse 0.0.1 documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=5ecbeea2" />
<link rel="stylesheet" type="text/css" href="../_static/basic.css?v=b08954a9" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=27fed22d" />
<script src="../_static/documentation_options.js?v=d45e8c67"></script>
<script src="../_static/doctools.js?v=fd6eb6e6"></script>
<script src="../_static/sphinx_highlight.js?v=6ffebe34"></script>
<script src="https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js"></script>
<script type="module">import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11.12.1/dist/mermaid.esm.min.mjs";
const initStyles = () => {
const defaultStyle = document.createElement('style');
defaultStyle.textContent = `pre.mermaid {
/* Same as .mermaid-container > pre */
display: block;
width: 100%;
}
pre.mermaid > svg {
/* Same as .mermaid-container > pre > svg */
height: 500px;
width: 100%;
max-width: 100% !important;
}`;
document.head.appendChild(defaultStyle);
const fullscreenStyle = document.createElement('style');
fullscreenStyle.textContent = `.mermaid-container {
display: flex;
flex-direction: row;
width: 100%;
}
.mermaid-container > pre {
display: block;
width: 100%;
}
.mermaid-container > pre > svg {
height: 500px;
width: 100%;
max-width: 100% !important;
}
.mermaid-fullscreen-btn {
width: 28px;
height: 28px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
font-size: 14px;
line-height: 1;
padding: 0;
color: #333;
}
.mermaid-fullscreen-btn:hover {
opacity: 100% !important;
background: rgba(255, 255, 255, 1);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
transform: scale(1.1);
}
.mermaid-fullscreen-btn.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.3);
color: #e0e0e0;
}
.mermaid-fullscreen-btn.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 3px 10px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal {
display: none;
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 95vw;
height: 100vh;
background: rgba(255, 255, 255, 0.98);
z-index: 9999;
padding: 20px;
overflow: auto;
}
.mermaid-fullscreen-modal.dark-theme {
background: rgba(0, 0, 0, 0.98);
}
.mermaid-fullscreen-modal.active {
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen {
position: relative;
width: 95vw;
height: 90vh;
max-width: 95vw;
max-height: 90vh;
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
overflow: auto;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen.dark-theme {
background: #1a1a1a;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);
}
.mermaid-container-fullscreen pre.mermaid {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen .mermaid svg {
height: 100% !important;
width: 100% !important;
cursor: grab;
}
.mermaid-fullscreen-close {
position: fixed !important;
top: 20px !important;
right: 20px !important;
width: 40px;
height: 40px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 50%;
cursor: pointer;
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
transition: all 0.2s;
font-size: 24px;
line-height: 1;
color: #333;
}
.mermaid-fullscreen-close:hover {
background: white;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
transform: scale(1.1);
}
.mermaid-fullscreen-close.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.2);
color: #e0e0e0;
}
.mermaid-fullscreen-close.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 6px 16px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal .mermaid-fullscreen-btn {
display: none !important;
}`;
document.head.appendChild(fullscreenStyle);
}
// Detect if page has dark background
const isDarkTheme = () => {
// We use a set of heuristics:
// 1. Check for common dark mode classes or attributes
// 2. Check computed background color brightness
if (document.documentElement.classList.contains('dark') ||
document.documentElement.getAttribute('data-theme') === 'dark' ||
document.body.classList.contains('dark') ||
document.body.getAttribute('data-theme') === 'dark') {
// console.log("Dark theme detected via class/attribute");
return true;
}
if (document.documentElement.classList.contains('light') ||
document.documentElement.getAttribute('data-theme') === 'light' ||
document.body.classList.contains('light') ||
document.body.getAttribute('data-theme') === 'light') {
// console.log("Light theme detected via class/attribute");
return false;
}
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
// console.log("Dark theme detected via prefers-color-scheme");
return true;
}
const bgColor = window.getComputedStyle(document.body).backgroundColor;
const match = bgColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)/);
if (match) {
const r = parseInt(match[1]);
const g = parseInt(match[2]);
const b = parseInt(match[3]);
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
// console.log("Background color brightness:", brightness);
return brightness < 128;
}
// console.log("No dark or light theme detected, defaulting to light theme");
return false;
};
let darkTheme = isDarkTheme();
let modal = null;
let modalContent = null;
let previousScrollOffset = [window.scrollX, window.scrollY];
const runMermaid = async (rerun) => {
console.log("Running mermaid diagrams, rerun =", rerun);
// clear all existing mermaid charts
let all_mermaids = document.querySelectorAll(".mermaid");
if (rerun) {
all_mermaids.forEach((el) => {
if(!el.hasAttribute("data-original-code")) {
// store original code
// console.log(`Storing original code for first run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
if(el.getAttribute("data-processed") === "true") {
// remove and restore original
el.removeAttribute("data-processed");
// console.log(`Restoring original code for re-run: `, el.getAttribute('data-original-code'));
el.innerHTML = el.getAttribute('data-original-code');
} else {
// store original code
// console.log(`Storing original code for re-run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
});
await mermaid.run();
}
all_mermaids = document.querySelectorAll(".mermaid");
const mermaids_processed = document.querySelectorAll(".mermaid[data-processed='true']");
if ("False" === "True") {
const mermaids_to_add_zoom = -1 === -1 ? all_mermaids.length : -1;
if(mermaids_to_add_zoom > 0) {
var svgs = d3.selectAll("");
if(all_mermaids.length !== mermaids_processed.length) {
setTimeout(() => runMermaid(false), 200);
return;
} else if(svgs.size() !== mermaids_to_add_zoom) {
setTimeout(() => runMermaid(false), 200);
return;
} else {
svgs.each(function() {
var svg = d3.select(this);
svg.html("<g class='wrapper'>" + svg.html() + "</g>");
var inner = svg.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svg.call(zoom);
});
}
}
} else if(all_mermaids.length !== mermaids_processed.length) {
// Wait for mermaid to process all diagrams
setTimeout(() => runMermaid(false), 200);
return;
}
// Stop here if not adding fullscreen capability
if ("True" !== "True") return;
if (modal !== null ) {
// Destroy existing modal
modal.remove();
modal = null;
modalContent = null;
}
modal = document.createElement('div');
modal.className = 'mermaid-fullscreen-modal' + (darkTheme ? ' dark-theme' : '');
modal.setAttribute('role', 'dialog');
modal.setAttribute('aria-modal', 'true');
modal.setAttribute('aria-label', 'Fullscreen diagram viewer');
modal.innerHTML = `
<button class="mermaid-fullscreen-close${darkTheme ? ' dark-theme' : ''}" aria-label="Close fullscreen">✕</button>
<div class="mermaid-container-fullscreen${darkTheme ? ' dark-theme' : ''}"></div>
`;
document.body.appendChild(modal);
modalContent = modal.querySelector('.mermaid-container-fullscreen');
const closeBtn = modal.querySelector('.mermaid-fullscreen-close');
const closeModal = () => {
modal.classList.remove('active');
modalContent.innerHTML = '';
document.body.style.overflow = ''
window.scrollTo({left: previousScrollOffset[0], top: previousScrollOffset[1], behavior: 'instant'});
};
closeBtn.addEventListener('click', closeModal);
modal.addEventListener('click', (e) => {
if (e.target === modal) closeModal();
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && modal.classList.contains('active')) {
closeModal();
}
});
document.querySelectorAll('.mermaid').forEach((mermaidDiv) => {
if (mermaidDiv.parentNode.classList.contains('mermaid-container') ||
mermaidDiv.closest('.mermaid-fullscreen-modal')) {
// Already processed, adjust button class if needed
const existingBtn = mermaidDiv.parentNode.querySelector('.mermaid-fullscreen-btn');
if (existingBtn) {
existingBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
}
return;
}
const container = document.createElement('div');
container.className = 'mermaid-container';
mermaidDiv.parentNode.insertBefore(container, mermaidDiv);
container.appendChild(mermaidDiv);
const fullscreenBtn = document.createElement('button');
fullscreenBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
fullscreenBtn.setAttribute('aria-label', 'View diagram in fullscreen');
fullscreenBtn.textContent = '⛶';
fullscreenBtn.style.opacity = '50%';
// Calculate dynamic position based on diagram's margin and padding
const diagramStyle = window.getComputedStyle(mermaidDiv);
const marginTop = parseFloat(diagramStyle.marginTop) || 0;
const marginRight = parseFloat(diagramStyle.marginRight) || 0;
const paddingTop = parseFloat(diagramStyle.paddingTop) || 0;
const paddingRight = parseFloat(diagramStyle.paddingRight) || 0;
fullscreenBtn.style.top = `${marginTop + paddingTop + 4}px`;
fullscreenBtn.style.right = `${marginRight + paddingRight + 4}px`;
fullscreenBtn.addEventListener('click', () => {
previousScrollOffset = [window.scroll, window.scrollY];
const clone = mermaidDiv.cloneNode(true);
modalContent.innerHTML = '';
modalContent.appendChild(clone);
const svg = clone.querySelector('svg');
if (svg) {
svg.removeAttribute('width');
svg.removeAttribute('height');
svg.style.width = '100%';
svg.style.height = 'auto';
svg.style.maxWidth = '100%';
svg.style.sdisplay = 'block';
if ("False" === "True") {
setTimeout(() => {
const g = svg.querySelector('g');
if (g) {
var svgD3 = d3.select(svg);
svgD3.html("<g class='wrapper'>" + svgD3.html() + "</g>");
var inner = svgD3.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svgD3.call(zoom);
}
}, 100);
}
}
modal.classList.add('active');
document.body.style.overflow = 'hidden';
});
container.appendChild(fullscreenBtn);
});
};
const load = async () => {
initStyles();
await runMermaid(true);
const reRunIfThemeChanges = async () => {
const newDarkTheme = isDarkTheme();
if (newDarkTheme !== darkTheme) {
darkTheme = newDarkTheme;
console.log("Theme change detected, re-running mermaid with", darkTheme ? "dark" : "default", "theme");
await mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
await runMermaid(true);
}
};
// Update theme classes when theme changes
const themeObserver = new MutationObserver(reRunIfThemeChanges);
themeObserver.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
themeObserver.observe(document.body, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
};
console.log("Initializing mermaid with", darkTheme ? "dark" : "default", "theme");
mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
window.addEventListener("load", load);
window.runMermaid = runMermaid;</script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Infrastruttura Async / DB" href="async_db_flow.html" />
<link rel="prev" title="search_pallets.py" href="search_pallets_flow.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="gestione-pickinglist-py">
<h1><code class="docutils literal notranslate"><span class="pre">gestione_pickinglist.py</span></code><a class="headerlink" href="#gestione-pickinglist-py" title="Link to this heading"></a></h1>
<section id="scopo">
<h2>Scopo<a class="headerlink" href="#scopo" title="Link to this heading"></a></h2>
<p>Questo modulo gestisce la vista master/detail delle picking list e permette di:</p>
<ul class="simple">
<li><p>caricare lelenco dei documenti;</p></li>
<li><p>vedere il dettaglio UDC della riga selezionata;</p></li>
<li><p>prenotare e s-prenotare una picking list;</p></li>
<li><p>mantenere una UI fluida con spinner e refresh differiti.</p></li>
</ul>
</section>
<section id="flusso-di-apertura">
<h2>Flusso di apertura<a class="headerlink" href="#flusso-di-apertura" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart TD
A[&quot;open_pickinglist_window() da main.py&quot;] --&gt; B[&quot;create_pickinglist_frame()&quot;]
B --&gt; C[&quot;GestionePickingListFrame.__init__()&quot;]
C --&gt; D[&quot;_build_layout()&quot;]
D --&gt; E[&quot;after_idle(_first_show)&quot;]
E --&gt; F[&quot;reload_from_db(first=True)&quot;]
F --&gt; G[&quot;query_json SQL_PL&quot;]
G --&gt; H[&quot;_refresh_mid_rows()&quot;]
H --&gt; I[&quot;Render tabella master&quot;]
</pre></section>
<section id="flusso-master-detail">
<h2>Flusso master/detail<a class="headerlink" href="#flusso-master-detail" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart TD
A[&quot;Utente seleziona checkbox riga&quot;] --&gt; B[&quot;on_row_checked()&quot;]
B --&gt; C[&quot;Deseleziona altre righe&quot;]
C --&gt; D[&quot;Salva detail_doc&quot;]
D --&gt; E[&quot;query_json SQL_PL_DETAILS&quot;]
E --&gt; F[&quot;_refresh_details()&quot;]
F --&gt; G[&quot;Render tabella dettaglio&quot;]
</pre></section>
<section id="prenotazione-s-prenotazione">
<h2>Prenotazione / s-prenotazione<a class="headerlink" href="#prenotazione-s-prenotazione" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart TD
A[&quot;Click Prenota o S-prenota&quot;] --&gt; B[&quot;Verifica riga selezionata&quot;]
B --&gt; C[&quot;Determina documento e stato atteso&quot;]
C --&gt; D[&quot;Chiama sp_xExePackingListPallet_async()&quot;]
D --&gt; E[&quot;Aggiorna Celle e LogPackingList sul DB&quot;]
E --&gt; F[&quot;SPResult&quot;]
F --&gt; G{&quot;rc == 0?&quot;}
G -- Si --&gt; H[&quot;_recolor_row_by_documento()&quot;]
G -- No --&gt; I[&quot;Messaggio di errore&quot;]
</pre></section>
<section id="schema-di-chiamata">
<h2>Schema di chiamata<a class="headerlink" href="#schema-di-chiamata" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart LR
Init[&quot;__init__&quot;] --&gt; Build[&quot;_build_layout&quot;]
Init --&gt; First[&quot;_first_show&quot;]
First --&gt; Reload[&quot;reload_from_db&quot;]
Reload --&gt; Mid[&quot;_refresh_mid_rows&quot;]
Check[&quot;on_row_checked&quot;] --&gt; Details[&quot;_refresh_details&quot;]
Pren[&quot;on_prenota&quot;] --&gt; SP[&quot;sp_xExePackingListPallet_async&quot;]
Spren[&quot;on_sprenota&quot;] --&gt; SP
</pre></section>
<section id="note">
<h2>Note<a class="headerlink" href="#note" title="Link to this heading"></a></h2>
<ul class="simple">
<li><p>Il modulo usa <code class="docutils literal notranslate"><span class="pre">AsyncRunner</span></code>, <code class="docutils literal notranslate"><span class="pre">BusyOverlay</span></code> e <code class="docutils literal notranslate"><span class="pre">ToolbarSpinner</span></code>.</p></li>
<li><p>Il caricamento iniziale è differito con <code class="docutils literal notranslate"><span class="pre">after_idle</span></code> per ridurre lo sfarfallio.</p></li>
<li><p>La riga selezionata viene tenuta separata dal dettaglio tramite <code class="docutils literal notranslate"><span class="pre">detail_doc</span></code>.</p></li>
</ul>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">warehouse</a></h1>
<search id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Search"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../architecture.html">Architettura Complessiva</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api_reference.html">Riferimento API</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Flow Diagrams</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="README.html">Flow Diagrams</a></li>
<li class="toctree-l2"><a class="reference internal" href="main_flow.html"><code class="docutils literal notranslate"><span class="pre">main.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="layout_window_flow.html"><code class="docutils literal notranslate"><span class="pre">layout_window.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="reset_corsie_flow.html"><code class="docutils literal notranslate"><span class="pre">reset_corsie.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="view_celle_multiple_flow.html"><code class="docutils literal notranslate"><span class="pre">view_celle_multiple.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="search_pallets_flow.html"><code class="docutils literal notranslate"><span class="pre">search_pallets.py</span></code></a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#"><code class="docutils literal notranslate"><span class="pre">gestione_pickinglist.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_db_flow.html">Infrastruttura Async / DB</a></li>
<li class="toctree-l2"><a class="reference internal" href="async_msssql_query_flow.html"><code class="docutils literal notranslate"><span class="pre">async_msssql_query.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_aree_frame_async_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_aree_frame_async.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_loop_singleton_flow.html"><code class="docutils literal notranslate"><span class="pre">async_loop_singleton.py</span></code></a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
<li><a href="index.html">Flow Diagrams</a><ul>
<li>Previous: <a href="search_pallets_flow.html" title="previous chapter"><code class="docutils literal notranslate"><span class="pre">search_pallets.py</span></code></a></li>
<li>Next: <a href="async_db_flow.html" title="next chapter">Infrastruttura Async / DB</a></li>
</ul></li>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 9.1.0</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 1.0.0</a>
|
<a href="../_sources/flows/gestione_pickinglist_flow.md.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

140
docs/_build/html/flows/index.html vendored Normal file
View File

@@ -0,0 +1,140 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Flow Diagrams &#8212; warehouse 0.0.1 documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=5ecbeea2" />
<link rel="stylesheet" type="text/css" href="../_static/basic.css?v=b08954a9" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=27fed22d" />
<script src="../_static/documentation_options.js?v=d45e8c67"></script>
<script src="../_static/doctools.js?v=fd6eb6e6"></script>
<script src="../_static/sphinx_highlight.js?v=6ffebe34"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Flow Diagrams" href="README.html" />
<link rel="prev" title="Riferimento API" href="../api_reference.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="flow-diagrams">
<h1>Flow Diagrams<a class="headerlink" href="#flow-diagrams" title="Link to this heading"></a></h1>
<p>Questa sezione raccoglie i diagrammi Mermaid dei moduli applicativi e
infrastrutturali.</p>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="README.html">Flow Diagrams</a></li>
<li class="toctree-l1"><a class="reference internal" href="main_flow.html"><code class="docutils literal notranslate"><span class="pre">main.py</span></code></a></li>
<li class="toctree-l1"><a class="reference internal" href="layout_window_flow.html"><code class="docutils literal notranslate"><span class="pre">layout_window.py</span></code></a></li>
<li class="toctree-l1"><a class="reference internal" href="reset_corsie_flow.html"><code class="docutils literal notranslate"><span class="pre">reset_corsie.py</span></code></a></li>
<li class="toctree-l1"><a class="reference internal" href="view_celle_multiple_flow.html"><code class="docutils literal notranslate"><span class="pre">view_celle_multiple.py</span></code></a></li>
<li class="toctree-l1"><a class="reference internal" href="search_pallets_flow.html"><code class="docutils literal notranslate"><span class="pre">search_pallets.py</span></code></a></li>
<li class="toctree-l1"><a class="reference internal" href="gestione_pickinglist_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_pickinglist.py</span></code></a></li>
<li class="toctree-l1"><a class="reference internal" href="async_db_flow.html">Infrastruttura Async / DB</a></li>
<li class="toctree-l1"><a class="reference internal" href="async_msssql_query_flow.html"><code class="docutils literal notranslate"><span class="pre">async_msssql_query.py</span></code></a></li>
<li class="toctree-l1"><a class="reference internal" href="gestione_aree_frame_async_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_aree_frame_async.py</span></code></a></li>
<li class="toctree-l1"><a class="reference internal" href="async_loop_singleton_flow.html"><code class="docutils literal notranslate"><span class="pre">async_loop_singleton.py</span></code></a></li>
</ul>
</div>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">warehouse</a></h1>
<search id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Search"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../architecture.html">Architettura Complessiva</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api_reference.html">Riferimento API</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Flow Diagrams</a><ul>
<li class="toctree-l2"><a class="reference internal" href="README.html">Flow Diagrams</a></li>
<li class="toctree-l2"><a class="reference internal" href="main_flow.html"><code class="docutils literal notranslate"><span class="pre">main.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="layout_window_flow.html"><code class="docutils literal notranslate"><span class="pre">layout_window.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="reset_corsie_flow.html"><code class="docutils literal notranslate"><span class="pre">reset_corsie.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="view_celle_multiple_flow.html"><code class="docutils literal notranslate"><span class="pre">view_celle_multiple.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="search_pallets_flow.html"><code class="docutils literal notranslate"><span class="pre">search_pallets.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_pickinglist_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_pickinglist.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_db_flow.html">Infrastruttura Async / DB</a></li>
<li class="toctree-l2"><a class="reference internal" href="async_msssql_query_flow.html"><code class="docutils literal notranslate"><span class="pre">async_msssql_query.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_aree_frame_async_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_aree_frame_async.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_loop_singleton_flow.html"><code class="docutils literal notranslate"><span class="pre">async_loop_singleton.py</span></code></a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
<li>Previous: <a href="../api_reference.html" title="previous chapter">Riferimento API</a></li>
<li>Next: <a href="README.html" title="next chapter">Flow Diagrams</a></li>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 9.1.0</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 1.0.0</a>
|
<a href="../_sources/flows/index.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@@ -0,0 +1,620 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>layout_window.py &#8212; warehouse 0.0.1 documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=5ecbeea2" />
<link rel="stylesheet" type="text/css" href="../_static/basic.css?v=b08954a9" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=27fed22d" />
<script src="../_static/documentation_options.js?v=d45e8c67"></script>
<script src="../_static/doctools.js?v=fd6eb6e6"></script>
<script src="../_static/sphinx_highlight.js?v=6ffebe34"></script>
<script src="https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js"></script>
<script type="module">import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11.12.1/dist/mermaid.esm.min.mjs";
const initStyles = () => {
const defaultStyle = document.createElement('style');
defaultStyle.textContent = `pre.mermaid {
/* Same as .mermaid-container > pre */
display: block;
width: 100%;
}
pre.mermaid > svg {
/* Same as .mermaid-container > pre > svg */
height: 500px;
width: 100%;
max-width: 100% !important;
}`;
document.head.appendChild(defaultStyle);
const fullscreenStyle = document.createElement('style');
fullscreenStyle.textContent = `.mermaid-container {
display: flex;
flex-direction: row;
width: 100%;
}
.mermaid-container > pre {
display: block;
width: 100%;
}
.mermaid-container > pre > svg {
height: 500px;
width: 100%;
max-width: 100% !important;
}
.mermaid-fullscreen-btn {
width: 28px;
height: 28px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
font-size: 14px;
line-height: 1;
padding: 0;
color: #333;
}
.mermaid-fullscreen-btn:hover {
opacity: 100% !important;
background: rgba(255, 255, 255, 1);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
transform: scale(1.1);
}
.mermaid-fullscreen-btn.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.3);
color: #e0e0e0;
}
.mermaid-fullscreen-btn.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 3px 10px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal {
display: none;
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 95vw;
height: 100vh;
background: rgba(255, 255, 255, 0.98);
z-index: 9999;
padding: 20px;
overflow: auto;
}
.mermaid-fullscreen-modal.dark-theme {
background: rgba(0, 0, 0, 0.98);
}
.mermaid-fullscreen-modal.active {
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen {
position: relative;
width: 95vw;
height: 90vh;
max-width: 95vw;
max-height: 90vh;
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
overflow: auto;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen.dark-theme {
background: #1a1a1a;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);
}
.mermaid-container-fullscreen pre.mermaid {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen .mermaid svg {
height: 100% !important;
width: 100% !important;
cursor: grab;
}
.mermaid-fullscreen-close {
position: fixed !important;
top: 20px !important;
right: 20px !important;
width: 40px;
height: 40px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 50%;
cursor: pointer;
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
transition: all 0.2s;
font-size: 24px;
line-height: 1;
color: #333;
}
.mermaid-fullscreen-close:hover {
background: white;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
transform: scale(1.1);
}
.mermaid-fullscreen-close.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.2);
color: #e0e0e0;
}
.mermaid-fullscreen-close.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 6px 16px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal .mermaid-fullscreen-btn {
display: none !important;
}`;
document.head.appendChild(fullscreenStyle);
}
// Detect if page has dark background
const isDarkTheme = () => {
// We use a set of heuristics:
// 1. Check for common dark mode classes or attributes
// 2. Check computed background color brightness
if (document.documentElement.classList.contains('dark') ||
document.documentElement.getAttribute('data-theme') === 'dark' ||
document.body.classList.contains('dark') ||
document.body.getAttribute('data-theme') === 'dark') {
// console.log("Dark theme detected via class/attribute");
return true;
}
if (document.documentElement.classList.contains('light') ||
document.documentElement.getAttribute('data-theme') === 'light' ||
document.body.classList.contains('light') ||
document.body.getAttribute('data-theme') === 'light') {
// console.log("Light theme detected via class/attribute");
return false;
}
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
// console.log("Dark theme detected via prefers-color-scheme");
return true;
}
const bgColor = window.getComputedStyle(document.body).backgroundColor;
const match = bgColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)/);
if (match) {
const r = parseInt(match[1]);
const g = parseInt(match[2]);
const b = parseInt(match[3]);
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
// console.log("Background color brightness:", brightness);
return brightness < 128;
}
// console.log("No dark or light theme detected, defaulting to light theme");
return false;
};
let darkTheme = isDarkTheme();
let modal = null;
let modalContent = null;
let previousScrollOffset = [window.scrollX, window.scrollY];
const runMermaid = async (rerun) => {
console.log("Running mermaid diagrams, rerun =", rerun);
// clear all existing mermaid charts
let all_mermaids = document.querySelectorAll(".mermaid");
if (rerun) {
all_mermaids.forEach((el) => {
if(!el.hasAttribute("data-original-code")) {
// store original code
// console.log(`Storing original code for first run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
if(el.getAttribute("data-processed") === "true") {
// remove and restore original
el.removeAttribute("data-processed");
// console.log(`Restoring original code for re-run: `, el.getAttribute('data-original-code'));
el.innerHTML = el.getAttribute('data-original-code');
} else {
// store original code
// console.log(`Storing original code for re-run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
});
await mermaid.run();
}
all_mermaids = document.querySelectorAll(".mermaid");
const mermaids_processed = document.querySelectorAll(".mermaid[data-processed='true']");
if ("False" === "True") {
const mermaids_to_add_zoom = -1 === -1 ? all_mermaids.length : -1;
if(mermaids_to_add_zoom > 0) {
var svgs = d3.selectAll("");
if(all_mermaids.length !== mermaids_processed.length) {
setTimeout(() => runMermaid(false), 200);
return;
} else if(svgs.size() !== mermaids_to_add_zoom) {
setTimeout(() => runMermaid(false), 200);
return;
} else {
svgs.each(function() {
var svg = d3.select(this);
svg.html("<g class='wrapper'>" + svg.html() + "</g>");
var inner = svg.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svg.call(zoom);
});
}
}
} else if(all_mermaids.length !== mermaids_processed.length) {
// Wait for mermaid to process all diagrams
setTimeout(() => runMermaid(false), 200);
return;
}
// Stop here if not adding fullscreen capability
if ("True" !== "True") return;
if (modal !== null ) {
// Destroy existing modal
modal.remove();
modal = null;
modalContent = null;
}
modal = document.createElement('div');
modal.className = 'mermaid-fullscreen-modal' + (darkTheme ? ' dark-theme' : '');
modal.setAttribute('role', 'dialog');
modal.setAttribute('aria-modal', 'true');
modal.setAttribute('aria-label', 'Fullscreen diagram viewer');
modal.innerHTML = `
<button class="mermaid-fullscreen-close${darkTheme ? ' dark-theme' : ''}" aria-label="Close fullscreen">✕</button>
<div class="mermaid-container-fullscreen${darkTheme ? ' dark-theme' : ''}"></div>
`;
document.body.appendChild(modal);
modalContent = modal.querySelector('.mermaid-container-fullscreen');
const closeBtn = modal.querySelector('.mermaid-fullscreen-close');
const closeModal = () => {
modal.classList.remove('active');
modalContent.innerHTML = '';
document.body.style.overflow = ''
window.scrollTo({left: previousScrollOffset[0], top: previousScrollOffset[1], behavior: 'instant'});
};
closeBtn.addEventListener('click', closeModal);
modal.addEventListener('click', (e) => {
if (e.target === modal) closeModal();
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && modal.classList.contains('active')) {
closeModal();
}
});
document.querySelectorAll('.mermaid').forEach((mermaidDiv) => {
if (mermaidDiv.parentNode.classList.contains('mermaid-container') ||
mermaidDiv.closest('.mermaid-fullscreen-modal')) {
// Already processed, adjust button class if needed
const existingBtn = mermaidDiv.parentNode.querySelector('.mermaid-fullscreen-btn');
if (existingBtn) {
existingBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
}
return;
}
const container = document.createElement('div');
container.className = 'mermaid-container';
mermaidDiv.parentNode.insertBefore(container, mermaidDiv);
container.appendChild(mermaidDiv);
const fullscreenBtn = document.createElement('button');
fullscreenBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
fullscreenBtn.setAttribute('aria-label', 'View diagram in fullscreen');
fullscreenBtn.textContent = '⛶';
fullscreenBtn.style.opacity = '50%';
// Calculate dynamic position based on diagram's margin and padding
const diagramStyle = window.getComputedStyle(mermaidDiv);
const marginTop = parseFloat(diagramStyle.marginTop) || 0;
const marginRight = parseFloat(diagramStyle.marginRight) || 0;
const paddingTop = parseFloat(diagramStyle.paddingTop) || 0;
const paddingRight = parseFloat(diagramStyle.paddingRight) || 0;
fullscreenBtn.style.top = `${marginTop + paddingTop + 4}px`;
fullscreenBtn.style.right = `${marginRight + paddingRight + 4}px`;
fullscreenBtn.addEventListener('click', () => {
previousScrollOffset = [window.scroll, window.scrollY];
const clone = mermaidDiv.cloneNode(true);
modalContent.innerHTML = '';
modalContent.appendChild(clone);
const svg = clone.querySelector('svg');
if (svg) {
svg.removeAttribute('width');
svg.removeAttribute('height');
svg.style.width = '100%';
svg.style.height = 'auto';
svg.style.maxWidth = '100%';
svg.style.sdisplay = 'block';
if ("False" === "True") {
setTimeout(() => {
const g = svg.querySelector('g');
if (g) {
var svgD3 = d3.select(svg);
svgD3.html("<g class='wrapper'>" + svgD3.html() + "</g>");
var inner = svgD3.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svgD3.call(zoom);
}
}, 100);
}
}
modal.classList.add('active');
document.body.style.overflow = 'hidden';
});
container.appendChild(fullscreenBtn);
});
};
const load = async () => {
initStyles();
await runMermaid(true);
const reRunIfThemeChanges = async () => {
const newDarkTheme = isDarkTheme();
if (newDarkTheme !== darkTheme) {
darkTheme = newDarkTheme;
console.log("Theme change detected, re-running mermaid with", darkTheme ? "dark" : "default", "theme");
await mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
await runMermaid(true);
}
};
// Update theme classes when theme changes
const themeObserver = new MutationObserver(reRunIfThemeChanges);
themeObserver.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
themeObserver.observe(document.body, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
};
console.log("Initializing mermaid with", darkTheme ? "dark" : "default", "theme");
mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
window.addEventListener("load", load);
window.runMermaid = runMermaid;</script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="reset_corsie.py" href="reset_corsie_flow.html" />
<link rel="prev" title="main.py" href="main_flow.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="layout-window-py">
<h1><code class="docutils literal notranslate"><span class="pre">layout_window.py</span></code><a class="headerlink" href="#layout-window-py" title="Link to this heading"></a></h1>
<section id="scopo">
<h2>Scopo<a class="headerlink" href="#scopo" title="Link to this heading"></a></h2>
<p>Questo modulo visualizza il layout delle corsie come matrice di celle, mostra
lo stato di occupazione, consente di cercare una UDC e permette lexport della
matrice.</p>
</section>
<section id="flusso-operativo">
<h2>Flusso operativo<a class="headerlink" href="#flusso-operativo" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart TD
A[&quot;open_layout_window()&quot;] --&gt; B[&quot;Crea o riporta in primo piano LayoutWindow&quot;]
B --&gt; C[&quot;LayoutWindow.__init__()&quot;]
C --&gt; D[&quot;Costruisce toolbar, host matrice, statistiche&quot;]
D --&gt; E[&quot;_load_corsie()&quot;]
E --&gt; F[&quot;AsyncRunner.run(query_json SQL corsie)&quot;]
F --&gt; G[&quot;_on_select() sulla corsia iniziale&quot;]
G --&gt; H[&quot;_load_matrix(corsia)&quot;]
H --&gt; I[&quot;AsyncRunner.run(query_json SQL matrice)&quot;]
I --&gt; J[&quot;_rebuild_matrix()&quot;]
J --&gt; K[&quot;_refresh_stats()&quot;]
</pre></section>
<section id="ricerca-udc">
<h2>Ricerca UDC<a class="headerlink" href="#ricerca-udc" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart TD
A[&quot;Utente inserisce barcode&quot;] --&gt; B[&quot;_search_udc()&quot;]
B --&gt; C[&quot;query_json ricerca pallet -&gt; corsia/colonna/fila&quot;]
C --&gt; D{&quot;UDC trovata?&quot;}
D -- No --&gt; E[&quot;Messaggio informativo&quot;]
D -- Si --&gt; F[&quot;Seleziona corsia in listbox&quot;]
F --&gt; G[&quot;_load_matrix(corsia)&quot;]
G --&gt; H[&quot;_rebuild_matrix()&quot;]
H --&gt; I[&quot;_highlight_cell_by_labels()&quot;]
</pre></section>
<section id="schema-di-chiamata-essenziale">
<h2>Schema di chiamata essenziale<a class="headerlink" href="#schema-di-chiamata-essenziale" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart LR
Init[&quot;__init__&quot;] --&gt; Top[&quot;_build_top&quot;]
Init --&gt; Host[&quot;_build_matrix_host&quot;]
Init --&gt; Stats[&quot;_build_stats&quot;]
Init --&gt; LoadCorsie[&quot;_load_corsie&quot;]
LoadCorsie --&gt; Select[&quot;_on_select&quot;]
Select --&gt; LoadMatrix[&quot;_load_matrix&quot;]
LoadMatrix --&gt; Rebuild[&quot;_rebuild_matrix&quot;]
Rebuild --&gt; RefreshStats[&quot;_refresh_stats&quot;]
Search[&quot;_search_udc&quot;] --&gt; LoadMatrix
Export[&quot;_export_xlsx&quot;] --&gt; MatrixState[&quot;matrix_state / fila_txt / col_txt / udc1&quot;]
</pre></section>
<section id="note">
<h2>Note<a class="headerlink" href="#note" title="Link to this heading"></a></h2>
<ul class="simple">
<li><p>Il modulo usa un token <code class="docutils literal notranslate"><span class="pre">_req_counter</span></code> per evitare che risposte async vecchie
aggiornino la UI fuori ordine.</p></li>
<li><p>La statistica globale viene ricalcolata da query SQL, mentre quella della
corsia corrente usa la matrice già caricata in memoria.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">destroy()</span></code> marca la finestra come non più attiva per evitare callback tardive.</p></li>
</ul>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">warehouse</a></h1>
<search id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Search"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../architecture.html">Architettura Complessiva</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api_reference.html">Riferimento API</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Flow Diagrams</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="README.html">Flow Diagrams</a></li>
<li class="toctree-l2"><a class="reference internal" href="main_flow.html"><code class="docutils literal notranslate"><span class="pre">main.py</span></code></a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#"><code class="docutils literal notranslate"><span class="pre">layout_window.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="reset_corsie_flow.html"><code class="docutils literal notranslate"><span class="pre">reset_corsie.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="view_celle_multiple_flow.html"><code class="docutils literal notranslate"><span class="pre">view_celle_multiple.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="search_pallets_flow.html"><code class="docutils literal notranslate"><span class="pre">search_pallets.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_pickinglist_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_pickinglist.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_db_flow.html">Infrastruttura Async / DB</a></li>
<li class="toctree-l2"><a class="reference internal" href="async_msssql_query_flow.html"><code class="docutils literal notranslate"><span class="pre">async_msssql_query.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_aree_frame_async_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_aree_frame_async.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_loop_singleton_flow.html"><code class="docutils literal notranslate"><span class="pre">async_loop_singleton.py</span></code></a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
<li><a href="index.html">Flow Diagrams</a><ul>
<li>Previous: <a href="main_flow.html" title="previous chapter"><code class="docutils literal notranslate"><span class="pre">main.py</span></code></a></li>
<li>Next: <a href="reset_corsie_flow.html" title="next chapter"><code class="docutils literal notranslate"><span class="pre">reset_corsie.py</span></code></a></li>
</ul></li>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 9.1.0</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 1.0.0</a>
|
<a href="../_sources/flows/layout_window_flow.md.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

605
docs/_build/html/flows/main_flow.html vendored Normal file
View File

@@ -0,0 +1,605 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>main.py &#8212; warehouse 0.0.1 documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=5ecbeea2" />
<link rel="stylesheet" type="text/css" href="../_static/basic.css?v=b08954a9" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=27fed22d" />
<script src="../_static/documentation_options.js?v=d45e8c67"></script>
<script src="../_static/doctools.js?v=fd6eb6e6"></script>
<script src="../_static/sphinx_highlight.js?v=6ffebe34"></script>
<script src="https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js"></script>
<script type="module">import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11.12.1/dist/mermaid.esm.min.mjs";
const initStyles = () => {
const defaultStyle = document.createElement('style');
defaultStyle.textContent = `pre.mermaid {
/* Same as .mermaid-container > pre */
display: block;
width: 100%;
}
pre.mermaid > svg {
/* Same as .mermaid-container > pre > svg */
height: 500px;
width: 100%;
max-width: 100% !important;
}`;
document.head.appendChild(defaultStyle);
const fullscreenStyle = document.createElement('style');
fullscreenStyle.textContent = `.mermaid-container {
display: flex;
flex-direction: row;
width: 100%;
}
.mermaid-container > pre {
display: block;
width: 100%;
}
.mermaid-container > pre > svg {
height: 500px;
width: 100%;
max-width: 100% !important;
}
.mermaid-fullscreen-btn {
width: 28px;
height: 28px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
font-size: 14px;
line-height: 1;
padding: 0;
color: #333;
}
.mermaid-fullscreen-btn:hover {
opacity: 100% !important;
background: rgba(255, 255, 255, 1);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
transform: scale(1.1);
}
.mermaid-fullscreen-btn.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.3);
color: #e0e0e0;
}
.mermaid-fullscreen-btn.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 3px 10px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal {
display: none;
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 95vw;
height: 100vh;
background: rgba(255, 255, 255, 0.98);
z-index: 9999;
padding: 20px;
overflow: auto;
}
.mermaid-fullscreen-modal.dark-theme {
background: rgba(0, 0, 0, 0.98);
}
.mermaid-fullscreen-modal.active {
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen {
position: relative;
width: 95vw;
height: 90vh;
max-width: 95vw;
max-height: 90vh;
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
overflow: auto;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen.dark-theme {
background: #1a1a1a;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);
}
.mermaid-container-fullscreen pre.mermaid {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen .mermaid svg {
height: 100% !important;
width: 100% !important;
cursor: grab;
}
.mermaid-fullscreen-close {
position: fixed !important;
top: 20px !important;
right: 20px !important;
width: 40px;
height: 40px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 50%;
cursor: pointer;
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
transition: all 0.2s;
font-size: 24px;
line-height: 1;
color: #333;
}
.mermaid-fullscreen-close:hover {
background: white;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
transform: scale(1.1);
}
.mermaid-fullscreen-close.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.2);
color: #e0e0e0;
}
.mermaid-fullscreen-close.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 6px 16px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal .mermaid-fullscreen-btn {
display: none !important;
}`;
document.head.appendChild(fullscreenStyle);
}
// Detect if page has dark background
const isDarkTheme = () => {
// We use a set of heuristics:
// 1. Check for common dark mode classes or attributes
// 2. Check computed background color brightness
if (document.documentElement.classList.contains('dark') ||
document.documentElement.getAttribute('data-theme') === 'dark' ||
document.body.classList.contains('dark') ||
document.body.getAttribute('data-theme') === 'dark') {
// console.log("Dark theme detected via class/attribute");
return true;
}
if (document.documentElement.classList.contains('light') ||
document.documentElement.getAttribute('data-theme') === 'light' ||
document.body.classList.contains('light') ||
document.body.getAttribute('data-theme') === 'light') {
// console.log("Light theme detected via class/attribute");
return false;
}
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
// console.log("Dark theme detected via prefers-color-scheme");
return true;
}
const bgColor = window.getComputedStyle(document.body).backgroundColor;
const match = bgColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)/);
if (match) {
const r = parseInt(match[1]);
const g = parseInt(match[2]);
const b = parseInt(match[3]);
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
// console.log("Background color brightness:", brightness);
return brightness < 128;
}
// console.log("No dark or light theme detected, defaulting to light theme");
return false;
};
let darkTheme = isDarkTheme();
let modal = null;
let modalContent = null;
let previousScrollOffset = [window.scrollX, window.scrollY];
const runMermaid = async (rerun) => {
console.log("Running mermaid diagrams, rerun =", rerun);
// clear all existing mermaid charts
let all_mermaids = document.querySelectorAll(".mermaid");
if (rerun) {
all_mermaids.forEach((el) => {
if(!el.hasAttribute("data-original-code")) {
// store original code
// console.log(`Storing original code for first run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
if(el.getAttribute("data-processed") === "true") {
// remove and restore original
el.removeAttribute("data-processed");
// console.log(`Restoring original code for re-run: `, el.getAttribute('data-original-code'));
el.innerHTML = el.getAttribute('data-original-code');
} else {
// store original code
// console.log(`Storing original code for re-run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
});
await mermaid.run();
}
all_mermaids = document.querySelectorAll(".mermaid");
const mermaids_processed = document.querySelectorAll(".mermaid[data-processed='true']");
if ("False" === "True") {
const mermaids_to_add_zoom = -1 === -1 ? all_mermaids.length : -1;
if(mermaids_to_add_zoom > 0) {
var svgs = d3.selectAll("");
if(all_mermaids.length !== mermaids_processed.length) {
setTimeout(() => runMermaid(false), 200);
return;
} else if(svgs.size() !== mermaids_to_add_zoom) {
setTimeout(() => runMermaid(false), 200);
return;
} else {
svgs.each(function() {
var svg = d3.select(this);
svg.html("<g class='wrapper'>" + svg.html() + "</g>");
var inner = svg.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svg.call(zoom);
});
}
}
} else if(all_mermaids.length !== mermaids_processed.length) {
// Wait for mermaid to process all diagrams
setTimeout(() => runMermaid(false), 200);
return;
}
// Stop here if not adding fullscreen capability
if ("True" !== "True") return;
if (modal !== null ) {
// Destroy existing modal
modal.remove();
modal = null;
modalContent = null;
}
modal = document.createElement('div');
modal.className = 'mermaid-fullscreen-modal' + (darkTheme ? ' dark-theme' : '');
modal.setAttribute('role', 'dialog');
modal.setAttribute('aria-modal', 'true');
modal.setAttribute('aria-label', 'Fullscreen diagram viewer');
modal.innerHTML = `
<button class="mermaid-fullscreen-close${darkTheme ? ' dark-theme' : ''}" aria-label="Close fullscreen">✕</button>
<div class="mermaid-container-fullscreen${darkTheme ? ' dark-theme' : ''}"></div>
`;
document.body.appendChild(modal);
modalContent = modal.querySelector('.mermaid-container-fullscreen');
const closeBtn = modal.querySelector('.mermaid-fullscreen-close');
const closeModal = () => {
modal.classList.remove('active');
modalContent.innerHTML = '';
document.body.style.overflow = ''
window.scrollTo({left: previousScrollOffset[0], top: previousScrollOffset[1], behavior: 'instant'});
};
closeBtn.addEventListener('click', closeModal);
modal.addEventListener('click', (e) => {
if (e.target === modal) closeModal();
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && modal.classList.contains('active')) {
closeModal();
}
});
document.querySelectorAll('.mermaid').forEach((mermaidDiv) => {
if (mermaidDiv.parentNode.classList.contains('mermaid-container') ||
mermaidDiv.closest('.mermaid-fullscreen-modal')) {
// Already processed, adjust button class if needed
const existingBtn = mermaidDiv.parentNode.querySelector('.mermaid-fullscreen-btn');
if (existingBtn) {
existingBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
}
return;
}
const container = document.createElement('div');
container.className = 'mermaid-container';
mermaidDiv.parentNode.insertBefore(container, mermaidDiv);
container.appendChild(mermaidDiv);
const fullscreenBtn = document.createElement('button');
fullscreenBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
fullscreenBtn.setAttribute('aria-label', 'View diagram in fullscreen');
fullscreenBtn.textContent = '⛶';
fullscreenBtn.style.opacity = '50%';
// Calculate dynamic position based on diagram's margin and padding
const diagramStyle = window.getComputedStyle(mermaidDiv);
const marginTop = parseFloat(diagramStyle.marginTop) || 0;
const marginRight = parseFloat(diagramStyle.marginRight) || 0;
const paddingTop = parseFloat(diagramStyle.paddingTop) || 0;
const paddingRight = parseFloat(diagramStyle.paddingRight) || 0;
fullscreenBtn.style.top = `${marginTop + paddingTop + 4}px`;
fullscreenBtn.style.right = `${marginRight + paddingRight + 4}px`;
fullscreenBtn.addEventListener('click', () => {
previousScrollOffset = [window.scroll, window.scrollY];
const clone = mermaidDiv.cloneNode(true);
modalContent.innerHTML = '';
modalContent.appendChild(clone);
const svg = clone.querySelector('svg');
if (svg) {
svg.removeAttribute('width');
svg.removeAttribute('height');
svg.style.width = '100%';
svg.style.height = 'auto';
svg.style.maxWidth = '100%';
svg.style.sdisplay = 'block';
if ("False" === "True") {
setTimeout(() => {
const g = svg.querySelector('g');
if (g) {
var svgD3 = d3.select(svg);
svgD3.html("<g class='wrapper'>" + svgD3.html() + "</g>");
var inner = svgD3.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svgD3.call(zoom);
}
}, 100);
}
}
modal.classList.add('active');
document.body.style.overflow = 'hidden';
});
container.appendChild(fullscreenBtn);
});
};
const load = async () => {
initStyles();
await runMermaid(true);
const reRunIfThemeChanges = async () => {
const newDarkTheme = isDarkTheme();
if (newDarkTheme !== darkTheme) {
darkTheme = newDarkTheme;
console.log("Theme change detected, re-running mermaid with", darkTheme ? "dark" : "default", "theme");
await mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
await runMermaid(true);
}
};
// Update theme classes when theme changes
const themeObserver = new MutationObserver(reRunIfThemeChanges);
themeObserver.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
themeObserver.observe(document.body, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
};
console.log("Initializing mermaid with", darkTheme ? "dark" : "default", "theme");
mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
window.addEventListener("load", load);
window.runMermaid = runMermaid;</script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="layout_window.py" href="layout_window_flow.html" />
<link rel="prev" title="Flow Diagrams" href="README.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="main-py">
<h1><code class="docutils literal notranslate"><span class="pre">main.py</span></code><a class="headerlink" href="#main-py" title="Link to this heading"></a></h1>
<section id="scopo">
<h2>Scopo<a class="headerlink" href="#scopo" title="Link to this heading"></a></h2>
<p><code class="docutils literal notranslate"><span class="pre">main.py</span></code> è il punto di ingresso dellapplicazione desktop. Inizializza il loop
asincrono condiviso, crea il client database condiviso e costruisce il launcher
con i pulsanti che aprono i moduli operativi.</p>
</section>
<section id="flusso-principale">
<h2>Flusso principale<a class="headerlink" href="#flusso-principale" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart TD
A[&quot;Avvio di main.py&quot;] --&gt; B[&quot;Configura policy asyncio su Windows&quot;]
B --&gt; C[&quot;Ottiene loop globale con get_global_loop()&quot;]
C --&gt; D[&quot;Imposta il loop come default&quot;]
D --&gt; E[&quot;Costruisce DSN SQL Server&quot;]
E --&gt; F[&quot;Crea AsyncMSSQLClient condiviso&quot;]
F --&gt; G[&quot;Istanzia Launcher&quot;]
G --&gt; H[&quot;Mostra finestra principale&quot;]
H --&gt; I{&quot;Click su un pulsante&quot;}
I --&gt; J[&quot;open_reset_corsie_window()&quot;]
I --&gt; K[&quot;open_layout_window()&quot;]
I --&gt; L[&quot;open_celle_multiple_window()&quot;]
I --&gt; M[&quot;open_search_window()&quot;]
I --&gt; N[&quot;open_pickinglist_window()&quot;]
</pre></section>
<section id="schema-di-chiamata">
<h2>Schema di chiamata<a class="headerlink" href="#schema-di-chiamata" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart LR
Launcher[&quot;Launcher.__init__&quot;] --&gt; Reset[&quot;open_reset_corsie_window&quot;]
Launcher --&gt; Layout[&quot;open_layout_window&quot;]
Launcher --&gt; Ghost[&quot;open_celle_multiple_window&quot;]
Launcher --&gt; Search[&quot;open_search_window&quot;]
Launcher --&gt; Pick[&quot;open_pickinglist_window&quot;]
Pick --&gt; PickFactory[&quot;create_pickinglist_frame&quot;]
</pre></section>
<section id="note">
<h2>Note<a class="headerlink" href="#note" title="Link to this heading"></a></h2>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">db_app</span></code> viene creato una sola volta e poi passato a tutte le finestre.</p></li>
<li><p>Alla chiusura del launcher viene chiamato <code class="docutils literal notranslate"><span class="pre">db_app.dispose()</span></code> sul loop globale.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">open_pickinglist_window()</span></code> costruisce la finestra in modo nascosto e la rende
visibile solo a layout pronto, per ridurre lo sfarfallio iniziale.</p></li>
</ul>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">warehouse</a></h1>
<search id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Search"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../architecture.html">Architettura Complessiva</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api_reference.html">Riferimento API</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Flow Diagrams</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="README.html">Flow Diagrams</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#"><code class="docutils literal notranslate"><span class="pre">main.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="layout_window_flow.html"><code class="docutils literal notranslate"><span class="pre">layout_window.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="reset_corsie_flow.html"><code class="docutils literal notranslate"><span class="pre">reset_corsie.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="view_celle_multiple_flow.html"><code class="docutils literal notranslate"><span class="pre">view_celle_multiple.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="search_pallets_flow.html"><code class="docutils literal notranslate"><span class="pre">search_pallets.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_pickinglist_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_pickinglist.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_db_flow.html">Infrastruttura Async / DB</a></li>
<li class="toctree-l2"><a class="reference internal" href="async_msssql_query_flow.html"><code class="docutils literal notranslate"><span class="pre">async_msssql_query.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_aree_frame_async_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_aree_frame_async.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_loop_singleton_flow.html"><code class="docutils literal notranslate"><span class="pre">async_loop_singleton.py</span></code></a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
<li><a href="index.html">Flow Diagrams</a><ul>
<li>Previous: <a href="README.html" title="previous chapter">Flow Diagrams</a></li>
<li>Next: <a href="layout_window_flow.html" title="next chapter"><code class="docutils literal notranslate"><span class="pre">layout_window.py</span></code></a></li>
</ul></li>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 9.1.0</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 1.0.0</a>
|
<a href="../_sources/flows/main_flow.md.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@@ -0,0 +1,605 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>reset_corsie.py &#8212; warehouse 0.0.1 documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=5ecbeea2" />
<link rel="stylesheet" type="text/css" href="../_static/basic.css?v=b08954a9" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=27fed22d" />
<script src="../_static/documentation_options.js?v=d45e8c67"></script>
<script src="../_static/doctools.js?v=fd6eb6e6"></script>
<script src="../_static/sphinx_highlight.js?v=6ffebe34"></script>
<script src="https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js"></script>
<script type="module">import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11.12.1/dist/mermaid.esm.min.mjs";
const initStyles = () => {
const defaultStyle = document.createElement('style');
defaultStyle.textContent = `pre.mermaid {
/* Same as .mermaid-container > pre */
display: block;
width: 100%;
}
pre.mermaid > svg {
/* Same as .mermaid-container > pre > svg */
height: 500px;
width: 100%;
max-width: 100% !important;
}`;
document.head.appendChild(defaultStyle);
const fullscreenStyle = document.createElement('style');
fullscreenStyle.textContent = `.mermaid-container {
display: flex;
flex-direction: row;
width: 100%;
}
.mermaid-container > pre {
display: block;
width: 100%;
}
.mermaid-container > pre > svg {
height: 500px;
width: 100%;
max-width: 100% !important;
}
.mermaid-fullscreen-btn {
width: 28px;
height: 28px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
font-size: 14px;
line-height: 1;
padding: 0;
color: #333;
}
.mermaid-fullscreen-btn:hover {
opacity: 100% !important;
background: rgba(255, 255, 255, 1);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
transform: scale(1.1);
}
.mermaid-fullscreen-btn.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.3);
color: #e0e0e0;
}
.mermaid-fullscreen-btn.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 3px 10px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal {
display: none;
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 95vw;
height: 100vh;
background: rgba(255, 255, 255, 0.98);
z-index: 9999;
padding: 20px;
overflow: auto;
}
.mermaid-fullscreen-modal.dark-theme {
background: rgba(0, 0, 0, 0.98);
}
.mermaid-fullscreen-modal.active {
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen {
position: relative;
width: 95vw;
height: 90vh;
max-width: 95vw;
max-height: 90vh;
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
overflow: auto;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen.dark-theme {
background: #1a1a1a;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);
}
.mermaid-container-fullscreen pre.mermaid {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen .mermaid svg {
height: 100% !important;
width: 100% !important;
cursor: grab;
}
.mermaid-fullscreen-close {
position: fixed !important;
top: 20px !important;
right: 20px !important;
width: 40px;
height: 40px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 50%;
cursor: pointer;
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
transition: all 0.2s;
font-size: 24px;
line-height: 1;
color: #333;
}
.mermaid-fullscreen-close:hover {
background: white;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
transform: scale(1.1);
}
.mermaid-fullscreen-close.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.2);
color: #e0e0e0;
}
.mermaid-fullscreen-close.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 6px 16px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal .mermaid-fullscreen-btn {
display: none !important;
}`;
document.head.appendChild(fullscreenStyle);
}
// Detect if page has dark background
const isDarkTheme = () => {
// We use a set of heuristics:
// 1. Check for common dark mode classes or attributes
// 2. Check computed background color brightness
if (document.documentElement.classList.contains('dark') ||
document.documentElement.getAttribute('data-theme') === 'dark' ||
document.body.classList.contains('dark') ||
document.body.getAttribute('data-theme') === 'dark') {
// console.log("Dark theme detected via class/attribute");
return true;
}
if (document.documentElement.classList.contains('light') ||
document.documentElement.getAttribute('data-theme') === 'light' ||
document.body.classList.contains('light') ||
document.body.getAttribute('data-theme') === 'light') {
// console.log("Light theme detected via class/attribute");
return false;
}
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
// console.log("Dark theme detected via prefers-color-scheme");
return true;
}
const bgColor = window.getComputedStyle(document.body).backgroundColor;
const match = bgColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)/);
if (match) {
const r = parseInt(match[1]);
const g = parseInt(match[2]);
const b = parseInt(match[3]);
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
// console.log("Background color brightness:", brightness);
return brightness < 128;
}
// console.log("No dark or light theme detected, defaulting to light theme");
return false;
};
let darkTheme = isDarkTheme();
let modal = null;
let modalContent = null;
let previousScrollOffset = [window.scrollX, window.scrollY];
const runMermaid = async (rerun) => {
console.log("Running mermaid diagrams, rerun =", rerun);
// clear all existing mermaid charts
let all_mermaids = document.querySelectorAll(".mermaid");
if (rerun) {
all_mermaids.forEach((el) => {
if(!el.hasAttribute("data-original-code")) {
// store original code
// console.log(`Storing original code for first run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
if(el.getAttribute("data-processed") === "true") {
// remove and restore original
el.removeAttribute("data-processed");
// console.log(`Restoring original code for re-run: `, el.getAttribute('data-original-code'));
el.innerHTML = el.getAttribute('data-original-code');
} else {
// store original code
// console.log(`Storing original code for re-run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
});
await mermaid.run();
}
all_mermaids = document.querySelectorAll(".mermaid");
const mermaids_processed = document.querySelectorAll(".mermaid[data-processed='true']");
if ("False" === "True") {
const mermaids_to_add_zoom = -1 === -1 ? all_mermaids.length : -1;
if(mermaids_to_add_zoom > 0) {
var svgs = d3.selectAll("");
if(all_mermaids.length !== mermaids_processed.length) {
setTimeout(() => runMermaid(false), 200);
return;
} else if(svgs.size() !== mermaids_to_add_zoom) {
setTimeout(() => runMermaid(false), 200);
return;
} else {
svgs.each(function() {
var svg = d3.select(this);
svg.html("<g class='wrapper'>" + svg.html() + "</g>");
var inner = svg.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svg.call(zoom);
});
}
}
} else if(all_mermaids.length !== mermaids_processed.length) {
// Wait for mermaid to process all diagrams
setTimeout(() => runMermaid(false), 200);
return;
}
// Stop here if not adding fullscreen capability
if ("True" !== "True") return;
if (modal !== null ) {
// Destroy existing modal
modal.remove();
modal = null;
modalContent = null;
}
modal = document.createElement('div');
modal.className = 'mermaid-fullscreen-modal' + (darkTheme ? ' dark-theme' : '');
modal.setAttribute('role', 'dialog');
modal.setAttribute('aria-modal', 'true');
modal.setAttribute('aria-label', 'Fullscreen diagram viewer');
modal.innerHTML = `
<button class="mermaid-fullscreen-close${darkTheme ? ' dark-theme' : ''}" aria-label="Close fullscreen">✕</button>
<div class="mermaid-container-fullscreen${darkTheme ? ' dark-theme' : ''}"></div>
`;
document.body.appendChild(modal);
modalContent = modal.querySelector('.mermaid-container-fullscreen');
const closeBtn = modal.querySelector('.mermaid-fullscreen-close');
const closeModal = () => {
modal.classList.remove('active');
modalContent.innerHTML = '';
document.body.style.overflow = ''
window.scrollTo({left: previousScrollOffset[0], top: previousScrollOffset[1], behavior: 'instant'});
};
closeBtn.addEventListener('click', closeModal);
modal.addEventListener('click', (e) => {
if (e.target === modal) closeModal();
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && modal.classList.contains('active')) {
closeModal();
}
});
document.querySelectorAll('.mermaid').forEach((mermaidDiv) => {
if (mermaidDiv.parentNode.classList.contains('mermaid-container') ||
mermaidDiv.closest('.mermaid-fullscreen-modal')) {
// Already processed, adjust button class if needed
const existingBtn = mermaidDiv.parentNode.querySelector('.mermaid-fullscreen-btn');
if (existingBtn) {
existingBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
}
return;
}
const container = document.createElement('div');
container.className = 'mermaid-container';
mermaidDiv.parentNode.insertBefore(container, mermaidDiv);
container.appendChild(mermaidDiv);
const fullscreenBtn = document.createElement('button');
fullscreenBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
fullscreenBtn.setAttribute('aria-label', 'View diagram in fullscreen');
fullscreenBtn.textContent = '⛶';
fullscreenBtn.style.opacity = '50%';
// Calculate dynamic position based on diagram's margin and padding
const diagramStyle = window.getComputedStyle(mermaidDiv);
const marginTop = parseFloat(diagramStyle.marginTop) || 0;
const marginRight = parseFloat(diagramStyle.marginRight) || 0;
const paddingTop = parseFloat(diagramStyle.paddingTop) || 0;
const paddingRight = parseFloat(diagramStyle.paddingRight) || 0;
fullscreenBtn.style.top = `${marginTop + paddingTop + 4}px`;
fullscreenBtn.style.right = `${marginRight + paddingRight + 4}px`;
fullscreenBtn.addEventListener('click', () => {
previousScrollOffset = [window.scroll, window.scrollY];
const clone = mermaidDiv.cloneNode(true);
modalContent.innerHTML = '';
modalContent.appendChild(clone);
const svg = clone.querySelector('svg');
if (svg) {
svg.removeAttribute('width');
svg.removeAttribute('height');
svg.style.width = '100%';
svg.style.height = 'auto';
svg.style.maxWidth = '100%';
svg.style.sdisplay = 'block';
if ("False" === "True") {
setTimeout(() => {
const g = svg.querySelector('g');
if (g) {
var svgD3 = d3.select(svg);
svgD3.html("<g class='wrapper'>" + svgD3.html() + "</g>");
var inner = svgD3.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svgD3.call(zoom);
}
}, 100);
}
}
modal.classList.add('active');
document.body.style.overflow = 'hidden';
});
container.appendChild(fullscreenBtn);
});
};
const load = async () => {
initStyles();
await runMermaid(true);
const reRunIfThemeChanges = async () => {
const newDarkTheme = isDarkTheme();
if (newDarkTheme !== darkTheme) {
darkTheme = newDarkTheme;
console.log("Theme change detected, re-running mermaid with", darkTheme ? "dark" : "default", "theme");
await mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
await runMermaid(true);
}
};
// Update theme classes when theme changes
const themeObserver = new MutationObserver(reRunIfThemeChanges);
themeObserver.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
themeObserver.observe(document.body, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
};
console.log("Initializing mermaid with", darkTheme ? "dark" : "default", "theme");
mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
window.addEventListener("load", load);
window.runMermaid = runMermaid;</script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="view_celle_multiple.py" href="view_celle_multiple_flow.html" />
<link rel="prev" title="layout_window.py" href="layout_window_flow.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="reset-corsie-py">
<h1><code class="docutils literal notranslate"><span class="pre">reset_corsie.py</span></code><a class="headerlink" href="#reset-corsie-py" title="Link to this heading"></a></h1>
<section id="scopo">
<h2>Scopo<a class="headerlink" href="#scopo" title="Link to this heading"></a></h2>
<p>Questo modulo mostra il riepilogo di una corsia e permette, dopo doppia
conferma, di cancellare i record di <code class="docutils literal notranslate"><span class="pre">MagazziniPallet</span></code> collegati a quella corsia.</p>
</section>
<section id="flusso-operativo">
<h2>Flusso operativo<a class="headerlink" href="#flusso-operativo" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart TD
A[&quot;open_reset_corsie_window()&quot;] --&gt; B[&quot;ResetCorsieWindow.__init__()&quot;]
B --&gt; C[&quot;_build_ui()&quot;]
C --&gt; D[&quot;_load_corsie()&quot;]
D --&gt; E[&quot;query_json SQL_CORSIE&quot;]
E --&gt; F[&quot;Seleziona corsia iniziale&quot;]
F --&gt; G[&quot;refresh()&quot;]
G --&gt; H[&quot;query_json SQL_RIEPILOGO&quot;]
G --&gt; I[&quot;query_json SQL_DETTAGLIO&quot;]
H --&gt; J[&quot;Aggiorna contatori&quot;]
I --&gt; K[&quot;Aggiorna tree celle occupate&quot;]
</pre></section>
<section id="flusso-distruttivo">
<h2>Flusso distruttivo<a class="headerlink" href="#flusso-distruttivo" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart TD
A[&quot;Click su Svuota corsia&quot;] --&gt; B[&quot;_ask_reset()&quot;]
B --&gt; C[&quot;query_json SQL_COUNT_DELETE&quot;]
C --&gt; D{&quot;Record da cancellare &gt; 0?&quot;}
D -- No --&gt; E[&quot;Messaggio: niente da rimuovere&quot;]
D -- Si --&gt; F[&quot;Richiesta conferma testuale&quot;]
F --&gt; G{&quot;Testo corretto?&quot;}
G -- No --&gt; H[&quot;Annulla operazione&quot;]
G -- Si --&gt; I[&quot;_do_reset(corsia)&quot;]
I --&gt; J[&quot;query_json SQL_DELETE&quot;]
J --&gt; K[&quot;Messaggio completato&quot;]
K --&gt; L[&quot;refresh()&quot;]
</pre></section>
<section id="note">
<h2>Note<a class="headerlink" href="#note" title="Link to this heading"></a></h2>
<ul class="simple">
<li><p>È il modulo più delicato lato operazioni, perché esegue <code class="docutils literal notranslate"><span class="pre">DELETE</span></code>.</p></li>
<li><p>La finestra separa chiaramente fase di ispezione e fase distruttiva.</p></li>
<li><p>Tutte le query passano dal client condiviso tramite <code class="docutils literal notranslate"><span class="pre">AsyncRunner</span></code>.</p></li>
</ul>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">warehouse</a></h1>
<search id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Search"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../architecture.html">Architettura Complessiva</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api_reference.html">Riferimento API</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Flow Diagrams</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="README.html">Flow Diagrams</a></li>
<li class="toctree-l2"><a class="reference internal" href="main_flow.html"><code class="docutils literal notranslate"><span class="pre">main.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="layout_window_flow.html"><code class="docutils literal notranslate"><span class="pre">layout_window.py</span></code></a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#"><code class="docutils literal notranslate"><span class="pre">reset_corsie.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="view_celle_multiple_flow.html"><code class="docutils literal notranslate"><span class="pre">view_celle_multiple.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="search_pallets_flow.html"><code class="docutils literal notranslate"><span class="pre">search_pallets.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_pickinglist_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_pickinglist.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_db_flow.html">Infrastruttura Async / DB</a></li>
<li class="toctree-l2"><a class="reference internal" href="async_msssql_query_flow.html"><code class="docutils literal notranslate"><span class="pre">async_msssql_query.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_aree_frame_async_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_aree_frame_async.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_loop_singleton_flow.html"><code class="docutils literal notranslate"><span class="pre">async_loop_singleton.py</span></code></a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
<li><a href="index.html">Flow Diagrams</a><ul>
<li>Previous: <a href="layout_window_flow.html" title="previous chapter"><code class="docutils literal notranslate"><span class="pre">layout_window.py</span></code></a></li>
<li>Next: <a href="view_celle_multiple_flow.html" title="next chapter"><code class="docutils literal notranslate"><span class="pre">view_celle_multiple.py</span></code></a></li>
</ul></li>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 9.1.0</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 1.0.0</a>
|
<a href="../_sources/flows/reset_corsie_flow.md.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@@ -0,0 +1,603 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>search_pallets.py &#8212; warehouse 0.0.1 documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=5ecbeea2" />
<link rel="stylesheet" type="text/css" href="../_static/basic.css?v=b08954a9" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=27fed22d" />
<script src="../_static/documentation_options.js?v=d45e8c67"></script>
<script src="../_static/doctools.js?v=fd6eb6e6"></script>
<script src="../_static/sphinx_highlight.js?v=6ffebe34"></script>
<script src="https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js"></script>
<script type="module">import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11.12.1/dist/mermaid.esm.min.mjs";
const initStyles = () => {
const defaultStyle = document.createElement('style');
defaultStyle.textContent = `pre.mermaid {
/* Same as .mermaid-container > pre */
display: block;
width: 100%;
}
pre.mermaid > svg {
/* Same as .mermaid-container > pre > svg */
height: 500px;
width: 100%;
max-width: 100% !important;
}`;
document.head.appendChild(defaultStyle);
const fullscreenStyle = document.createElement('style');
fullscreenStyle.textContent = `.mermaid-container {
display: flex;
flex-direction: row;
width: 100%;
}
.mermaid-container > pre {
display: block;
width: 100%;
}
.mermaid-container > pre > svg {
height: 500px;
width: 100%;
max-width: 100% !important;
}
.mermaid-fullscreen-btn {
width: 28px;
height: 28px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
font-size: 14px;
line-height: 1;
padding: 0;
color: #333;
}
.mermaid-fullscreen-btn:hover {
opacity: 100% !important;
background: rgba(255, 255, 255, 1);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
transform: scale(1.1);
}
.mermaid-fullscreen-btn.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.3);
color: #e0e0e0;
}
.mermaid-fullscreen-btn.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 3px 10px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal {
display: none;
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 95vw;
height: 100vh;
background: rgba(255, 255, 255, 0.98);
z-index: 9999;
padding: 20px;
overflow: auto;
}
.mermaid-fullscreen-modal.dark-theme {
background: rgba(0, 0, 0, 0.98);
}
.mermaid-fullscreen-modal.active {
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen {
position: relative;
width: 95vw;
height: 90vh;
max-width: 95vw;
max-height: 90vh;
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
overflow: auto;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen.dark-theme {
background: #1a1a1a;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);
}
.mermaid-container-fullscreen pre.mermaid {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen .mermaid svg {
height: 100% !important;
width: 100% !important;
cursor: grab;
}
.mermaid-fullscreen-close {
position: fixed !important;
top: 20px !important;
right: 20px !important;
width: 40px;
height: 40px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 50%;
cursor: pointer;
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
transition: all 0.2s;
font-size: 24px;
line-height: 1;
color: #333;
}
.mermaid-fullscreen-close:hover {
background: white;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
transform: scale(1.1);
}
.mermaid-fullscreen-close.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.2);
color: #e0e0e0;
}
.mermaid-fullscreen-close.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 6px 16px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal .mermaid-fullscreen-btn {
display: none !important;
}`;
document.head.appendChild(fullscreenStyle);
}
// Detect if page has dark background
const isDarkTheme = () => {
// We use a set of heuristics:
// 1. Check for common dark mode classes or attributes
// 2. Check computed background color brightness
if (document.documentElement.classList.contains('dark') ||
document.documentElement.getAttribute('data-theme') === 'dark' ||
document.body.classList.contains('dark') ||
document.body.getAttribute('data-theme') === 'dark') {
// console.log("Dark theme detected via class/attribute");
return true;
}
if (document.documentElement.classList.contains('light') ||
document.documentElement.getAttribute('data-theme') === 'light' ||
document.body.classList.contains('light') ||
document.body.getAttribute('data-theme') === 'light') {
// console.log("Light theme detected via class/attribute");
return false;
}
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
// console.log("Dark theme detected via prefers-color-scheme");
return true;
}
const bgColor = window.getComputedStyle(document.body).backgroundColor;
const match = bgColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)/);
if (match) {
const r = parseInt(match[1]);
const g = parseInt(match[2]);
const b = parseInt(match[3]);
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
// console.log("Background color brightness:", brightness);
return brightness < 128;
}
// console.log("No dark or light theme detected, defaulting to light theme");
return false;
};
let darkTheme = isDarkTheme();
let modal = null;
let modalContent = null;
let previousScrollOffset = [window.scrollX, window.scrollY];
const runMermaid = async (rerun) => {
console.log("Running mermaid diagrams, rerun =", rerun);
// clear all existing mermaid charts
let all_mermaids = document.querySelectorAll(".mermaid");
if (rerun) {
all_mermaids.forEach((el) => {
if(!el.hasAttribute("data-original-code")) {
// store original code
// console.log(`Storing original code for first run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
if(el.getAttribute("data-processed") === "true") {
// remove and restore original
el.removeAttribute("data-processed");
// console.log(`Restoring original code for re-run: `, el.getAttribute('data-original-code'));
el.innerHTML = el.getAttribute('data-original-code');
} else {
// store original code
// console.log(`Storing original code for re-run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
});
await mermaid.run();
}
all_mermaids = document.querySelectorAll(".mermaid");
const mermaids_processed = document.querySelectorAll(".mermaid[data-processed='true']");
if ("False" === "True") {
const mermaids_to_add_zoom = -1 === -1 ? all_mermaids.length : -1;
if(mermaids_to_add_zoom > 0) {
var svgs = d3.selectAll("");
if(all_mermaids.length !== mermaids_processed.length) {
setTimeout(() => runMermaid(false), 200);
return;
} else if(svgs.size() !== mermaids_to_add_zoom) {
setTimeout(() => runMermaid(false), 200);
return;
} else {
svgs.each(function() {
var svg = d3.select(this);
svg.html("<g class='wrapper'>" + svg.html() + "</g>");
var inner = svg.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svg.call(zoom);
});
}
}
} else if(all_mermaids.length !== mermaids_processed.length) {
// Wait for mermaid to process all diagrams
setTimeout(() => runMermaid(false), 200);
return;
}
// Stop here if not adding fullscreen capability
if ("True" !== "True") return;
if (modal !== null ) {
// Destroy existing modal
modal.remove();
modal = null;
modalContent = null;
}
modal = document.createElement('div');
modal.className = 'mermaid-fullscreen-modal' + (darkTheme ? ' dark-theme' : '');
modal.setAttribute('role', 'dialog');
modal.setAttribute('aria-modal', 'true');
modal.setAttribute('aria-label', 'Fullscreen diagram viewer');
modal.innerHTML = `
<button class="mermaid-fullscreen-close${darkTheme ? ' dark-theme' : ''}" aria-label="Close fullscreen">✕</button>
<div class="mermaid-container-fullscreen${darkTheme ? ' dark-theme' : ''}"></div>
`;
document.body.appendChild(modal);
modalContent = modal.querySelector('.mermaid-container-fullscreen');
const closeBtn = modal.querySelector('.mermaid-fullscreen-close');
const closeModal = () => {
modal.classList.remove('active');
modalContent.innerHTML = '';
document.body.style.overflow = ''
window.scrollTo({left: previousScrollOffset[0], top: previousScrollOffset[1], behavior: 'instant'});
};
closeBtn.addEventListener('click', closeModal);
modal.addEventListener('click', (e) => {
if (e.target === modal) closeModal();
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && modal.classList.contains('active')) {
closeModal();
}
});
document.querySelectorAll('.mermaid').forEach((mermaidDiv) => {
if (mermaidDiv.parentNode.classList.contains('mermaid-container') ||
mermaidDiv.closest('.mermaid-fullscreen-modal')) {
// Already processed, adjust button class if needed
const existingBtn = mermaidDiv.parentNode.querySelector('.mermaid-fullscreen-btn');
if (existingBtn) {
existingBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
}
return;
}
const container = document.createElement('div');
container.className = 'mermaid-container';
mermaidDiv.parentNode.insertBefore(container, mermaidDiv);
container.appendChild(mermaidDiv);
const fullscreenBtn = document.createElement('button');
fullscreenBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
fullscreenBtn.setAttribute('aria-label', 'View diagram in fullscreen');
fullscreenBtn.textContent = '⛶';
fullscreenBtn.style.opacity = '50%';
// Calculate dynamic position based on diagram's margin and padding
const diagramStyle = window.getComputedStyle(mermaidDiv);
const marginTop = parseFloat(diagramStyle.marginTop) || 0;
const marginRight = parseFloat(diagramStyle.marginRight) || 0;
const paddingTop = parseFloat(diagramStyle.paddingTop) || 0;
const paddingRight = parseFloat(diagramStyle.paddingRight) || 0;
fullscreenBtn.style.top = `${marginTop + paddingTop + 4}px`;
fullscreenBtn.style.right = `${marginRight + paddingRight + 4}px`;
fullscreenBtn.addEventListener('click', () => {
previousScrollOffset = [window.scroll, window.scrollY];
const clone = mermaidDiv.cloneNode(true);
modalContent.innerHTML = '';
modalContent.appendChild(clone);
const svg = clone.querySelector('svg');
if (svg) {
svg.removeAttribute('width');
svg.removeAttribute('height');
svg.style.width = '100%';
svg.style.height = 'auto';
svg.style.maxWidth = '100%';
svg.style.sdisplay = 'block';
if ("False" === "True") {
setTimeout(() => {
const g = svg.querySelector('g');
if (g) {
var svgD3 = d3.select(svg);
svgD3.html("<g class='wrapper'>" + svgD3.html() + "</g>");
var inner = svgD3.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svgD3.call(zoom);
}
}, 100);
}
}
modal.classList.add('active');
document.body.style.overflow = 'hidden';
});
container.appendChild(fullscreenBtn);
});
};
const load = async () => {
initStyles();
await runMermaid(true);
const reRunIfThemeChanges = async () => {
const newDarkTheme = isDarkTheme();
if (newDarkTheme !== darkTheme) {
darkTheme = newDarkTheme;
console.log("Theme change detected, re-running mermaid with", darkTheme ? "dark" : "default", "theme");
await mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
await runMermaid(true);
}
};
// Update theme classes when theme changes
const themeObserver = new MutationObserver(reRunIfThemeChanges);
themeObserver.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
themeObserver.observe(document.body, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
};
console.log("Initializing mermaid with", darkTheme ? "dark" : "default", "theme");
mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
window.addEventListener("load", load);
window.runMermaid = runMermaid;</script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="gestione_pickinglist.py" href="gestione_pickinglist_flow.html" />
<link rel="prev" title="view_celle_multiple.py" href="view_celle_multiple_flow.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="search-pallets-py">
<h1><code class="docutils literal notranslate"><span class="pre">search_pallets.py</span></code><a class="headerlink" href="#search-pallets-py" title="Link to this heading"></a></h1>
<section id="scopo">
<h2>Scopo<a class="headerlink" href="#scopo" title="Link to this heading"></a></h2>
<p>Questo modulo consente di cercare pallet/UDC, lotti e codici prodotto su tutto
il magazzino e di esportare i risultati.</p>
</section>
<section id="flusso-operativo">
<h2>Flusso operativo<a class="headerlink" href="#flusso-operativo" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart TD
A[&quot;open_search_window()&quot;] --&gt; B[&quot;SearchWindow.__init__()&quot;]
B --&gt; C[&quot;_build_ui()&quot;]
C --&gt; D[&quot;Utente compila filtri&quot;]
D --&gt; E[&quot;_do_search()&quot;]
E --&gt; F{&quot;Filtri vuoti?&quot;}
F -- Si --&gt; G[&quot;Richiesta conferma ricerca globale&quot;]
F -- No --&gt; H[&quot;Prepara parametri SQL&quot;]
G --&gt; H
H --&gt; I[&quot;AsyncRunner.run(query_json SQL_SEARCH)&quot;]
I --&gt; J[&quot;_ok()&quot;]
J --&gt; K[&quot;Popola Treeview&quot;]
K --&gt; L[&quot;Eventuale reset campi&quot;]
</pre></section>
<section id="ordinamento-ed-export">
<h2>Ordinamento ed export<a class="headerlink" href="#ordinamento-ed-export" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart TD
A[&quot;Doppio click su header&quot;] --&gt; B[&quot;_on_heading_double_click()&quot;]
B --&gt; C[&quot;_sort_by_column()&quot;]
C --&gt; D[&quot;Riordina righe del Treeview&quot;]
E[&quot;Click Export XLSX&quot;] --&gt; F[&quot;_export_xlsx()&quot;]
F --&gt; G[&quot;Legge righe visibili&quot;]
G --&gt; H[&quot;Scrive workbook Excel&quot;]
</pre></section>
<section id="note">
<h2>Note<a class="headerlink" href="#note" title="Link to this heading"></a></h2>
<ul class="simple">
<li><p>Il modulo usa <code class="docutils literal notranslate"><span class="pre">Treeview</span></code> come backend principale.</p></li>
<li><p>Le ricerche possono essere molto ampie: per questo, senza filtri, viene chiesta conferma.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">IDCella</span> <span class="pre">=</span> <span class="pre">9999</span></code> viene evidenziata con uno stile dedicato.</p></li>
</ul>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">warehouse</a></h1>
<search id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Search"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../architecture.html">Architettura Complessiva</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api_reference.html">Riferimento API</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Flow Diagrams</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="README.html">Flow Diagrams</a></li>
<li class="toctree-l2"><a class="reference internal" href="main_flow.html"><code class="docutils literal notranslate"><span class="pre">main.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="layout_window_flow.html"><code class="docutils literal notranslate"><span class="pre">layout_window.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="reset_corsie_flow.html"><code class="docutils literal notranslate"><span class="pre">reset_corsie.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="view_celle_multiple_flow.html"><code class="docutils literal notranslate"><span class="pre">view_celle_multiple.py</span></code></a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#"><code class="docutils literal notranslate"><span class="pre">search_pallets.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_pickinglist_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_pickinglist.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_db_flow.html">Infrastruttura Async / DB</a></li>
<li class="toctree-l2"><a class="reference internal" href="async_msssql_query_flow.html"><code class="docutils literal notranslate"><span class="pre">async_msssql_query.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_aree_frame_async_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_aree_frame_async.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_loop_singleton_flow.html"><code class="docutils literal notranslate"><span class="pre">async_loop_singleton.py</span></code></a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
<li><a href="index.html">Flow Diagrams</a><ul>
<li>Previous: <a href="view_celle_multiple_flow.html" title="previous chapter"><code class="docutils literal notranslate"><span class="pre">view_celle_multiple.py</span></code></a></li>
<li>Next: <a href="gestione_pickinglist_flow.html" title="next chapter"><code class="docutils literal notranslate"><span class="pre">gestione_pickinglist.py</span></code></a></li>
</ul></li>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 9.1.0</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 1.0.0</a>
|
<a href="../_sources/flows/search_pallets_flow.md.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

View File

@@ -0,0 +1,618 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>view_celle_multiple.py &#8212; warehouse 0.0.1 documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=5ecbeea2" />
<link rel="stylesheet" type="text/css" href="../_static/basic.css?v=b08954a9" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=27fed22d" />
<script src="../_static/documentation_options.js?v=d45e8c67"></script>
<script src="../_static/doctools.js?v=fd6eb6e6"></script>
<script src="../_static/sphinx_highlight.js?v=6ffebe34"></script>
<script src="https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js"></script>
<script type="module">import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11.12.1/dist/mermaid.esm.min.mjs";
const initStyles = () => {
const defaultStyle = document.createElement('style');
defaultStyle.textContent = `pre.mermaid {
/* Same as .mermaid-container > pre */
display: block;
width: 100%;
}
pre.mermaid > svg {
/* Same as .mermaid-container > pre > svg */
height: 500px;
width: 100%;
max-width: 100% !important;
}`;
document.head.appendChild(defaultStyle);
const fullscreenStyle = document.createElement('style');
fullscreenStyle.textContent = `.mermaid-container {
display: flex;
flex-direction: row;
width: 100%;
}
.mermaid-container > pre {
display: block;
width: 100%;
}
.mermaid-container > pre > svg {
height: 500px;
width: 100%;
max-width: 100% !important;
}
.mermaid-fullscreen-btn {
width: 28px;
height: 28px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
font-size: 14px;
line-height: 1;
padding: 0;
color: #333;
}
.mermaid-fullscreen-btn:hover {
opacity: 100% !important;
background: rgba(255, 255, 255, 1);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
transform: scale(1.1);
}
.mermaid-fullscreen-btn.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.3);
color: #e0e0e0;
}
.mermaid-fullscreen-btn.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 3px 10px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal {
display: none;
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 95vw;
height: 100vh;
background: rgba(255, 255, 255, 0.98);
z-index: 9999;
padding: 20px;
overflow: auto;
}
.mermaid-fullscreen-modal.dark-theme {
background: rgba(0, 0, 0, 0.98);
}
.mermaid-fullscreen-modal.active {
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen {
position: relative;
width: 95vw;
height: 90vh;
max-width: 95vw;
max-height: 90vh;
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
overflow: auto;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen.dark-theme {
background: #1a1a1a;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);
}
.mermaid-container-fullscreen pre.mermaid {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen .mermaid svg {
height: 100% !important;
width: 100% !important;
cursor: grab;
}
.mermaid-fullscreen-close {
position: fixed !important;
top: 20px !important;
right: 20px !important;
width: 40px;
height: 40px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 50%;
cursor: pointer;
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
transition: all 0.2s;
font-size: 24px;
line-height: 1;
color: #333;
}
.mermaid-fullscreen-close:hover {
background: white;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
transform: scale(1.1);
}
.mermaid-fullscreen-close.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.2);
color: #e0e0e0;
}
.mermaid-fullscreen-close.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 6px 16px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal .mermaid-fullscreen-btn {
display: none !important;
}`;
document.head.appendChild(fullscreenStyle);
}
// Detect if page has dark background
const isDarkTheme = () => {
// We use a set of heuristics:
// 1. Check for common dark mode classes or attributes
// 2. Check computed background color brightness
if (document.documentElement.classList.contains('dark') ||
document.documentElement.getAttribute('data-theme') === 'dark' ||
document.body.classList.contains('dark') ||
document.body.getAttribute('data-theme') === 'dark') {
// console.log("Dark theme detected via class/attribute");
return true;
}
if (document.documentElement.classList.contains('light') ||
document.documentElement.getAttribute('data-theme') === 'light' ||
document.body.classList.contains('light') ||
document.body.getAttribute('data-theme') === 'light') {
// console.log("Light theme detected via class/attribute");
return false;
}
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
// console.log("Dark theme detected via prefers-color-scheme");
return true;
}
const bgColor = window.getComputedStyle(document.body).backgroundColor;
const match = bgColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)/);
if (match) {
const r = parseInt(match[1]);
const g = parseInt(match[2]);
const b = parseInt(match[3]);
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
// console.log("Background color brightness:", brightness);
return brightness < 128;
}
// console.log("No dark or light theme detected, defaulting to light theme");
return false;
};
let darkTheme = isDarkTheme();
let modal = null;
let modalContent = null;
let previousScrollOffset = [window.scrollX, window.scrollY];
const runMermaid = async (rerun) => {
console.log("Running mermaid diagrams, rerun =", rerun);
// clear all existing mermaid charts
let all_mermaids = document.querySelectorAll(".mermaid");
if (rerun) {
all_mermaids.forEach((el) => {
if(!el.hasAttribute("data-original-code")) {
// store original code
// console.log(`Storing original code for first run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
if(el.getAttribute("data-processed") === "true") {
// remove and restore original
el.removeAttribute("data-processed");
// console.log(`Restoring original code for re-run: `, el.getAttribute('data-original-code'));
el.innerHTML = el.getAttribute('data-original-code');
} else {
// store original code
// console.log(`Storing original code for re-run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
});
await mermaid.run();
}
all_mermaids = document.querySelectorAll(".mermaid");
const mermaids_processed = document.querySelectorAll(".mermaid[data-processed='true']");
if ("False" === "True") {
const mermaids_to_add_zoom = -1 === -1 ? all_mermaids.length : -1;
if(mermaids_to_add_zoom > 0) {
var svgs = d3.selectAll("");
if(all_mermaids.length !== mermaids_processed.length) {
setTimeout(() => runMermaid(false), 200);
return;
} else if(svgs.size() !== mermaids_to_add_zoom) {
setTimeout(() => runMermaid(false), 200);
return;
} else {
svgs.each(function() {
var svg = d3.select(this);
svg.html("<g class='wrapper'>" + svg.html() + "</g>");
var inner = svg.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svg.call(zoom);
});
}
}
} else if(all_mermaids.length !== mermaids_processed.length) {
// Wait for mermaid to process all diagrams
setTimeout(() => runMermaid(false), 200);
return;
}
// Stop here if not adding fullscreen capability
if ("True" !== "True") return;
if (modal !== null ) {
// Destroy existing modal
modal.remove();
modal = null;
modalContent = null;
}
modal = document.createElement('div');
modal.className = 'mermaid-fullscreen-modal' + (darkTheme ? ' dark-theme' : '');
modal.setAttribute('role', 'dialog');
modal.setAttribute('aria-modal', 'true');
modal.setAttribute('aria-label', 'Fullscreen diagram viewer');
modal.innerHTML = `
<button class="mermaid-fullscreen-close${darkTheme ? ' dark-theme' : ''}" aria-label="Close fullscreen">✕</button>
<div class="mermaid-container-fullscreen${darkTheme ? ' dark-theme' : ''}"></div>
`;
document.body.appendChild(modal);
modalContent = modal.querySelector('.mermaid-container-fullscreen');
const closeBtn = modal.querySelector('.mermaid-fullscreen-close');
const closeModal = () => {
modal.classList.remove('active');
modalContent.innerHTML = '';
document.body.style.overflow = ''
window.scrollTo({left: previousScrollOffset[0], top: previousScrollOffset[1], behavior: 'instant'});
};
closeBtn.addEventListener('click', closeModal);
modal.addEventListener('click', (e) => {
if (e.target === modal) closeModal();
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && modal.classList.contains('active')) {
closeModal();
}
});
document.querySelectorAll('.mermaid').forEach((mermaidDiv) => {
if (mermaidDiv.parentNode.classList.contains('mermaid-container') ||
mermaidDiv.closest('.mermaid-fullscreen-modal')) {
// Already processed, adjust button class if needed
const existingBtn = mermaidDiv.parentNode.querySelector('.mermaid-fullscreen-btn');
if (existingBtn) {
existingBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
}
return;
}
const container = document.createElement('div');
container.className = 'mermaid-container';
mermaidDiv.parentNode.insertBefore(container, mermaidDiv);
container.appendChild(mermaidDiv);
const fullscreenBtn = document.createElement('button');
fullscreenBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
fullscreenBtn.setAttribute('aria-label', 'View diagram in fullscreen');
fullscreenBtn.textContent = '⛶';
fullscreenBtn.style.opacity = '50%';
// Calculate dynamic position based on diagram's margin and padding
const diagramStyle = window.getComputedStyle(mermaidDiv);
const marginTop = parseFloat(diagramStyle.marginTop) || 0;
const marginRight = parseFloat(diagramStyle.marginRight) || 0;
const paddingTop = parseFloat(diagramStyle.paddingTop) || 0;
const paddingRight = parseFloat(diagramStyle.paddingRight) || 0;
fullscreenBtn.style.top = `${marginTop + paddingTop + 4}px`;
fullscreenBtn.style.right = `${marginRight + paddingRight + 4}px`;
fullscreenBtn.addEventListener('click', () => {
previousScrollOffset = [window.scroll, window.scrollY];
const clone = mermaidDiv.cloneNode(true);
modalContent.innerHTML = '';
modalContent.appendChild(clone);
const svg = clone.querySelector('svg');
if (svg) {
svg.removeAttribute('width');
svg.removeAttribute('height');
svg.style.width = '100%';
svg.style.height = 'auto';
svg.style.maxWidth = '100%';
svg.style.sdisplay = 'block';
if ("False" === "True") {
setTimeout(() => {
const g = svg.querySelector('g');
if (g) {
var svgD3 = d3.select(svg);
svgD3.html("<g class='wrapper'>" + svgD3.html() + "</g>");
var inner = svgD3.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svgD3.call(zoom);
}
}, 100);
}
}
modal.classList.add('active');
document.body.style.overflow = 'hidden';
});
container.appendChild(fullscreenBtn);
});
};
const load = async () => {
initStyles();
await runMermaid(true);
const reRunIfThemeChanges = async () => {
const newDarkTheme = isDarkTheme();
if (newDarkTheme !== darkTheme) {
darkTheme = newDarkTheme;
console.log("Theme change detected, re-running mermaid with", darkTheme ? "dark" : "default", "theme");
await mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
await runMermaid(true);
}
};
// Update theme classes when theme changes
const themeObserver = new MutationObserver(reRunIfThemeChanges);
themeObserver.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
themeObserver.observe(document.body, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
};
console.log("Initializing mermaid with", darkTheme ? "dark" : "default", "theme");
mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
window.addEventListener("load", load);
window.runMermaid = runMermaid;</script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="search_pallets.py" href="search_pallets_flow.html" />
<link rel="prev" title="reset_corsie.py" href="reset_corsie_flow.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="view-celle-multiple-py">
<h1><code class="docutils literal notranslate"><span class="pre">view_celle_multiple.py</span></code><a class="headerlink" href="#view-celle-multiple-py" title="Link to this heading"></a></h1>
<section id="scopo">
<h2>Scopo<a class="headerlink" href="#scopo" title="Link to this heading"></a></h2>
<p>Questo modulo esplora le celle che contengono più pallet del previsto,
organizzando i risultati in un albero:</p>
<ul class="simple">
<li><p>corsia</p></li>
<li><p>cella duplicata</p></li>
<li><p>pallet contenuti nella cella</p></li>
</ul>
</section>
<section id="flusso-operativo">
<h2>Flusso operativo<a class="headerlink" href="#flusso-operativo" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart TD
A[&quot;open_celle_multiple_window()&quot;] --&gt; B[&quot;CelleMultipleWindow.__init__()&quot;]
B --&gt; C[&quot;_build_layout()&quot;]
C --&gt; D[&quot;_bind_events()&quot;]
D --&gt; E[&quot;refresh_all()&quot;]
E --&gt; F[&quot;_load_corsie()&quot;]
E --&gt; G[&quot;_load_riepilogo()&quot;]
F --&gt; H[&quot;query_json SQL_CORSIE&quot;]
G --&gt; I[&quot;query_json SQL_RIEPILOGO_PERCENTUALI&quot;]
H --&gt; J[&quot;_fill_corsie()&quot;]
I --&gt; K[&quot;_fill_riepilogo()&quot;]
</pre></section>
<section id="lazy-loading-dell-albero">
<h2>Lazy loading dellalbero<a class="headerlink" href="#lazy-loading-dell-albero" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart TD
A[&quot;Espansione nodo tree&quot;] --&gt; B[&quot;_on_open_node()&quot;]
B --&gt; C{&quot;Nodo corsia o nodo cella?&quot;}
C -- Corsia --&gt; D[&quot;_load_celle_for_corsia()&quot;]
D --&gt; E[&quot;query_json SQL_CELLE_DUP_PER_CORSIA&quot;]
E --&gt; F[&quot;_fill_celle()&quot;]
C -- Cella --&gt; G[&quot;_load_pallet_for_cella()&quot;]
G --&gt; H[&quot;query_json SQL_PALLET_IN_CELLA&quot;]
H --&gt; I[&quot;_fill_pallet()&quot;]
</pre></section>
<section id="schema-di-chiamata">
<h2>Schema di chiamata<a class="headerlink" href="#schema-di-chiamata" title="Link to this heading"></a></h2>
<pre class="mermaid">
flowchart LR
Refresh[&quot;refresh_all&quot;] --&gt; Corsie[&quot;_load_corsie&quot;]
Refresh --&gt; Riep[&quot;_load_riepilogo&quot;]
Open[&quot;_on_open_node&quot;] --&gt; LoadCelle[&quot;_load_celle_for_corsia&quot;]
Open --&gt; LoadPallet[&quot;_load_pallet_for_cella&quot;]
Export[&quot;export_to_xlsx&quot;] --&gt; Tree[&quot;tree dati dettaglio&quot;]
Export --&gt; Sum[&quot;sum_tbl riepilogo&quot;]
</pre></section>
<section id="note">
<h2>Note<a class="headerlink" href="#note" title="Link to this heading"></a></h2>
<ul class="simple">
<li><p>Lalbero è caricato a richiesta, non tutto in una sola query.</p></li>
<li><p>Questo riduce il costo iniziale e rende il modulo più scalabile.</p></li>
<li><p>Lexport legge sia il dettaglio dellalbero sia la tabella di riepilogo.</p></li>
</ul>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">warehouse</a></h1>
<search id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Search"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../architecture.html">Architettura Complessiva</a></li>
<li class="toctree-l1"><a class="reference internal" href="../api_reference.html">Riferimento API</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Flow Diagrams</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="README.html">Flow Diagrams</a></li>
<li class="toctree-l2"><a class="reference internal" href="main_flow.html"><code class="docutils literal notranslate"><span class="pre">main.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="layout_window_flow.html"><code class="docutils literal notranslate"><span class="pre">layout_window.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="reset_corsie_flow.html"><code class="docutils literal notranslate"><span class="pre">reset_corsie.py</span></code></a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#"><code class="docutils literal notranslate"><span class="pre">view_celle_multiple.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="search_pallets_flow.html"><code class="docutils literal notranslate"><span class="pre">search_pallets.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_pickinglist_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_pickinglist.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_db_flow.html">Infrastruttura Async / DB</a></li>
<li class="toctree-l2"><a class="reference internal" href="async_msssql_query_flow.html"><code class="docutils literal notranslate"><span class="pre">async_msssql_query.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="gestione_aree_frame_async_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_aree_frame_async.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="async_loop_singleton_flow.html"><code class="docutils literal notranslate"><span class="pre">async_loop_singleton.py</span></code></a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
<li><a href="index.html">Flow Diagrams</a><ul>
<li>Previous: <a href="reset_corsie_flow.html" title="previous chapter"><code class="docutils literal notranslate"><span class="pre">reset_corsie.py</span></code></a></li>
<li>Next: <a href="search_pallets_flow.html" title="next chapter"><code class="docutils literal notranslate"><span class="pre">search_pallets.py</span></code></a></li>
</ul></li>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 9.1.0</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 1.0.0</a>
|
<a href="../_sources/flows/view_celle_multiple_flow.md.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

923
docs/_build/html/genindex.html vendored Normal file
View File

@@ -0,0 +1,923 @@
<!DOCTYPE html>
<html lang="en" data-content_root="./">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Index &#8212; warehouse 0.0.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=5ecbeea2" />
<link rel="stylesheet" type="text/css" href="_static/basic.css?v=b08954a9" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=27fed22d" />
<script src="_static/documentation_options.js?v=d45e8c67"></script>
<script src="_static/doctools.js?v=fd6eb6e6"></script>
<script src="_static/sphinx_highlight.js?v=6ffebe34"></script>
<script src="https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js"></script>
<script type="module">import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11.12.1/dist/mermaid.esm.min.mjs";
const initStyles = () => {
const defaultStyle = document.createElement('style');
defaultStyle.textContent = `pre.mermaid {
/* Same as .mermaid-container > pre */
display: block;
width: 100%;
}
pre.mermaid > svg {
/* Same as .mermaid-container > pre > svg */
height: 500px;
width: 100%;
max-width: 100% !important;
}`;
document.head.appendChild(defaultStyle);
const fullscreenStyle = document.createElement('style');
fullscreenStyle.textContent = `.mermaid-container {
display: flex;
flex-direction: row;
width: 100%;
}
.mermaid-container > pre {
display: block;
width: 100%;
}
.mermaid-container > pre > svg {
height: 500px;
width: 100%;
max-width: 100% !important;
}
.mermaid-fullscreen-btn {
width: 28px;
height: 28px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
font-size: 14px;
line-height: 1;
padding: 0;
color: #333;
}
.mermaid-fullscreen-btn:hover {
opacity: 100% !important;
background: rgba(255, 255, 255, 1);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
transform: scale(1.1);
}
.mermaid-fullscreen-btn.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.3);
color: #e0e0e0;
}
.mermaid-fullscreen-btn.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 3px 10px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal {
display: none;
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 95vw;
height: 100vh;
background: rgba(255, 255, 255, 0.98);
z-index: 9999;
padding: 20px;
overflow: auto;
}
.mermaid-fullscreen-modal.dark-theme {
background: rgba(0, 0, 0, 0.98);
}
.mermaid-fullscreen-modal.active {
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen {
position: relative;
width: 95vw;
height: 90vh;
max-width: 95vw;
max-height: 90vh;
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
overflow: auto;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen.dark-theme {
background: #1a1a1a;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);
}
.mermaid-container-fullscreen pre.mermaid {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen .mermaid svg {
height: 100% !important;
width: 100% !important;
cursor: grab;
}
.mermaid-fullscreen-close {
position: fixed !important;
top: 20px !important;
right: 20px !important;
width: 40px;
height: 40px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 50%;
cursor: pointer;
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
transition: all 0.2s;
font-size: 24px;
line-height: 1;
color: #333;
}
.mermaid-fullscreen-close:hover {
background: white;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
transform: scale(1.1);
}
.mermaid-fullscreen-close.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.2);
color: #e0e0e0;
}
.mermaid-fullscreen-close.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 6px 16px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal .mermaid-fullscreen-btn {
display: none !important;
}`;
document.head.appendChild(fullscreenStyle);
}
// Detect if page has dark background
const isDarkTheme = () => {
// We use a set of heuristics:
// 1. Check for common dark mode classes or attributes
// 2. Check computed background color brightness
if (document.documentElement.classList.contains('dark') ||
document.documentElement.getAttribute('data-theme') === 'dark' ||
document.body.classList.contains('dark') ||
document.body.getAttribute('data-theme') === 'dark') {
// console.log("Dark theme detected via class/attribute");
return true;
}
if (document.documentElement.classList.contains('light') ||
document.documentElement.getAttribute('data-theme') === 'light' ||
document.body.classList.contains('light') ||
document.body.getAttribute('data-theme') === 'light') {
// console.log("Light theme detected via class/attribute");
return false;
}
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
// console.log("Dark theme detected via prefers-color-scheme");
return true;
}
const bgColor = window.getComputedStyle(document.body).backgroundColor;
const match = bgColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)/);
if (match) {
const r = parseInt(match[1]);
const g = parseInt(match[2]);
const b = parseInt(match[3]);
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
// console.log("Background color brightness:", brightness);
return brightness < 128;
}
// console.log("No dark or light theme detected, defaulting to light theme");
return false;
};
let darkTheme = isDarkTheme();
let modal = null;
let modalContent = null;
let previousScrollOffset = [window.scrollX, window.scrollY];
const runMermaid = async (rerun) => {
console.log("Running mermaid diagrams, rerun =", rerun);
// clear all existing mermaid charts
let all_mermaids = document.querySelectorAll(".mermaid");
if (rerun) {
all_mermaids.forEach((el) => {
if(!el.hasAttribute("data-original-code")) {
// store original code
// console.log(`Storing original code for first run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
if(el.getAttribute("data-processed") === "true") {
// remove and restore original
el.removeAttribute("data-processed");
// console.log(`Restoring original code for re-run: `, el.getAttribute('data-original-code'));
el.innerHTML = el.getAttribute('data-original-code');
} else {
// store original code
// console.log(`Storing original code for re-run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
});
await mermaid.run();
}
all_mermaids = document.querySelectorAll(".mermaid");
const mermaids_processed = document.querySelectorAll(".mermaid[data-processed='true']");
if ("False" === "True") {
const mermaids_to_add_zoom = -1 === -1 ? all_mermaids.length : -1;
if(mermaids_to_add_zoom > 0) {
var svgs = d3.selectAll("");
if(all_mermaids.length !== mermaids_processed.length) {
setTimeout(() => runMermaid(false), 200);
return;
} else if(svgs.size() !== mermaids_to_add_zoom) {
setTimeout(() => runMermaid(false), 200);
return;
} else {
svgs.each(function() {
var svg = d3.select(this);
svg.html("<g class='wrapper'>" + svg.html() + "</g>");
var inner = svg.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svg.call(zoom);
});
}
}
} else if(all_mermaids.length !== mermaids_processed.length) {
// Wait for mermaid to process all diagrams
setTimeout(() => runMermaid(false), 200);
return;
}
// Stop here if not adding fullscreen capability
if ("True" !== "True") return;
if (modal !== null ) {
// Destroy existing modal
modal.remove();
modal = null;
modalContent = null;
}
modal = document.createElement('div');
modal.className = 'mermaid-fullscreen-modal' + (darkTheme ? ' dark-theme' : '');
modal.setAttribute('role', 'dialog');
modal.setAttribute('aria-modal', 'true');
modal.setAttribute('aria-label', 'Fullscreen diagram viewer');
modal.innerHTML = `
<button class="mermaid-fullscreen-close${darkTheme ? ' dark-theme' : ''}" aria-label="Close fullscreen">✕</button>
<div class="mermaid-container-fullscreen${darkTheme ? ' dark-theme' : ''}"></div>
`;
document.body.appendChild(modal);
modalContent = modal.querySelector('.mermaid-container-fullscreen');
const closeBtn = modal.querySelector('.mermaid-fullscreen-close');
const closeModal = () => {
modal.classList.remove('active');
modalContent.innerHTML = '';
document.body.style.overflow = ''
window.scrollTo({left: previousScrollOffset[0], top: previousScrollOffset[1], behavior: 'instant'});
};
closeBtn.addEventListener('click', closeModal);
modal.addEventListener('click', (e) => {
if (e.target === modal) closeModal();
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && modal.classList.contains('active')) {
closeModal();
}
});
document.querySelectorAll('.mermaid').forEach((mermaidDiv) => {
if (mermaidDiv.parentNode.classList.contains('mermaid-container') ||
mermaidDiv.closest('.mermaid-fullscreen-modal')) {
// Already processed, adjust button class if needed
const existingBtn = mermaidDiv.parentNode.querySelector('.mermaid-fullscreen-btn');
if (existingBtn) {
existingBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
}
return;
}
const container = document.createElement('div');
container.className = 'mermaid-container';
mermaidDiv.parentNode.insertBefore(container, mermaidDiv);
container.appendChild(mermaidDiv);
const fullscreenBtn = document.createElement('button');
fullscreenBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
fullscreenBtn.setAttribute('aria-label', 'View diagram in fullscreen');
fullscreenBtn.textContent = '⛶';
fullscreenBtn.style.opacity = '50%';
// Calculate dynamic position based on diagram's margin and padding
const diagramStyle = window.getComputedStyle(mermaidDiv);
const marginTop = parseFloat(diagramStyle.marginTop) || 0;
const marginRight = parseFloat(diagramStyle.marginRight) || 0;
const paddingTop = parseFloat(diagramStyle.paddingTop) || 0;
const paddingRight = parseFloat(diagramStyle.paddingRight) || 0;
fullscreenBtn.style.top = `${marginTop + paddingTop + 4}px`;
fullscreenBtn.style.right = `${marginRight + paddingRight + 4}px`;
fullscreenBtn.addEventListener('click', () => {
previousScrollOffset = [window.scroll, window.scrollY];
const clone = mermaidDiv.cloneNode(true);
modalContent.innerHTML = '';
modalContent.appendChild(clone);
const svg = clone.querySelector('svg');
if (svg) {
svg.removeAttribute('width');
svg.removeAttribute('height');
svg.style.width = '100%';
svg.style.height = 'auto';
svg.style.maxWidth = '100%';
svg.style.sdisplay = 'block';
if ("False" === "True") {
setTimeout(() => {
const g = svg.querySelector('g');
if (g) {
var svgD3 = d3.select(svg);
svgD3.html("<g class='wrapper'>" + svgD3.html() + "</g>");
var inner = svgD3.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svgD3.call(zoom);
}
}, 100);
}
}
modal.classList.add('active');
document.body.style.overflow = 'hidden';
});
container.appendChild(fullscreenBtn);
});
};
const load = async () => {
initStyles();
await runMermaid(true);
const reRunIfThemeChanges = async () => {
const newDarkTheme = isDarkTheme();
if (newDarkTheme !== darkTheme) {
darkTheme = newDarkTheme;
console.log("Theme change detected, re-running mermaid with", darkTheme ? "dark" : "default", "theme");
await mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
await runMermaid(true);
}
};
// Update theme classes when theme changes
const themeObserver = new MutationObserver(reRunIfThemeChanges);
themeObserver.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
themeObserver.observe(document.body, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
};
console.log("Initializing mermaid with", darkTheme ? "dark" : "default", "theme");
mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
window.addEventListener("load", load);
window.runMermaid = runMermaid;</script>
<link rel="index" title="Index" href="#" />
<link rel="search" title="Search" href="search.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1 id="index">Index</h1>
<div class="genindex-jumpbox">
<a href="#A"><strong>A</strong></a>
| <a href="#B"><strong>B</strong></a>
| <a href="#C"><strong>C</strong></a>
| <a href="#D"><strong>D</strong></a>
| <a href="#E"><strong>E</strong></a>
| <a href="#F"><strong>F</strong></a>
| <a href="#G"><strong>G</strong></a>
| <a href="#H"><strong>H</strong></a>
| <a href="#I"><strong>I</strong></a>
| <a href="#K"><strong>K</strong></a>
| <a href="#L"><strong>L</strong></a>
| <a href="#M"><strong>M</strong></a>
| <a href="#O"><strong>O</strong></a>
| <a href="#P"><strong>P</strong></a>
| <a href="#Q"><strong>Q</strong></a>
| <a href="#R"><strong>R</strong></a>
| <a href="#S"><strong>S</strong></a>
| <a href="#T"><strong>T</strong></a>
| <a href="#V"><strong>V</strong></a>
| <a href="#W"><strong>W</strong></a>
</div>
<h2 id="A">A</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#gestione_pickinglist.ScrollTable.add_row">add_row() (gestione_pickinglist.ScrollTable method)</a>
</li>
<li><a href="api_reference.html#gestione_pickinglist.ColSpec.anchor">anchor (gestione_pickinglist.ColSpec attribute)</a>
</li>
<li>
async_msssql_query
<ul>
<li><a href="api_reference.html#module-async_msssql_query">module</a>
</li>
</ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#async_msssql_query.AsyncMSSQLClient">AsyncMSSQLClient (class in async_msssql_query)</a>
</li>
<li><a href="api_reference.html#gestione_aree_frame_async.AsyncRunner">AsyncRunner (class in gestione_aree_frame_async)</a>
</li>
</ul></td>
</tr></table>
<h2 id="B">B</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#gestione_pickinglist.PLRow.build_checkbox">build_checkbox() (gestione_pickinglist.PLRow method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#gestione_aree_frame_async.BusyOverlay">BusyOverlay (class in gestione_aree_frame_async)</a>
</li>
</ul></td>
</tr></table>
<h2 id="C">C</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#view_celle_multiple.CelleMultipleWindow">CelleMultipleWindow (class in view_celle_multiple)</a>
</li>
<li><a href="api_reference.html#gestione_pickinglist.ScrollTable.clear_rows">clear_rows() (gestione_pickinglist.ScrollTable method)</a>
</li>
<li><a href="api_reference.html#gestione_aree_frame_async.AsyncRunner.close">close() (gestione_aree_frame_async.AsyncRunner method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#view_celle_multiple.CelleMultipleWindow.collapse_all">collapse_all() (view_celle_multiple.CelleMultipleWindow method)</a>
</li>
<li><a href="api_reference.html#gestione_pickinglist.ColSpec">ColSpec (class in gestione_pickinglist)</a>
</li>
<li><a href="api_reference.html#gestione_pickinglist.create_frame">create_frame() (in module gestione_pickinglist)</a>
</li>
</ul></td>
</tr></table>
<h2 id="D">D</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#layout_window.LayoutWindow.destroy">destroy() (layout_window.LayoutWindow method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#async_msssql_query.AsyncMSSQLClient.dispose">dispose() (async_msssql_query.AsyncMSSQLClient method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="E">E</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#async_msssql_query.AsyncMSSQLClient.exec">exec() (async_msssql_query.AsyncMSSQLClient method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#view_celle_multiple.CelleMultipleWindow.expand_all">expand_all() (view_celle_multiple.CelleMultipleWindow method)</a>
</li>
<li><a href="api_reference.html#view_celle_multiple.CelleMultipleWindow.export_to_xlsx">export_to_xlsx() (view_celle_multiple.CelleMultipleWindow method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="F">F</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#gestione_pickinglist.ToolbarSpinner.FRAMES">FRAMES (gestione_pickinglist.ToolbarSpinner attribute)</a>
</li>
</ul></td>
</tr></table>
<h2 id="G">G</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li>
gestione_aree_frame_async
<ul>
<li><a href="api_reference.html#module-gestione_aree_frame_async">module</a>
</li>
</ul></li>
<li>
gestione_pickinglist
<ul>
<li><a href="api_reference.html#module-gestione_pickinglist">module</a>
</li>
</ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#gestione_pickinglist.GestionePickingListFrame">GestionePickingListFrame (class in gestione_pickinglist)</a>
</li>
<li><a href="api_reference.html#gestione_aree_frame_async.get_global_loop">get_global_loop() (in module gestione_aree_frame_async)</a>
</li>
<li><a href="api_reference.html#gestione_pickinglist.ScrollTable.GRID_COLOR">GRID_COLOR (gestione_pickinglist.ScrollTable attribute)</a>
</li>
</ul></td>
</tr></table>
<h2 id="H">H</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#gestione_aree_frame_async.BusyOverlay.hide">hide() (gestione_aree_frame_async.BusyOverlay method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="I">I</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#prenota_sprenota_sql.SPResult.id_result">id_result (prenota_sprenota_sql.SPResult attribute)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#gestione_pickinglist.PLRow.is_checked">is_checked() (gestione_pickinglist.PLRow method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="K">K</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#gestione_pickinglist.ColSpec.key">key (gestione_pickinglist.ColSpec attribute)</a>
</li>
</ul></td>
</tr></table>
<h2 id="L">L</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#main.Launcher">Launcher (class in main)</a>
</li>
<li>
layout_window
<ul>
<li><a href="api_reference.html#module-layout_window">module</a>
</li>
</ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#layout_window.LayoutWindow">LayoutWindow (class in layout_window)</a>
</li>
</ul></td>
</tr></table>
<h2 id="M">M</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li>
main
<ul>
<li><a href="api_reference.html#module-main">module</a>
</li>
</ul></li>
<li><a href="api_reference.html#async_msssql_query.make_mssql_dsn">make_mssql_dsn() (in module async_msssql_query)</a>
</li>
<li><a href="api_reference.html#prenota_sprenota_sql.SPResult.message">message (prenota_sprenota_sql.SPResult attribute)</a>
</li>
<li>
module
<ul>
<li><a href="api_reference.html#module-async_msssql_query">async_msssql_query</a>
</li>
<li><a href="api_reference.html#module-gestione_aree_frame_async">gestione_aree_frame_async</a>
</li>
<li><a href="api_reference.html#module-gestione_pickinglist">gestione_pickinglist</a>
</li>
<li><a href="api_reference.html#module-layout_window">layout_window</a>
</li>
<li><a href="api_reference.html#module-main">main</a>
</li>
<li><a href="api_reference.html#module-prenota_sprenota_sql">prenota_sprenota_sql</a>
</li>
<li><a href="api_reference.html#module-reset_corsie">reset_corsie</a>
</li>
<li><a href="api_reference.html#module-search_pallets">search_pallets</a>
</li>
<li><a href="api_reference.html#module-view_celle_multiple">view_celle_multiple</a>
</li>
</ul></li>
</ul></td>
</tr></table>
<h2 id="O">O</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#gestione_pickinglist.GestionePickingListFrame.on_export">on_export() (gestione_pickinglist.GestionePickingListFrame method)</a>
</li>
<li><a href="api_reference.html#gestione_pickinglist.GestionePickingListFrame.on_prenota">on_prenota() (gestione_pickinglist.GestionePickingListFrame method)</a>
</li>
<li><a href="api_reference.html#gestione_pickinglist.GestionePickingListFrame.on_row_checked">on_row_checked() (gestione_pickinglist.GestionePickingListFrame method)</a>
</li>
<li><a href="api_reference.html#gestione_pickinglist.GestionePickingListFrame.on_sprenota">on_sprenota() (gestione_pickinglist.GestionePickingListFrame method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#view_celle_multiple.open_celle_multiple_window">open_celle_multiple_window() (in module view_celle_multiple)</a>
</li>
<li><a href="api_reference.html#layout_window.open_layout_window">open_layout_window() (in module layout_window)</a>
</li>
<li><a href="api_reference.html#main.open_pickinglist_window">open_pickinglist_window() (in module main)</a>
</li>
<li><a href="api_reference.html#reset_corsie.open_reset_corsie_window">open_reset_corsie_window() (in module reset_corsie)</a>
</li>
<li><a href="api_reference.html#search_pallets.open_search_window">open_search_window() (in module search_pallets)</a>
</li>
</ul></td>
</tr></table>
<h2 id="P">P</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#gestione_pickinglist.ScrollTable.PADX_L">PADX_L (gestione_pickinglist.ScrollTable attribute)</a>
</li>
<li><a href="api_reference.html#gestione_pickinglist.ScrollTable.PADX_R">PADX_R (gestione_pickinglist.ScrollTable attribute)</a>
</li>
<li><a href="api_reference.html#gestione_pickinglist.ScrollTable.PADY">PADY (gestione_pickinglist.ScrollTable attribute)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#layout_window.pct_text">pct_text() (in module layout_window)</a>
</li>
<li><a href="api_reference.html#gestione_pickinglist.PLRow">PLRow (class in gestione_pickinglist)</a>
</li>
<li>
prenota_sprenota_sql
<ul>
<li><a href="api_reference.html#module-prenota_sprenota_sql">module</a>
</li>
</ul></li>
</ul></td>
</tr></table>
<h2 id="Q">Q</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#async_msssql_query.AsyncMSSQLClient.query_json">query_json() (async_msssql_query.AsyncMSSQLClient method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="R">R</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#prenota_sprenota_sql.SPResult.rc">rc (prenota_sprenota_sql.SPResult attribute)</a>
</li>
<li><a href="api_reference.html#reset_corsie.ResetCorsieWindow.refresh">refresh() (reset_corsie.ResetCorsieWindow method)</a>
</li>
<li><a href="api_reference.html#view_celle_multiple.CelleMultipleWindow.refresh_all">refresh_all() (view_celle_multiple.CelleMultipleWindow method)</a>
</li>
<li><a href="api_reference.html#gestione_pickinglist.GestionePickingListFrame.reload_from_db">reload_from_db() (gestione_pickinglist.GestionePickingListFrame method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li>
reset_corsie
<ul>
<li><a href="api_reference.html#module-reset_corsie">module</a>
</li>
</ul></li>
<li><a href="api_reference.html#reset_corsie.ResetCorsieWindow">ResetCorsieWindow (class in reset_corsie)</a>
</li>
<li><a href="api_reference.html#gestione_pickinglist.GestionePickingListFrame.rows_models">rows_models (gestione_pickinglist.GestionePickingListFrame attribute)</a>
</li>
<li><a href="api_reference.html#gestione_aree_frame_async.AsyncRunner.run">run() (gestione_aree_frame_async.AsyncRunner method)</a>
</li>
</ul></td>
</tr></table>
<h2 id="S">S</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#gestione_pickinglist.ScrollTable">ScrollTable (class in gestione_pickinglist)</a>
</li>
<li>
search_pallets
<ul>
<li><a href="api_reference.html#module-search_pallets">module</a>
</li>
</ul></li>
<li><a href="api_reference.html#search_pallets.SearchWindow">SearchWindow (class in search_pallets)</a>
</li>
<li><a href="api_reference.html#gestione_pickinglist.PLRow.set_checked">set_checked() (gestione_pickinglist.PLRow method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#gestione_aree_frame_async.BusyOverlay.show">show() (gestione_aree_frame_async.BusyOverlay method)</a>
</li>
<li><a href="api_reference.html#prenota_sprenota_sql.sp_xExePackingListPallet_async">sp_xExePackingListPallet_async() (in module prenota_sprenota_sql)</a>
</li>
<li><a href="api_reference.html#prenota_sprenota_sql.SPResult">SPResult (class in prenota_sprenota_sql)</a>
</li>
<li><a href="api_reference.html#gestione_pickinglist.ToolbarSpinner.start">start() (gestione_pickinglist.ToolbarSpinner method)</a>
</li>
<li><a href="api_reference.html#gestione_pickinglist.ToolbarSpinner.stop">stop() (gestione_pickinglist.ToolbarSpinner method)</a>
</li>
<li><a href="api_reference.html#gestione_aree_frame_async.stop_global_loop">stop_global_loop() (in module gestione_aree_frame_async)</a>
</li>
</ul></td>
</tr></table>
<h2 id="T">T</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#gestione_pickinglist.ColSpec.title">title (gestione_pickinglist.ColSpec attribute)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#gestione_pickinglist.ToolbarSpinner">ToolbarSpinner (class in gestione_pickinglist)</a>
</li>
</ul></td>
</tr></table>
<h2 id="V">V</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li>
view_celle_multiple
<ul>
<li><a href="api_reference.html#module-view_celle_multiple">module</a>
</li>
</ul></li>
</ul></td>
</tr></table>
<h2 id="W">W</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#gestione_pickinglist.ToolbarSpinner.widget">widget() (gestione_pickinglist.ToolbarSpinner method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="api_reference.html#gestione_pickinglist.ColSpec.width">width (gestione_pickinglist.ColSpec attribute)</a>
</li>
</ul></td>
</tr></table>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">warehouse</a></h1>
<search id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Search"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="architecture.html">Architettura Complessiva</a></li>
<li class="toctree-l1"><a class="reference internal" href="api_reference.html">Riferimento API</a></li>
<li class="toctree-l1"><a class="reference internal" href="flows/index.html">Flow Diagrams</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 9.1.0</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 1.0.0</a>
</div>
</body>
</html>

151
docs/_build/html/index.html vendored Normal file
View File

@@ -0,0 +1,151 @@
<!DOCTYPE html>
<html lang="en" data-content_root="./">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Warehouse Documentation &#8212; warehouse 0.0.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=5ecbeea2" />
<link rel="stylesheet" type="text/css" href="_static/basic.css?v=b08954a9" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=27fed22d" />
<script src="_static/documentation_options.js?v=d45e8c67"></script>
<script src="_static/doctools.js?v=fd6eb6e6"></script>
<script src="_static/sphinx_highlight.js?v=6ffebe34"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Architettura Complessiva" href="architecture.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="warehouse-documentation">
<h1>Warehouse Documentation<a class="headerlink" href="#warehouse-documentation" title="Link to this heading"></a></h1>
<p>Questa documentazione raccoglie:</p>
<ul class="simple">
<li><p>riferimento API generato dal codice Python;</p></li>
<li><p>diagrammi di flusso in Markdown/Mermaid;</p></li>
<li><p>vista architetturale complessiva del progetto.</p></li>
</ul>
<div class="toctree-wrapper compound">
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="architecture.html">Architettura Complessiva</a><ul>
<li class="toctree-l2"><a class="reference internal" href="architecture.html#vista-architetturale">Vista architetturale</a></li>
<li class="toctree-l2"><a class="reference internal" href="architecture.html#flusso-applicativo-generale">Flusso applicativo generale</a></li>
<li class="toctree-l2"><a class="reference internal" href="architecture.html#osservazioni">Osservazioni</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="api_reference.html">Riferimento API</a><ul>
<li class="toctree-l2"><a class="reference internal" href="api_reference.html#module-main">main.py</a></li>
<li class="toctree-l2"><a class="reference internal" href="api_reference.html#module-async_msssql_query">async_msssql_query.py</a></li>
<li class="toctree-l2"><a class="reference internal" href="api_reference.html#module-gestione_aree_frame_async">gestione_aree_frame_async.py</a></li>
<li class="toctree-l2"><a class="reference internal" href="api_reference.html#module-layout_window">layout_window.py</a></li>
<li class="toctree-l2"><a class="reference internal" href="api_reference.html#module-reset_corsie">reset_corsie.py</a></li>
<li class="toctree-l2"><a class="reference internal" href="api_reference.html#module-view_celle_multiple">view_celle_multiple.py</a></li>
<li class="toctree-l2"><a class="reference internal" href="api_reference.html#module-search_pallets">search_pallets.py</a></li>
<li class="toctree-l2"><a class="reference internal" href="api_reference.html#module-gestione_pickinglist">gestione_pickinglist.py</a></li>
<li class="toctree-l2"><a class="reference internal" href="api_reference.html#module-prenota_sprenota_sql">prenota_sprenota_sql.py</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="flows/index.html">Flow Diagrams</a><ul>
<li class="toctree-l2"><a class="reference internal" href="flows/README.html">Flow Diagrams</a></li>
<li class="toctree-l2"><a class="reference internal" href="flows/main_flow.html"><code class="docutils literal notranslate"><span class="pre">main.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="flows/layout_window_flow.html"><code class="docutils literal notranslate"><span class="pre">layout_window.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="flows/reset_corsie_flow.html"><code class="docutils literal notranslate"><span class="pre">reset_corsie.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="flows/view_celle_multiple_flow.html"><code class="docutils literal notranslate"><span class="pre">view_celle_multiple.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="flows/search_pallets_flow.html"><code class="docutils literal notranslate"><span class="pre">search_pallets.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="flows/gestione_pickinglist_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_pickinglist.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="flows/async_db_flow.html">Infrastruttura Async / DB</a></li>
<li class="toctree-l2"><a class="reference internal" href="flows/async_msssql_query_flow.html"><code class="docutils literal notranslate"><span class="pre">async_msssql_query.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="flows/gestione_aree_frame_async_flow.html"><code class="docutils literal notranslate"><span class="pre">gestione_aree_frame_async.py</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="flows/async_loop_singleton_flow.html"><code class="docutils literal notranslate"><span class="pre">async_loop_singleton.py</span></code></a></li>
</ul>
</li>
</ul>
</div>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="#">warehouse</a></h1>
<search id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Search"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="architecture.html">Architettura Complessiva</a></li>
<li class="toctree-l1"><a class="reference internal" href="api_reference.html">Riferimento API</a></li>
<li class="toctree-l1"><a class="reference internal" href="flows/index.html">Flow Diagrams</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="#">Documentation overview</a><ul>
<li>Next: <a href="architecture.html" title="next chapter">Architettura Complessiva</a></li>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 9.1.0</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 1.0.0</a>
|
<a href="_sources/index.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>

BIN
docs/_build/html/objects.inv vendored Normal file

Binary file not shown.

627
docs/_build/html/py-modindex.html vendored Normal file
View File

@@ -0,0 +1,627 @@
<!DOCTYPE html>
<html lang="en" data-content_root="./">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Python Module Index &#8212; warehouse 0.0.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=5ecbeea2" />
<link rel="stylesheet" type="text/css" href="_static/basic.css?v=b08954a9" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=27fed22d" />
<script src="_static/documentation_options.js?v=d45e8c67"></script>
<script src="_static/doctools.js?v=fd6eb6e6"></script>
<script src="_static/sphinx_highlight.js?v=6ffebe34"></script>
<script src="https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js"></script>
<script type="module">import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11.12.1/dist/mermaid.esm.min.mjs";
const initStyles = () => {
const defaultStyle = document.createElement('style');
defaultStyle.textContent = `pre.mermaid {
/* Same as .mermaid-container > pre */
display: block;
width: 100%;
}
pre.mermaid > svg {
/* Same as .mermaid-container > pre > svg */
height: 500px;
width: 100%;
max-width: 100% !important;
}`;
document.head.appendChild(defaultStyle);
const fullscreenStyle = document.createElement('style');
fullscreenStyle.textContent = `.mermaid-container {
display: flex;
flex-direction: row;
width: 100%;
}
.mermaid-container > pre {
display: block;
width: 100%;
}
.mermaid-container > pre > svg {
height: 500px;
width: 100%;
max-width: 100% !important;
}
.mermaid-fullscreen-btn {
width: 28px;
height: 28px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
font-size: 14px;
line-height: 1;
padding: 0;
color: #333;
}
.mermaid-fullscreen-btn:hover {
opacity: 100% !important;
background: rgba(255, 255, 255, 1);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
transform: scale(1.1);
}
.mermaid-fullscreen-btn.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.3);
color: #e0e0e0;
}
.mermaid-fullscreen-btn.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 3px 10px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal {
display: none;
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 95vw;
height: 100vh;
background: rgba(255, 255, 255, 0.98);
z-index: 9999;
padding: 20px;
overflow: auto;
}
.mermaid-fullscreen-modal.dark-theme {
background: rgba(0, 0, 0, 0.98);
}
.mermaid-fullscreen-modal.active {
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen {
position: relative;
width: 95vw;
height: 90vh;
max-width: 95vw;
max-height: 90vh;
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
overflow: auto;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen.dark-theme {
background: #1a1a1a;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);
}
.mermaid-container-fullscreen pre.mermaid {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen .mermaid svg {
height: 100% !important;
width: 100% !important;
cursor: grab;
}
.mermaid-fullscreen-close {
position: fixed !important;
top: 20px !important;
right: 20px !important;
width: 40px;
height: 40px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 50%;
cursor: pointer;
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
transition: all 0.2s;
font-size: 24px;
line-height: 1;
color: #333;
}
.mermaid-fullscreen-close:hover {
background: white;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
transform: scale(1.1);
}
.mermaid-fullscreen-close.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.2);
color: #e0e0e0;
}
.mermaid-fullscreen-close.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 6px 16px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal .mermaid-fullscreen-btn {
display: none !important;
}`;
document.head.appendChild(fullscreenStyle);
}
// Detect if page has dark background
const isDarkTheme = () => {
// We use a set of heuristics:
// 1. Check for common dark mode classes or attributes
// 2. Check computed background color brightness
if (document.documentElement.classList.contains('dark') ||
document.documentElement.getAttribute('data-theme') === 'dark' ||
document.body.classList.contains('dark') ||
document.body.getAttribute('data-theme') === 'dark') {
// console.log("Dark theme detected via class/attribute");
return true;
}
if (document.documentElement.classList.contains('light') ||
document.documentElement.getAttribute('data-theme') === 'light' ||
document.body.classList.contains('light') ||
document.body.getAttribute('data-theme') === 'light') {
// console.log("Light theme detected via class/attribute");
return false;
}
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
// console.log("Dark theme detected via prefers-color-scheme");
return true;
}
const bgColor = window.getComputedStyle(document.body).backgroundColor;
const match = bgColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)/);
if (match) {
const r = parseInt(match[1]);
const g = parseInt(match[2]);
const b = parseInt(match[3]);
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
// console.log("Background color brightness:", brightness);
return brightness < 128;
}
// console.log("No dark or light theme detected, defaulting to light theme");
return false;
};
let darkTheme = isDarkTheme();
let modal = null;
let modalContent = null;
let previousScrollOffset = [window.scrollX, window.scrollY];
const runMermaid = async (rerun) => {
console.log("Running mermaid diagrams, rerun =", rerun);
// clear all existing mermaid charts
let all_mermaids = document.querySelectorAll(".mermaid");
if (rerun) {
all_mermaids.forEach((el) => {
if(!el.hasAttribute("data-original-code")) {
// store original code
// console.log(`Storing original code for first run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
if(el.getAttribute("data-processed") === "true") {
// remove and restore original
el.removeAttribute("data-processed");
// console.log(`Restoring original code for re-run: `, el.getAttribute('data-original-code'));
el.innerHTML = el.getAttribute('data-original-code');
} else {
// store original code
// console.log(`Storing original code for re-run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
});
await mermaid.run();
}
all_mermaids = document.querySelectorAll(".mermaid");
const mermaids_processed = document.querySelectorAll(".mermaid[data-processed='true']");
if ("False" === "True") {
const mermaids_to_add_zoom = -1 === -1 ? all_mermaids.length : -1;
if(mermaids_to_add_zoom > 0) {
var svgs = d3.selectAll("");
if(all_mermaids.length !== mermaids_processed.length) {
setTimeout(() => runMermaid(false), 200);
return;
} else if(svgs.size() !== mermaids_to_add_zoom) {
setTimeout(() => runMermaid(false), 200);
return;
} else {
svgs.each(function() {
var svg = d3.select(this);
svg.html("<g class='wrapper'>" + svg.html() + "</g>");
var inner = svg.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svg.call(zoom);
});
}
}
} else if(all_mermaids.length !== mermaids_processed.length) {
// Wait for mermaid to process all diagrams
setTimeout(() => runMermaid(false), 200);
return;
}
// Stop here if not adding fullscreen capability
if ("True" !== "True") return;
if (modal !== null ) {
// Destroy existing modal
modal.remove();
modal = null;
modalContent = null;
}
modal = document.createElement('div');
modal.className = 'mermaid-fullscreen-modal' + (darkTheme ? ' dark-theme' : '');
modal.setAttribute('role', 'dialog');
modal.setAttribute('aria-modal', 'true');
modal.setAttribute('aria-label', 'Fullscreen diagram viewer');
modal.innerHTML = `
<button class="mermaid-fullscreen-close${darkTheme ? ' dark-theme' : ''}" aria-label="Close fullscreen">✕</button>
<div class="mermaid-container-fullscreen${darkTheme ? ' dark-theme' : ''}"></div>
`;
document.body.appendChild(modal);
modalContent = modal.querySelector('.mermaid-container-fullscreen');
const closeBtn = modal.querySelector('.mermaid-fullscreen-close');
const closeModal = () => {
modal.classList.remove('active');
modalContent.innerHTML = '';
document.body.style.overflow = ''
window.scrollTo({left: previousScrollOffset[0], top: previousScrollOffset[1], behavior: 'instant'});
};
closeBtn.addEventListener('click', closeModal);
modal.addEventListener('click', (e) => {
if (e.target === modal) closeModal();
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && modal.classList.contains('active')) {
closeModal();
}
});
document.querySelectorAll('.mermaid').forEach((mermaidDiv) => {
if (mermaidDiv.parentNode.classList.contains('mermaid-container') ||
mermaidDiv.closest('.mermaid-fullscreen-modal')) {
// Already processed, adjust button class if needed
const existingBtn = mermaidDiv.parentNode.querySelector('.mermaid-fullscreen-btn');
if (existingBtn) {
existingBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
}
return;
}
const container = document.createElement('div');
container.className = 'mermaid-container';
mermaidDiv.parentNode.insertBefore(container, mermaidDiv);
container.appendChild(mermaidDiv);
const fullscreenBtn = document.createElement('button');
fullscreenBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
fullscreenBtn.setAttribute('aria-label', 'View diagram in fullscreen');
fullscreenBtn.textContent = '⛶';
fullscreenBtn.style.opacity = '50%';
// Calculate dynamic position based on diagram's margin and padding
const diagramStyle = window.getComputedStyle(mermaidDiv);
const marginTop = parseFloat(diagramStyle.marginTop) || 0;
const marginRight = parseFloat(diagramStyle.marginRight) || 0;
const paddingTop = parseFloat(diagramStyle.paddingTop) || 0;
const paddingRight = parseFloat(diagramStyle.paddingRight) || 0;
fullscreenBtn.style.top = `${marginTop + paddingTop + 4}px`;
fullscreenBtn.style.right = `${marginRight + paddingRight + 4}px`;
fullscreenBtn.addEventListener('click', () => {
previousScrollOffset = [window.scroll, window.scrollY];
const clone = mermaidDiv.cloneNode(true);
modalContent.innerHTML = '';
modalContent.appendChild(clone);
const svg = clone.querySelector('svg');
if (svg) {
svg.removeAttribute('width');
svg.removeAttribute('height');
svg.style.width = '100%';
svg.style.height = 'auto';
svg.style.maxWidth = '100%';
svg.style.sdisplay = 'block';
if ("False" === "True") {
setTimeout(() => {
const g = svg.querySelector('g');
if (g) {
var svgD3 = d3.select(svg);
svgD3.html("<g class='wrapper'>" + svgD3.html() + "</g>");
var inner = svgD3.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svgD3.call(zoom);
}
}, 100);
}
}
modal.classList.add('active');
document.body.style.overflow = 'hidden';
});
container.appendChild(fullscreenBtn);
});
};
const load = async () => {
initStyles();
await runMermaid(true);
const reRunIfThemeChanges = async () => {
const newDarkTheme = isDarkTheme();
if (newDarkTheme !== darkTheme) {
darkTheme = newDarkTheme;
console.log("Theme change detected, re-running mermaid with", darkTheme ? "dark" : "default", "theme");
await mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
await runMermaid(true);
}
};
// Update theme classes when theme changes
const themeObserver = new MutationObserver(reRunIfThemeChanges);
themeObserver.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
themeObserver.observe(document.body, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
};
console.log("Initializing mermaid with", darkTheme ? "dark" : "default", "theme");
mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
window.addEventListener("load", load);
window.runMermaid = runMermaid;</script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
<script>
DOCUMENTATION_OPTIONS.COLLAPSE_INDEX = true;
</script>
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Python Module Index</h1>
<div class="modindex-jumpbox">
<a href="#cap-a"><strong>a</strong></a> |
<a href="#cap-g"><strong>g</strong></a> |
<a href="#cap-l"><strong>l</strong></a> |
<a href="#cap-m"><strong>m</strong></a> |
<a href="#cap-p"><strong>p</strong></a> |
<a href="#cap-r"><strong>r</strong></a> |
<a href="#cap-s"><strong>s</strong></a> |
<a href="#cap-v"><strong>v</strong></a>
</div>
<table class="indextable modindextable">
<tr class="pcap"><td></td><td>&#160;</td><td></td></tr>
<tr class="cap" id="cap-a"><td></td><td>
<strong>a</strong></td><td></td></tr>
<tr>
<td></td>
<td>
<a href="api_reference.html#module-async_msssql_query"><code class="xref">async_msssql_query</code></a></td><td>
<em></em></td></tr>
<tr class="pcap"><td></td><td>&#160;</td><td></td></tr>
<tr class="cap" id="cap-g"><td></td><td>
<strong>g</strong></td><td></td></tr>
<tr>
<td></td>
<td>
<a href="api_reference.html#module-gestione_aree_frame_async"><code class="xref">gestione_aree_frame_async</code></a></td><td>
<em></em></td></tr>
<tr>
<td></td>
<td>
<a href="api_reference.html#module-gestione_pickinglist"><code class="xref">gestione_pickinglist</code></a></td><td>
<em></em></td></tr>
<tr class="pcap"><td></td><td>&#160;</td><td></td></tr>
<tr class="cap" id="cap-l"><td></td><td>
<strong>l</strong></td><td></td></tr>
<tr>
<td></td>
<td>
<a href="api_reference.html#module-layout_window"><code class="xref">layout_window</code></a></td><td>
<em></em></td></tr>
<tr class="pcap"><td></td><td>&#160;</td><td></td></tr>
<tr class="cap" id="cap-m"><td></td><td>
<strong>m</strong></td><td></td></tr>
<tr>
<td></td>
<td>
<a href="api_reference.html#module-main"><code class="xref">main</code></a></td><td>
<em></em></td></tr>
<tr class="pcap"><td></td><td>&#160;</td><td></td></tr>
<tr class="cap" id="cap-p"><td></td><td>
<strong>p</strong></td><td></td></tr>
<tr>
<td></td>
<td>
<a href="api_reference.html#module-prenota_sprenota_sql"><code class="xref">prenota_sprenota_sql</code></a></td><td>
<em></em></td></tr>
<tr class="pcap"><td></td><td>&#160;</td><td></td></tr>
<tr class="cap" id="cap-r"><td></td><td>
<strong>r</strong></td><td></td></tr>
<tr>
<td></td>
<td>
<a href="api_reference.html#module-reset_corsie"><code class="xref">reset_corsie</code></a></td><td>
<em></em></td></tr>
<tr class="pcap"><td></td><td>&#160;</td><td></td></tr>
<tr class="cap" id="cap-s"><td></td><td>
<strong>s</strong></td><td></td></tr>
<tr>
<td></td>
<td>
<a href="api_reference.html#module-search_pallets"><code class="xref">search_pallets</code></a></td><td>
<em></em></td></tr>
<tr class="pcap"><td></td><td>&#160;</td><td></td></tr>
<tr class="cap" id="cap-v"><td></td><td>
<strong>v</strong></td><td></td></tr>
<tr>
<td></td>
<td>
<a href="api_reference.html#module-view_celle_multiple"><code class="xref">view_celle_multiple</code></a></td><td>
<em></em></td></tr>
</table>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">warehouse</a></h1>
<search id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Search"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="architecture.html">Architettura Complessiva</a></li>
<li class="toctree-l1"><a class="reference internal" href="api_reference.html">Riferimento API</a></li>
<li class="toctree-l1"><a class="reference internal" href="flows/index.html">Flow Diagrams</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 9.1.0</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 1.0.0</a>
</div>
</body>
</html>

559
docs/_build/html/search.html vendored Normal file
View File

@@ -0,0 +1,559 @@
<!DOCTYPE html>
<html lang="en" data-content_root="./">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Search &#8212; warehouse 0.0.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=5ecbeea2" />
<link rel="stylesheet" type="text/css" href="_static/basic.css?v=b08954a9" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=27fed22d" />
<script src="_static/documentation_options.js?v=d45e8c67"></script>
<script src="_static/doctools.js?v=fd6eb6e6"></script>
<script src="_static/sphinx_highlight.js?v=6ffebe34"></script>
<script src="https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js"></script>
<script type="module">import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11.12.1/dist/mermaid.esm.min.mjs";
const initStyles = () => {
const defaultStyle = document.createElement('style');
defaultStyle.textContent = `pre.mermaid {
/* Same as .mermaid-container > pre */
display: block;
width: 100%;
}
pre.mermaid > svg {
/* Same as .mermaid-container > pre > svg */
height: 500px;
width: 100%;
max-width: 100% !important;
}`;
document.head.appendChild(defaultStyle);
const fullscreenStyle = document.createElement('style');
fullscreenStyle.textContent = `.mermaid-container {
display: flex;
flex-direction: row;
width: 100%;
}
.mermaid-container > pre {
display: block;
width: 100%;
}
.mermaid-container > pre > svg {
height: 500px;
width: 100%;
max-width: 100% !important;
}
.mermaid-fullscreen-btn {
width: 28px;
height: 28px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
font-size: 14px;
line-height: 1;
padding: 0;
color: #333;
}
.mermaid-fullscreen-btn:hover {
opacity: 100% !important;
background: rgba(255, 255, 255, 1);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
transform: scale(1.1);
}
.mermaid-fullscreen-btn.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.3);
color: #e0e0e0;
}
.mermaid-fullscreen-btn.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 3px 10px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal {
display: none;
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 95vw;
height: 100vh;
background: rgba(255, 255, 255, 0.98);
z-index: 9999;
padding: 20px;
overflow: auto;
}
.mermaid-fullscreen-modal.dark-theme {
background: rgba(0, 0, 0, 0.98);
}
.mermaid-fullscreen-modal.active {
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen {
position: relative;
width: 95vw;
height: 90vh;
max-width: 95vw;
max-height: 90vh;
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
overflow: auto;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen.dark-theme {
background: #1a1a1a;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);
}
.mermaid-container-fullscreen pre.mermaid {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen .mermaid svg {
height: 100% !important;
width: 100% !important;
cursor: grab;
}
.mermaid-fullscreen-close {
position: fixed !important;
top: 20px !important;
right: 20px !important;
width: 40px;
height: 40px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 50%;
cursor: pointer;
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
transition: all 0.2s;
font-size: 24px;
line-height: 1;
color: #333;
}
.mermaid-fullscreen-close:hover {
background: white;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
transform: scale(1.1);
}
.mermaid-fullscreen-close.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.2);
color: #e0e0e0;
}
.mermaid-fullscreen-close.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 6px 16px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal .mermaid-fullscreen-btn {
display: none !important;
}`;
document.head.appendChild(fullscreenStyle);
}
// Detect if page has dark background
const isDarkTheme = () => {
// We use a set of heuristics:
// 1. Check for common dark mode classes or attributes
// 2. Check computed background color brightness
if (document.documentElement.classList.contains('dark') ||
document.documentElement.getAttribute('data-theme') === 'dark' ||
document.body.classList.contains('dark') ||
document.body.getAttribute('data-theme') === 'dark') {
// console.log("Dark theme detected via class/attribute");
return true;
}
if (document.documentElement.classList.contains('light') ||
document.documentElement.getAttribute('data-theme') === 'light' ||
document.body.classList.contains('light') ||
document.body.getAttribute('data-theme') === 'light') {
// console.log("Light theme detected via class/attribute");
return false;
}
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
// console.log("Dark theme detected via prefers-color-scheme");
return true;
}
const bgColor = window.getComputedStyle(document.body).backgroundColor;
const match = bgColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)/);
if (match) {
const r = parseInt(match[1]);
const g = parseInt(match[2]);
const b = parseInt(match[3]);
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
// console.log("Background color brightness:", brightness);
return brightness < 128;
}
// console.log("No dark or light theme detected, defaulting to light theme");
return false;
};
let darkTheme = isDarkTheme();
let modal = null;
let modalContent = null;
let previousScrollOffset = [window.scrollX, window.scrollY];
const runMermaid = async (rerun) => {
console.log("Running mermaid diagrams, rerun =", rerun);
// clear all existing mermaid charts
let all_mermaids = document.querySelectorAll(".mermaid");
if (rerun) {
all_mermaids.forEach((el) => {
if(!el.hasAttribute("data-original-code")) {
// store original code
// console.log(`Storing original code for first run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
if(el.getAttribute("data-processed") === "true") {
// remove and restore original
el.removeAttribute("data-processed");
// console.log(`Restoring original code for re-run: `, el.getAttribute('data-original-code'));
el.innerHTML = el.getAttribute('data-original-code');
} else {
// store original code
// console.log(`Storing original code for re-run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
});
await mermaid.run();
}
all_mermaids = document.querySelectorAll(".mermaid");
const mermaids_processed = document.querySelectorAll(".mermaid[data-processed='true']");
if ("False" === "True") {
const mermaids_to_add_zoom = -1 === -1 ? all_mermaids.length : -1;
if(mermaids_to_add_zoom > 0) {
var svgs = d3.selectAll("");
if(all_mermaids.length !== mermaids_processed.length) {
setTimeout(() => runMermaid(false), 200);
return;
} else if(svgs.size() !== mermaids_to_add_zoom) {
setTimeout(() => runMermaid(false), 200);
return;
} else {
svgs.each(function() {
var svg = d3.select(this);
svg.html("<g class='wrapper'>" + svg.html() + "</g>");
var inner = svg.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svg.call(zoom);
});
}
}
} else if(all_mermaids.length !== mermaids_processed.length) {
// Wait for mermaid to process all diagrams
setTimeout(() => runMermaid(false), 200);
return;
}
// Stop here if not adding fullscreen capability
if ("True" !== "True") return;
if (modal !== null ) {
// Destroy existing modal
modal.remove();
modal = null;
modalContent = null;
}
modal = document.createElement('div');
modal.className = 'mermaid-fullscreen-modal' + (darkTheme ? ' dark-theme' : '');
modal.setAttribute('role', 'dialog');
modal.setAttribute('aria-modal', 'true');
modal.setAttribute('aria-label', 'Fullscreen diagram viewer');
modal.innerHTML = `
<button class="mermaid-fullscreen-close${darkTheme ? ' dark-theme' : ''}" aria-label="Close fullscreen">✕</button>
<div class="mermaid-container-fullscreen${darkTheme ? ' dark-theme' : ''}"></div>
`;
document.body.appendChild(modal);
modalContent = modal.querySelector('.mermaid-container-fullscreen');
const closeBtn = modal.querySelector('.mermaid-fullscreen-close');
const closeModal = () => {
modal.classList.remove('active');
modalContent.innerHTML = '';
document.body.style.overflow = ''
window.scrollTo({left: previousScrollOffset[0], top: previousScrollOffset[1], behavior: 'instant'});
};
closeBtn.addEventListener('click', closeModal);
modal.addEventListener('click', (e) => {
if (e.target === modal) closeModal();
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && modal.classList.contains('active')) {
closeModal();
}
});
document.querySelectorAll('.mermaid').forEach((mermaidDiv) => {
if (mermaidDiv.parentNode.classList.contains('mermaid-container') ||
mermaidDiv.closest('.mermaid-fullscreen-modal')) {
// Already processed, adjust button class if needed
const existingBtn = mermaidDiv.parentNode.querySelector('.mermaid-fullscreen-btn');
if (existingBtn) {
existingBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
}
return;
}
const container = document.createElement('div');
container.className = 'mermaid-container';
mermaidDiv.parentNode.insertBefore(container, mermaidDiv);
container.appendChild(mermaidDiv);
const fullscreenBtn = document.createElement('button');
fullscreenBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
fullscreenBtn.setAttribute('aria-label', 'View diagram in fullscreen');
fullscreenBtn.textContent = '⛶';
fullscreenBtn.style.opacity = '50%';
// Calculate dynamic position based on diagram's margin and padding
const diagramStyle = window.getComputedStyle(mermaidDiv);
const marginTop = parseFloat(diagramStyle.marginTop) || 0;
const marginRight = parseFloat(diagramStyle.marginRight) || 0;
const paddingTop = parseFloat(diagramStyle.paddingTop) || 0;
const paddingRight = parseFloat(diagramStyle.paddingRight) || 0;
fullscreenBtn.style.top = `${marginTop + paddingTop + 4}px`;
fullscreenBtn.style.right = `${marginRight + paddingRight + 4}px`;
fullscreenBtn.addEventListener('click', () => {
previousScrollOffset = [window.scroll, window.scrollY];
const clone = mermaidDiv.cloneNode(true);
modalContent.innerHTML = '';
modalContent.appendChild(clone);
const svg = clone.querySelector('svg');
if (svg) {
svg.removeAttribute('width');
svg.removeAttribute('height');
svg.style.width = '100%';
svg.style.height = 'auto';
svg.style.maxWidth = '100%';
svg.style.sdisplay = 'block';
if ("False" === "True") {
setTimeout(() => {
const g = svg.querySelector('g');
if (g) {
var svgD3 = d3.select(svg);
svgD3.html("<g class='wrapper'>" + svgD3.html() + "</g>");
var inner = svgD3.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svgD3.call(zoom);
}
}, 100);
}
}
modal.classList.add('active');
document.body.style.overflow = 'hidden';
});
container.appendChild(fullscreenBtn);
});
};
const load = async () => {
initStyles();
await runMermaid(true);
const reRunIfThemeChanges = async () => {
const newDarkTheme = isDarkTheme();
if (newDarkTheme !== darkTheme) {
darkTheme = newDarkTheme;
console.log("Theme change detected, re-running mermaid with", darkTheme ? "dark" : "default", "theme");
await mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
await runMermaid(true);
}
};
// Update theme classes when theme changes
const themeObserver = new MutationObserver(reRunIfThemeChanges);
themeObserver.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
themeObserver.observe(document.body, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
};
console.log("Initializing mermaid with", darkTheme ? "dark" : "default", "theme");
mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
window.addEventListener("load", load);
window.runMermaid = runMermaid;</script>
<script src="_static/searchtools.js"></script>
<script src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="#" />
<script src="searchindex.js" defer="defer"></script>
<meta name="robots" content="noindex" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1 id="search-documentation">Search</h1>
<noscript>
<div class="admonition warning">
<p>
Please activate JavaScript to enable the search
functionality.
</p>
</div>
</noscript>
<p>
Searching for multiple words only shows matches that contain
all words.
</p>
<form action="" method="get">
<input type="text" name="q" aria-labelledby="search-documentation" value="" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="search" />
<span id="search-progress" style="padding-left: 10px"></span>
</form>
<div id="search-results"></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">warehouse</a></h1>
<h3>Navigation</h3>
<p class="caption" role="heading"><span class="caption-text">Contenuti</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="architecture.html">Architettura Complessiva</a></li>
<li class="toctree-l1"><a class="reference internal" href="api_reference.html">Riferimento API</a></li>
<li class="toctree-l1"><a class="reference internal" href="flows/index.html">Flow Diagrams</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 9.1.0</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 1.0.0</a>
</div>
</body>
</html>

1
docs/_build/html/searchindex.js vendored Normal file

File diff suppressed because one or more lines are too long

77
docs/api_reference.rst Normal file
View File

@@ -0,0 +1,77 @@
Riferimento API
===============
La sezione seguente usa ``autodoc`` per estrarre docstring direttamente dai
moduli Python principali del progetto.
main.py
-------
.. automodule:: main
:members:
:undoc-members:
:show-inheritance:
async_msssql_query.py
---------------------
.. automodule:: async_msssql_query
:members:
:undoc-members:
:show-inheritance:
gestione_aree_frame_async.py
----------------------------
.. automodule:: gestione_aree_frame_async
:members:
:undoc-members:
:show-inheritance:
layout_window.py
----------------
.. automodule:: layout_window
:members:
:undoc-members:
:show-inheritance:
reset_corsie.py
---------------
.. automodule:: reset_corsie
:members:
:undoc-members:
:show-inheritance:
view_celle_multiple.py
----------------------
.. automodule:: view_celle_multiple
:members:
:undoc-members:
:show-inheritance:
search_pallets.py
-----------------
.. automodule:: search_pallets
:members:
:undoc-members:
:show-inheritance:
gestione_pickinglist.py
-----------------------
.. automodule:: gestione_pickinglist
:members:
:undoc-members:
:show-inheritance:
prenota_sprenota_sql.py
-----------------------
.. automodule:: prenota_sprenota_sql
:members:
:undoc-members:
:show-inheritance:

51
docs/architecture.md Normal file
View File

@@ -0,0 +1,51 @@
# Architettura Complessiva
Questa pagina collega i moduli principali del progetto in una vista unica,
partendo dal launcher fino ai moduli GUI e al livello infrastrutturale async/DB.
## Vista architetturale
```{mermaid}
flowchart TD
Main["main.py"] --> Launcher["Launcher"]
Main --> Loop["async_loop_singleton.get_global_loop()"]
Main --> DB["AsyncMSSQLClient"]
Launcher --> Reset["reset_corsie.py"]
Launcher --> Layout["layout_window.py"]
Launcher --> Ghost["view_celle_multiple.py"]
Launcher --> Search["search_pallets.py"]
Launcher --> Picking["gestione_pickinglist.py"]
Reset --> Runner["gestione_aree_frame_async.AsyncRunner"]
Layout --> Runner
Ghost --> Runner
Search --> Runner
Picking --> Runner
Runner --> Loop
Runner --> DB
Picking --> SP["prenota_sprenota_sql.py"]
SP --> DB
DB --> SQL["SQL Server / Mediseawall"]
```
## Flusso applicativo generale
```{mermaid}
flowchart LR
User["Utente"] --> MainWin["Launcher"]
MainWin --> Module["Finestra modulo"]
Module --> AsyncReq["AsyncRunner.run(...)"]
AsyncReq --> DbClient["AsyncMSSQLClient"]
DbClient --> SqlServer["Database SQL Server"]
SqlServer --> Callback["Callback _ok/_err"]
Callback --> Module
```
## Osservazioni
- `main.py` centralizza il loop asincrono e il client database condiviso.
- I moduli GUI si concentrano sulla UI e delegano query e task lunghi a `AsyncRunner`.
- `gestione_pickinglist.py` è l'unico modulo che passa anche da `prenota_sprenota_sql.py` per la logica di prenotazione.
- La cartella `docs/flows/` contiene la vista dettagliata modulo per modulo.

40
docs/conf.py Normal file
View File

@@ -0,0 +1,40 @@
"""Sphinx configuration for the warehouse project documentation."""
from pathlib import Path
import sys
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT))
project = "warehouse"
author = "Project Team"
release = "0.0.1"
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.napoleon",
"myst_parser",
"sphinxcontrib.mermaid",
]
templates_path = ["_templates"]
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
source_suffix = {
".rst": "restructuredtext",
".md": "markdown",
}
html_theme = "alabaster"
html_static_path = ["_static"]
autodoc_member_order = "bysource"
autodoc_typehints = "description"
napoleon_google_docstring = True
napoleon_numpy_docstring = False
myst_enable_extensions = [
"colon_fence",
]
mermaid_output_format = "raw"

27
docs/flows/README.md Normal file
View File

@@ -0,0 +1,27 @@
# Flow Diagrams
Questa cartella contiene schemi di flusso e schemi di chiamata dei moduli
principali avviati da `main.py`.
I diagrammi sono scritti in Mermaid, quindi possono essere:
- letti direttamente nei file Markdown;
- renderizzati da molti editor Git/Markdown;
- inclusi in una futura documentazione Sphinx o MkDocs.
## Indice
- [main](./main_flow.md)
- [layout_window](./layout_window_flow.md)
- [reset_corsie](./reset_corsie_flow.md)
- [view_celle_multiple](./view_celle_multiple_flow.md)
- [search_pallets](./search_pallets_flow.md)
- [gestione_pickinglist](./gestione_pickinglist_flow.md)
- [infrastruttura async/db](./async_db_flow.md)
## Convenzioni
- I diagrammi descrivono il flusso applicativo ad alto livello.
- Non rappresentano ogni singola riga di codice.
- I nodi `AsyncRunner` e `query_json` evidenziano i passaggi asincroni più
importanti tra interfaccia e database.

View File

@@ -0,0 +1,39 @@
# Infrastruttura Async / DB
## Scopo
Questo diagramma descrive il flusso comune usato da tutti i moduli GUI quando
eseguono una query sul database.
## Flusso trasversale
```{mermaid}
flowchart TD
A["Evento UI (click / selezione / ricerca)"] --> B["Metodo finestra"]
B --> C["AsyncRunner.run(awaitable)"]
C --> D["Coroutines sul loop globale"]
D --> E["AsyncMSSQLClient.query_json() / exec()"]
E --> F["SQL Server"]
F --> G["Risultato query"]
G --> H["Future completata"]
H --> I["Callback _ok / _err su thread Tk"]
I --> J["Aggiornamento widget"]
```
## Relazioni principali
```{mermaid}
flowchart LR
Main["main.py"] --> Loop["get_global_loop()"]
Main --> DB["AsyncMSSQLClient"]
Windows["Moduli GUI"] --> Runner["AsyncRunner"]
Runner --> Loop
Runner --> DB
DB --> SQL["SQL Server Mediseawall"]
```
## Note
- Il loop asincrono è condiviso tra tutte le finestre.
- Il client DB è condiviso e creato una sola volta nel launcher.
- I callback che aggiornano la UI rientrano sempre sul thread Tk.

View File

@@ -0,0 +1,39 @@
# `async_loop_singleton.py`
## Scopo
Questo modulo mantiene un loop asyncio globale e condiviso, eseguito su un
thread dedicato.
## Flusso
```{mermaid}
flowchart TD
A["Chiamata a get_global_loop()"] --> B{"Loop gia presente?"}
B -- Si --> C["Ritorna loop esistente"]
B -- No --> D["Crea Event ready"]
D --> E["Avvia thread daemon"]
E --> F["_run()"]
F --> G["new_event_loop()"]
G --> H["set_event_loop(loop)"]
H --> I["ready.set()"]
I --> J["loop.run_forever()"]
J --> K["Ritorna loop al chiamante"]
```
## Chiusura
```{mermaid}
flowchart TD
A["stop_global_loop()"] --> B{"Loop attivo?"}
B -- No --> C["Nessuna azione"]
B -- Si --> D["call_soon_threadsafe(loop.stop)"]
D --> E["join del thread"]
E --> F["Azzera riferimenti globali"]
```
## Note
- E un helper minimale usato da `main.py`.
- Il modulo esiste separato da `gestione_aree_frame_async.py`, ma concettualmente
svolge lo stesso ruolo di gestione del loop condiviso.

View File

@@ -0,0 +1,41 @@
# `async_msssql_query.py`
## Scopo
Questo modulo centralizza la costruzione del DSN SQL Server e l'accesso
asincrono al database tramite `AsyncMSSQLClient`.
## Flusso di utilizzo
```{mermaid}
flowchart TD
A["main.py o modulo chiamante"] --> B["make_mssql_dsn(...)"]
B --> C["Crea stringa mssql+aioodbc"]
C --> D["AsyncMSSQLClient(dsn)"]
D --> E["query_json(...) o exec(...)"]
E --> F["_ensure_engine()"]
F --> G{"Engine gia creato?"}
G -- No --> H["create_async_engine(..., NullPool, loop corrente)"]
G -- Si --> I["Riusa engine esistente"]
H --> J["execute(text(sql), params)"]
I --> J
J --> K["Normalizza rows/columns"]
K --> L["Ritorna payload JSON-friendly"]
```
## Schema di chiamata
```{mermaid}
flowchart LR
DSN["make_mssql_dsn"] --> Client["AsyncMSSQLClient.__init__"]
Client --> Ensure["_ensure_engine"]
Ensure --> Query["query_json"]
Ensure --> Exec["exec"]
Client --> Dispose["dispose"]
```
## Note
- `NullPool` evita problemi di riuso connessioni tra loop diversi.
- L'engine viene creato solo al primo utilizzo reale.
- `query_json()` restituisce un formato gia pronto per le callback GUI.

View File

@@ -0,0 +1,45 @@
# `gestione_aree_frame_async.py`
## Scopo
Questo modulo fornisce l'infrastruttura async usata dalle finestre GUI:
- loop asincrono globale;
- overlay di attesa;
- runner che collega coroutine e callback Tk.
## Flusso infrastrutturale
```{mermaid}
flowchart TD
A["Metodo finestra GUI"] --> B["AsyncRunner.run(awaitable)"]
B --> C{"busy overlay richiesto?"}
C -- Si --> D["BusyOverlay.show()"]
C -- No --> E["Salta overlay"]
D --> F["run_coroutine_threadsafe(awaitable, loop globale)"]
E --> F
F --> G["Polling del Future"]
G --> H{"Future completato?"}
H -- No --> G
H -- Si --> I{"Successo o errore?"}
I -- Successo --> J["widget.after(..., on_success)"]
I -- Errore --> K["widget.after(..., on_error)"]
J --> L["BusyOverlay.hide()"]
K --> L
```
## Schema di componenti
```{mermaid}
flowchart LR
Holder["_LoopHolder"] --> Loop["get_global_loop"]
Loop --> Runner["AsyncRunner"]
Overlay["BusyOverlay"] --> Runner
Runner --> GUI["Moduli GUI"]
```
## Note
- Il modulo fa da ponte tra thread Tk e thread del loop asincrono.
- `BusyOverlay` e riusato da piu finestre, quindi e un componente condiviso.
- `AsyncRunner` evita che i moduli GUI gestiscano direttamente i `Future`.

View File

@@ -0,0 +1,69 @@
# `gestione_pickinglist.py`
## Scopo
Questo modulo gestisce la vista master/detail delle picking list e permette di:
- caricare l'elenco dei documenti;
- vedere il dettaglio UDC della riga selezionata;
- prenotare e s-prenotare una picking list;
- mantenere una UI fluida con spinner e refresh differiti.
## Flusso di apertura
```{mermaid}
flowchart TD
A["open_pickinglist_window() da main.py"] --> B["create_pickinglist_frame()"]
B --> C["GestionePickingListFrame.__init__()"]
C --> D["_build_layout()"]
D --> E["after_idle(_first_show)"]
E --> F["reload_from_db(first=True)"]
F --> G["query_json SQL_PL"]
G --> H["_refresh_mid_rows()"]
H --> I["Render tabella master"]
```
## Flusso master/detail
```{mermaid}
flowchart TD
A["Utente seleziona checkbox riga"] --> B["on_row_checked()"]
B --> C["Deseleziona altre righe"]
C --> D["Salva detail_doc"]
D --> E["query_json SQL_PL_DETAILS"]
E --> F["_refresh_details()"]
F --> G["Render tabella dettaglio"]
```
## Prenotazione / s-prenotazione
```{mermaid}
flowchart TD
A["Click Prenota o S-prenota"] --> B["Verifica riga selezionata"]
B --> C["Determina documento e stato atteso"]
C --> D["Chiama sp_xExePackingListPallet_async()"]
D --> E["Aggiorna Celle e LogPackingList sul DB"]
E --> F["SPResult"]
F --> G{"rc == 0?"}
G -- Si --> H["_recolor_row_by_documento()"]
G -- No --> I["Messaggio di errore"]
```
## Schema di chiamata
```{mermaid}
flowchart LR
Init["__init__"] --> Build["_build_layout"]
Init --> First["_first_show"]
First --> Reload["reload_from_db"]
Reload --> Mid["_refresh_mid_rows"]
Check["on_row_checked"] --> Details["_refresh_details"]
Pren["on_prenota"] --> SP["sp_xExePackingListPallet_async"]
Spren["on_sprenota"] --> SP
```
## Note
- Il modulo usa `AsyncRunner`, `BusyOverlay` e `ToolbarSpinner`.
- Il caricamento iniziale è differito con `after_idle` per ridurre lo sfarfallio.
- La riga selezionata viene tenuta separata dal dettaglio tramite `detail_doc`.

20
docs/flows/index.rst Normal file
View File

@@ -0,0 +1,20 @@
Flow Diagrams
=============
Questa sezione raccoglie i diagrammi Mermaid dei moduli applicativi e
infrastrutturali.
.. toctree::
:maxdepth: 1
README.md
main_flow.md
layout_window_flow.md
reset_corsie_flow.md
view_celle_multiple_flow.md
search_pallets_flow.md
gestione_pickinglist_flow.md
async_db_flow.md
async_msssql_query_flow.md
gestione_aree_frame_async_flow.md
async_loop_singleton_flow.md

View File

@@ -0,0 +1,61 @@
# `layout_window.py`
## Scopo
Questo modulo visualizza il layout delle corsie come matrice di celle, mostra
lo stato di occupazione, consente di cercare una UDC e permette l'export della
matrice.
## Flusso operativo
```{mermaid}
flowchart TD
A["open_layout_window()"] --> B["Crea o riporta in primo piano LayoutWindow"]
B --> C["LayoutWindow.__init__()"]
C --> D["Costruisce toolbar, host matrice, statistiche"]
D --> E["_load_corsie()"]
E --> F["AsyncRunner.run(query_json SQL corsie)"]
F --> G["_on_select() sulla corsia iniziale"]
G --> H["_load_matrix(corsia)"]
H --> I["AsyncRunner.run(query_json SQL matrice)"]
I --> J["_rebuild_matrix()"]
J --> K["_refresh_stats()"]
```
## Ricerca UDC
```{mermaid}
flowchart TD
A["Utente inserisce barcode"] --> B["_search_udc()"]
B --> C["query_json ricerca pallet -> corsia/colonna/fila"]
C --> D{"UDC trovata?"}
D -- No --> E["Messaggio informativo"]
D -- Si --> F["Seleziona corsia in listbox"]
F --> G["_load_matrix(corsia)"]
G --> H["_rebuild_matrix()"]
H --> I["_highlight_cell_by_labels()"]
```
## Schema di chiamata essenziale
```{mermaid}
flowchart LR
Init["__init__"] --> Top["_build_top"]
Init --> Host["_build_matrix_host"]
Init --> Stats["_build_stats"]
Init --> LoadCorsie["_load_corsie"]
LoadCorsie --> Select["_on_select"]
Select --> LoadMatrix["_load_matrix"]
LoadMatrix --> Rebuild["_rebuild_matrix"]
Rebuild --> RefreshStats["_refresh_stats"]
Search["_search_udc"] --> LoadMatrix
Export["_export_xlsx"] --> MatrixState["matrix_state / fila_txt / col_txt / udc1"]
```
## Note
- Il modulo usa un token `_req_counter` per evitare che risposte async vecchie
aggiornino la UI fuori ordine.
- La statistica globale viene ricalcolata da query SQL, mentre quella della
corsia corrente usa la matrice già caricata in memoria.
- `destroy()` marca la finestra come non più attiva per evitare callback tardive.

45
docs/flows/main_flow.md Normal file
View File

@@ -0,0 +1,45 @@
# `main.py`
## Scopo
`main.py` è il punto di ingresso dell'applicazione desktop. Inizializza il loop
asincrono condiviso, crea il client database condiviso e costruisce il launcher
con i pulsanti che aprono i moduli operativi.
## Flusso principale
```{mermaid}
flowchart TD
A["Avvio di main.py"] --> B["Configura policy asyncio su Windows"]
B --> C["Ottiene loop globale con get_global_loop()"]
C --> D["Imposta il loop come default"]
D --> E["Costruisce DSN SQL Server"]
E --> F["Crea AsyncMSSQLClient condiviso"]
F --> G["Istanzia Launcher"]
G --> H["Mostra finestra principale"]
H --> I{"Click su un pulsante"}
I --> J["open_reset_corsie_window()"]
I --> K["open_layout_window()"]
I --> L["open_celle_multiple_window()"]
I --> M["open_search_window()"]
I --> N["open_pickinglist_window()"]
```
## Schema di chiamata
```{mermaid}
flowchart LR
Launcher["Launcher.__init__"] --> Reset["open_reset_corsie_window"]
Launcher --> Layout["open_layout_window"]
Launcher --> Ghost["open_celle_multiple_window"]
Launcher --> Search["open_search_window"]
Launcher --> Pick["open_pickinglist_window"]
Pick --> PickFactory["create_pickinglist_frame"]
```
## Note
- `db_app` viene creato una sola volta e poi passato a tutte le finestre.
- Alla chiusura del launcher viene chiamato `db_app.dispose()` sul loop globale.
- `open_pickinglist_window()` costruisce la finestra in modo nascosto e la rende
visibile solo a layout pronto, per ridurre lo sfarfallio iniziale.

View File

@@ -0,0 +1,45 @@
# `reset_corsie.py`
## Scopo
Questo modulo mostra il riepilogo di una corsia e permette, dopo doppia
conferma, di cancellare i record di `MagazziniPallet` collegati a quella corsia.
## Flusso operativo
```{mermaid}
flowchart TD
A["open_reset_corsie_window()"] --> B["ResetCorsieWindow.__init__()"]
B --> C["_build_ui()"]
C --> D["_load_corsie()"]
D --> E["query_json SQL_CORSIE"]
E --> F["Seleziona corsia iniziale"]
F --> G["refresh()"]
G --> H["query_json SQL_RIEPILOGO"]
G --> I["query_json SQL_DETTAGLIO"]
H --> J["Aggiorna contatori"]
I --> K["Aggiorna tree celle occupate"]
```
## Flusso distruttivo
```{mermaid}
flowchart TD
A["Click su Svuota corsia"] --> B["_ask_reset()"]
B --> C["query_json SQL_COUNT_DELETE"]
C --> D{"Record da cancellare > 0?"}
D -- No --> E["Messaggio: niente da rimuovere"]
D -- Si --> F["Richiesta conferma testuale"]
F --> G{"Testo corretto?"}
G -- No --> H["Annulla operazione"]
G -- Si --> I["_do_reset(corsia)"]
I --> J["query_json SQL_DELETE"]
J --> K["Messaggio completato"]
K --> L["refresh()"]
```
## Note
- È il modulo più delicato lato operazioni, perché esegue `DELETE`.
- La finestra separa chiaramente fase di ispezione e fase distruttiva.
- Tutte le query passano dal client condiviso tramite `AsyncRunner`.

View File

@@ -0,0 +1,43 @@
# `search_pallets.py`
## Scopo
Questo modulo consente di cercare pallet/UDC, lotti e codici prodotto su tutto
il magazzino e di esportare i risultati.
## Flusso operativo
```{mermaid}
flowchart TD
A["open_search_window()"] --> B["SearchWindow.__init__()"]
B --> C["_build_ui()"]
C --> D["Utente compila filtri"]
D --> E["_do_search()"]
E --> F{"Filtri vuoti?"}
F -- Si --> G["Richiesta conferma ricerca globale"]
F -- No --> H["Prepara parametri SQL"]
G --> H
H --> I["AsyncRunner.run(query_json SQL_SEARCH)"]
I --> J["_ok()"]
J --> K["Popola Treeview"]
K --> L["Eventuale reset campi"]
```
## Ordinamento ed export
```{mermaid}
flowchart TD
A["Doppio click su header"] --> B["_on_heading_double_click()"]
B --> C["_sort_by_column()"]
C --> D["Riordina righe del Treeview"]
E["Click Export XLSX"] --> F["_export_xlsx()"]
F --> G["Legge righe visibili"]
G --> H["Scrive workbook Excel"]
```
## Note
- Il modulo usa `Treeview` come backend principale.
- Le ricerche possono essere molto ampie: per questo, senza filtri, viene chiesta conferma.
- `IDCella = 9999` viene evidenziata con uno stile dedicato.

View File

@@ -0,0 +1,58 @@
# `view_celle_multiple.py`
## Scopo
Questo modulo esplora le celle che contengono più pallet del previsto,
organizzando i risultati in un albero:
- corsia
- cella duplicata
- pallet contenuti nella cella
## Flusso operativo
```{mermaid}
flowchart TD
A["open_celle_multiple_window()"] --> B["CelleMultipleWindow.__init__()"]
B --> C["_build_layout()"]
C --> D["_bind_events()"]
D --> E["refresh_all()"]
E --> F["_load_corsie()"]
E --> G["_load_riepilogo()"]
F --> H["query_json SQL_CORSIE"]
G --> I["query_json SQL_RIEPILOGO_PERCENTUALI"]
H --> J["_fill_corsie()"]
I --> K["_fill_riepilogo()"]
```
## Lazy loading dell'albero
```{mermaid}
flowchart TD
A["Espansione nodo tree"] --> B["_on_open_node()"]
B --> C{"Nodo corsia o nodo cella?"}
C -- Corsia --> D["_load_celle_for_corsia()"]
D --> E["query_json SQL_CELLE_DUP_PER_CORSIA"]
E --> F["_fill_celle()"]
C -- Cella --> G["_load_pallet_for_cella()"]
G --> H["query_json SQL_PALLET_IN_CELLA"]
H --> I["_fill_pallet()"]
```
## Schema di chiamata
```{mermaid}
flowchart LR
Refresh["refresh_all"] --> Corsie["_load_corsie"]
Refresh --> Riep["_load_riepilogo"]
Open["_on_open_node"] --> LoadCelle["_load_celle_for_corsia"]
Open --> LoadPallet["_load_pallet_for_cella"]
Export["export_to_xlsx"] --> Tree["tree dati dettaglio"]
Export --> Sum["sum_tbl riepilogo"]
```
## Note
- L'albero è caricato a richiesta, non tutto in una sola query.
- Questo riduce il costo iniziale e rende il modulo più scalabile.
- L'export legge sia il dettaglio dell'albero sia la tabella di riepilogo.

16
docs/index.rst Normal file
View File

@@ -0,0 +1,16 @@
Warehouse Documentation
=======================
Questa documentazione raccoglie:
- riferimento API generato dal codice Python;
- diagrammi di flusso in Markdown/Mermaid;
- vista architetturale complessiva del progetto.
.. toctree::
:maxdepth: 2
:caption: Contenuti
architecture
api_reference
flows/index

18
docs/make.bat Normal file
View File

@@ -0,0 +1,18 @@
@ECHO OFF
set SPHINXBUILD=sphinx-build
set SOURCEDIR=.
set BUILDDIR=_build
if "%1" == "" goto help
%SPHINXBUILD% -b %1 %SOURCEDIR% %BUILDDIR%/%1
GOTO end
:help
ECHO.Usage: make.bat ^<builder^>
ECHO.
ECHO.Example:
ECHO. make.bat html
:end

3
docs/requirements.txt Normal file
View File

@@ -0,0 +1,3 @@
sphinx>=8.0
myst-parser>=4.0
sphinxcontrib-mermaid>=1.0