1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
|
#! /bin/sh
# restart with wish \
exec wish "$0"
#
# Name : dfm-open_dir.tcl
# Zweck: Eingabedialog zum ffnen eines DFM-Verzeichnisfensters.
# Autor: Christian V. J. Brssow <cvjb@bigfoot.de>
# Stand: Mit 03 Feb 1999 19:05:50 MET
# Notiz: BETA; en_GB (Skript wurde mit TAB=3 geschrieben; VIM)
# BESCHREIBUNG
#
# Stellt einen Eingabedialog mit einer Eingabezeile fr Verzeichnispfade
# dar. Das in dieser Eingabezeile angegebene Verzeichnis kann durch
# Drcken der Enter-Taste mit dem DFM geffnet werden; Aufruf: dfm <verz>.
# Tritt beim Start des DFM ein Fehler auf, so wird dies gemeldet.
#
# Existiert das Verzeichnis nicht, so wird eine entsprechende Meldung
# ausgegeben. Der Benutzer kann seine Eingabe anschlieend korrigieren.
# DFM wird nicht gestartet.
#
# Ist die Eingabe nicht komplett oder ist sich der Anwender nicht sicher,
# ob das Verzeichnis existiert bzw. kennt nicht den kompletten Namen, so
# kann durch Drcken der Tabulator-Taste eine Dateinamenexpansion
# eingeleitet werden; hnlich wie z.B. bei der Bash.
# Schlgt die Expansion fehl, so wird dies angezeigt.
# Ist die Expansion nicht eindeutig, so wird dies ebenfalls angezeigt,
# auerdem werden die mglichen Lsungen ausgegeben.
#
# Durch Drcken der Escape-Taste wird das Programm abgebrochen. DFM wird
# nicht gestartet.
#
# Durch Drcken der F1-Taste erhlt der Anwender eine kurze Angabe der
# Tastenbelegung. DFM wird nicht gestartet.
# VORGABEN
# Name des DFM-Programms. Ist DFM nicht im Suchpfad enthalten, so
# kann hier der komplette Pfad angegeben werden.
set DFM dfm
# Vorgabe im Eingabefeld ist das Home-Verzeichnis.
set dir $env(HOME)
# PROZEDUREN
# Ersatz fr tk_dialog.
# Setzt im Gegensatz zu tk_dialog die Schrift fr die Meldung
# nicht explizit.
# Steht hier, damit dieses Skript portabel bleibt. Bei dem Autor selbst
# wird diese Funktion durch sog. Autoloading aus einer Library geladen.
proc new_tk_dialog {w title text bitmap default args} {
global tk_priv
# Toplevelfenster erstellen.
catch {destroy $w}
toplevel $w -class Dialog
wm title $w $title
wm iconname $w Dialog
# Fenster in zwei Hauptframes vertikal unterteilen.
# Oberer Hauptframe.
frame $w.top -relief raised -borderwidth 1
pack $w.top -side top -fill both
# Im oberen Frame wird die gewnschte Nachricht angezeigt.
message $w.top.msg -aspect 320 -text $text
pack $w.top.msg -side right -expand 1 -fill both -padx 5m -pady 5m
# Ebenso wird optional, links neben der Nachricht eine Bitmap
# ausgegebe.
if {$bitmap != ""} {
label $w.top.bitmap -bitmap $bitmap
pack $w.top.bitmap -side left -padx 5m -pady 5m
}
# Unterer Hauptframe.
frame $w.bot -relief raised -borderwidth 1
pack $w.bot -side bottom -fill both
# Im unteren Frame werden die angegebene Schalter positioniert.
# Falls angegeben, wird der Vorgabeschalter gesondert hervorgehoben.
set i 0
foreach but $args {
button $w.button$i -text $but -command "set tk_priv(button) $i"
if {$i == $default} {
# Vorgabeschalter.
frame $w.bot.default -relief sunken -borderwidth 1
raise $w.button$i $w.bot.default
pack $w.bot.default -side left -expand 1 -padx 2m -pady 1m
pack $w.button$i -in $w.bot.default -padx 1m -pady 1m -ipadx 0m -ipady 0m
bind $w <Return> "$w.button$i flash ; set tk_priv(button) $i"
} else {
# Normaler Schalter.
pack $w.button$i -in $w.bot -side left -expand 1 -padx 2m -pady 2m\
-ipadx 0m -ipady 0m
}
incr i
}
# Das Fenster komplett vom Schirm entfernen, sein Layout aktualisieren.
# Dann in der Mitte des Bildschirms positionieren; Angaben hierzu werden
# aus seiner aktuellen Gre berechnet. Wenn alles klar ist, dann das
# Fenster wieder auf dem Schirm darstellen.
wm withdraw $w
update idletasks
set x [expr [winfo screenwidth $w]/2 - [winfo reqwidth $w]/2 \
- [winfo vrootx [winfo parent $w]]]
set y [expr [winfo screenheight $w]/2 - [winfo reqheight $w]/2 \
- [winfo vrooty [winfo parent $w]]]
wm geometry $w +$x+$y
wm deiconify $w
# Das Fenster erhlt den Focus und den Grab; Vorgngerfocus wird
# aber gesichert.
set old_focus [focus]
grab $w
focus $w
# Jetzt solange warten, bis der Benutzer einen Knopf bettigt.
# Dann das Fenster lschen und den alten Focus wieder herstellen.
# Zuletzt wird die Kennung des gedrckten Knopfs als Funktionswert
# zurckgeliefert.
tkwait variable tk_priv(button)
destroy $w
focus $old_focus
return $tk_priv(button)
}
# Prfen, ob $dir ein Verzeichnis ist/existiert.
# Wenn ja, dann wird 1 zurckgeliefert. Wenn nein, dann
# wird eine entsprechende Meldung angezeigt und 0
# zurckgeliefert.
proc is_dir dir {
if [file isdirectory $dir] {
return 1
} else {
new_tk_dialog .err_d {Fehler} \
"$dir: no such directory. Typo?" \
error 0 { Ok }
return 0
}
}
# Verzeichnis mit DFM ffnen.
proc start_dfm dir {
global DFM
if [is_dir $dir] {
if ![catch { exec $DFM $dir & } ] {
exit
} else {
new_tk_dialog .err_d {Error} \
{Execution of DFM has failed} \
error 0 { Ok }
exit 1
}
}
}
# Expandiere die Zeichenkette zu einem passenden Verzeichnis,
# wenn es solch eines gibt. Schlgt der Expansionsversuch fehl,
# so wird $dir unverndert zurck gegeben.
proc expand_dir dir {
# Expansion vornehmen.
set expanded_dir [ glob -nocomplain $dir\* ]
# War die Expansion erfolgreich?
set l [ llength $expanded_dir ]
if { $l == 0 } {
# Nein: Expansion vollstndig fehlgeschlagen!
set msg "There is no directory starting with $dir!"
new_tk_dialog .msg_d {Completion not possible} $msg error 0 { Ok }
return $dir
} elseif { $l == 1 } {
# Ja: expandierter Verzeichnispfad wird zurck geliefert.
return $expanded_dir
} else {
# Nein: Ergebnis war nicht eindeutig, d.h. Angabe in $dir ist zu kurz.
set msg "Possible completions:\n$expanded_dir"
new_tk_dialog .msg_d {Insufficient statement} $msg warning 0 { Ok }
return $dir
}
}
# Kurze Hilfe ausgeben.
proc help {} {
new_tk_dialog .help_d {Help} {Keys:
Enter : open given directory with DFM
Esc : cancel execution
Tab : try completion of given dir.
F1 : show this short help
} question 0 { OK }
}
# WIDGETS DEFINIEREN
frame .plane -relief raised -borderwidth 1
# Bezeichner fr die erwartete Eingabe.
label .plane.label -text "DIR:"
# Eingabezeile.
entry .plane.entry -textvariable dir -width 32 -relief sunken -borderwidth 1
# EVENTS
# Globale Events
# Return-Taste => Eingabe bernehmen und damit den DFM starten.
# ESC-Taste => Eingabe verwerfen und Programm abbrechen.
bind all <Return> {start_dfm $dir}
bind all <Escape> {exit}
bind all <F1> {help}
# Lokale Events
# TAB-Taste in Eingabezeile => Suche nach passendem Verzeichnis.
# ACHTUNG: das Standard-Binding fr TAB wird auer Kraft gesetzt.
bind .plane.entry <Tab> {set dir [expand_dir $dir]
.plane.entry icursor end
break}
# FOCUS
# Den Focus bekommt die Eingabezeile.
focus .plane.entry
# SELEKTION
# Die Vorgabe in der Eingabezeile wird markiert.
# Erleichtert schnelles berschreiben der Vorgabe.
.plane.entry selection range 0 end
# WIDGETS DARSTELLEN
# Zuerst die Unterwidgets.
pack .plane.label -side left -fill x
pack .plane.entry -side left -fill x -expand 1
# Zuletzt das Hauptwidget, dadurch erscheinen das Widgetensemble
# quasi auf einen Schlag.
pack .plane -fill x
# APPLIKATIONSFENSTER
# Das Fenster ist ein sog; transientes Fenster.
# Diese Fenster ist sein eigener Master! Dies ist ein etwas
# unsauberer Trick, um ein transientes Fenster ohne "wirkliches"
# Masterfenster zu erzeugen.
wm transient . .
# Fenster- und Icontitel.
wm title . "Open directory"
wm iconname . "open dir"
# Fixe Fenstergre.
wm geometry . {}
wm resizable . 0 0
# Fenster in der Bildschirmmitte positionieren.
# Zuerst mu die Fenstermitte bestimmt werden.
wm withdraw .
set x [expr [winfo screenwidth .]/2 - [winfo reqwidth .]/2 \
- [winfo vrootx .]]
set y [expr [winfo screenheight .]/2 - [winfo reqheight .]/2 \
- [winfo vrooty .]]
wm geometry . +$x+$y
wm deiconify .
# Explizit alles neu darstellen.
update idletasks
# vim: set tw=128 sw=3 ts=3 nocindent:
|