diff --git a/fhem/webfrontend/pgm2/01_FHEMWEB.pm b/fhem/webfrontend/pgm2/01_FHEMWEB.pm index e113ef3ed..a419bb6a3 100755 --- a/fhem/webfrontend/pgm2/01_FHEMWEB.pm +++ b/fhem/webfrontend/pgm2/01_FHEMWEB.pm @@ -2,11 +2,6 @@ # $Id$ package main; -# -# #Todo: -# 3) logical icons should contain no extension, initial icon search uses any graphics type of png, gif, jpg - - use strict; use warnings; use TcpServerUtils; @@ -98,6 +93,12 @@ my $FW_chash; # client fhem hash my $FW_encoding="UTF-8"; +my $ICONEXTENSION = "gif|ico|png|jpg"; # don't forget to amend FW_ServeSpecial if you change this! + +# FIXME +# use constant FOO => BAR +# is better but then I cannot use FOO in a regexp. Any ideas how to fix it? + ##################################### sub FHEMWEB_Initialize($) @@ -306,7 +307,7 @@ FW_ServeSpecial($$$) { #Debug "We serve $dir/$file.$ext"; open(FH, "$dir/$file.$ext") || return 0; - binmode(FH) if($ext =~ m/gif|png|jpg/); # necessary for Windows + binmode(FH) if($ext =~ m/$ICONEXTENSION/); # necessary for Windows FW_pO join("", ); close(FH); $FW_RETTYPE = "text/plain" if($ext eq "txt"); @@ -316,6 +317,7 @@ FW_ServeSpecial($$$) { $FW_RETTYPE = "image/jpeg" if($ext eq "jpg"); $FW_RETTYPE = "image/png" if($ext eq "png"); $FW_RETTYPE = "image/gif" if($ext eq "gif"); + $FW_RETTYPE = "image/x-icon" if($ext eq "ico"); return 1; } @@ -422,7 +424,7 @@ FW_AnswerCall($) $cachable = 0; return 0 if(!$icon); } - $FW_icons{$icon} =~ m/(.*)\.(gif|jpg|png)/; + $FW_icons{$icon} =~ m/(.*)\.($ICONEXTENSION)/; my ($file,$ext)= ($1,$2); if(FW_ServeSpecial($file,$ext,$FW_icondir)) { @@ -536,7 +538,7 @@ FW_AnswerCall($) # Enable WebApp if($FW_tp || $FW_ss) { - FW_pO ''; + FW_pO ''; FW_pO ''; if($FW_ss) { FW_pO ''; @@ -937,9 +939,8 @@ FW_roomOverview($) if($idx", $l1 eq $FW_room ? " class=\"sel\"" : ""; - my $icon = ""; - $icon = " " - if($FW_icons{"ico${l1}.png"}); + # image tag if we have an icon, else empty + my $icon= $FW_icons{"ico${l1}"} ? FW_makeImage("ico${l1}") . " " : ""; if($l2 =~ m/.html$/ || $l2 =~ m/^http/) { FW_pO "$icon$l1"; @@ -1005,6 +1006,9 @@ FW_showRoom() pF "\n", ($row&1)?"odd":"even"; my $devName = AttrVal($d, "alias", $d); my $icon = AttrVal($d, "icon", ""); + if($icon =~ m/^(.*)\.($ICONEXTENSION)$/) { + $icon= $1; # silently remove the extension + } $icon = FW_makeImage($icon) . " " if($icon); if($FW_hiddenroom{detail}) { @@ -1172,10 +1176,10 @@ FW_logWrapper($) } else { FW_pO "
"; FW_pO "
"; - FW_zoomLink("cmd=$cmd;zoom=-1", "Zoom-in.png", "zoom in"); - FW_zoomLink("cmd=$cmd;zoom=1", "Zoom-out.png","zoom out"); - FW_zoomLink("cmd=$cmd;off=-1", "Prev.png", "prev"); - FW_zoomLink("cmd=$cmd;off=1", "Next.png", "next"); + FW_zoomLink("cmd=$cmd;zoom=-1", "Zoom-in", "zoom in"); + FW_zoomLink("cmd=$cmd;zoom=1", "Zoom-out","zoom out"); + FW_zoomLink("cmd=$cmd;off=-1", "Prev", "prev"); + FW_zoomLink("cmd=$cmd;off=1", "Next", "next"); FW_pO "
"; FW_pO ""; my $logtype = $defs{$d}{TYPE}; @@ -1954,10 +1958,10 @@ FW_showWeblink($$$$) ($defs{$d}{WLTYPE} eq "fileplot" || $defs{$d}{WLTYPE} eq "dbplot")&& !AttrVal($d, "fixedrange", undef)) { - FW_zoomLink("zoom=-1", "Zoom-in.png", "zoom in"); - FW_zoomLink("zoom=1", "Zoom-out.png","zoom out"); - FW_zoomLink("off=-1", "Prev.png", "prev"); - FW_zoomLink("off=1", "Next.png", "next"); + FW_zoomLink("zoom=-1", "Zoom-in", "zoom in"); + FW_zoomLink("zoom=1", "Zoom-out","zoom out"); + FW_zoomLink("off=-1", "Prev", "prev"); + FW_zoomLink("off=1", "Next", "next"); $buttons = 0; FW_pO "
"; } @@ -2013,7 +2017,7 @@ FW_Attr(@) sub FW_ReadIconsFrom($$) { - # recursively reads .gif .jpg .png files and returns filenames as array + # recursively reads .gif .ico .jpg .png files and returns filenames as array # recursion starts at $FW_icondir/$dir # filenames are relative to $FW_icondir @@ -2023,27 +2027,23 @@ FW_ReadIconsFrom($$) { my (@entries, @filenames); if(opendir(DH, "${FW_icondir}/${dir}")) { - @entries= sort readdir(DH); # assures order: .gif .jpg .png + @entries= sort readdir(DH); # assures order: .gif .ico .jpg .png closedir(DH); } #Debug "$#entries entries found."; foreach my $entry (@entries) { my $filename= "$dir/$entry"; - my $iconname= "${prepend}${entry}"; - #Debug " entry: \"$entry\", filename= \"$filename\", iconname= \"$iconname\""; + #Debug " entry: \"$entry\", filename= \"$filename\""; if( -d "${FW_icondir}/${filename}" ) { # entry is a directory - FW_ReadIconsFrom("${iconname}/", $filename) unless($entry eq "." || $entry eq ".."); + FW_ReadIconsFrom("${prepend}${entry}/", $filename) unless($entry eq "." || $entry eq ".."); } elsif( -f "${FW_icondir}/${filename}") { # entry is a regular file - if($entry =~ m/\.(png|gif|jpg)$/i) { - # extension is .gif .jpg .png - #my $basename= $entry; - #$basename =~ s/\.[^.]+$//; # cut extension - # priority due to sort: .png (highest) to .gif (lowest) - #$FW_icons{"${prepend}${basename}"}= $filenamerel; - # store icon with extension - $FW_icons{"${prepend}${entry}"}= $filename; + if($entry =~ m/^(.*)\.($ICONEXTENSION)$/i) { + my $logicalname= $1; + my $iconname= "${prepend}${logicalname}"; + #Debug " icon: \"$iconname\""; + $FW_icons{$iconname}= $filename; } } } @@ -2084,11 +2084,21 @@ FW_GetIcons() { %FW_icons= split(":", $hash->{fhem}{icons}); } +sub +FW_canonicalizeIcon($) { + my ($name)= @_; + if($name =~ m/^(.*)\.($ICONEXTENSION)$/) { + Log 1, "WARNING: argument of FW_canonicalizeIcon($name) has extension - inform the developers!"; + $name= $1; + } + return $name; +} + sub FW_getIcon($) { my ($name)= @_; - my $icon= "$name.png"; # FIXME - return $FW_icons{$icon} ? $icon : undef; + $name= FW_canonicalizeIcon($name); + return $FW_icons{$name} ? $name : undef; } # returns the physical absolute path relative for the logical path @@ -2097,10 +2107,8 @@ FW_getIcon($) { # weather/sunny -> $FW_icondir/default/weather/sunny.gif sub FW_IconPath($) { - my ($name)= @_; - $name =~ s/\.(png)$//; # FIXME - $name= "${name}.png"; # FIXME + $name= FW_canonicalizeIcon($name); FW_GetIcons(); # get the icon set for the current instance my $path= $FW_icons{$name}; return $path ? $FW_icondir. $path : undef; @@ -2112,8 +2120,8 @@ FW_IconPath($) { # weather/sunny -> /icons/sunny sub FW_IconURL($) { my ($name)= @_; - $name =~ s/\.(png)$//; # FIXME - return "$FW_ME/icons/${name}.png"; # FIXME + $name= FW_canonicalizeIcon($name); + return "$FW_ME/icons/${name}"; } diff --git a/fhem/webfrontend/pgm2/95_FLOORPLAN.pm b/fhem/webfrontend/pgm2/95_FLOORPLAN.pm index be39a8a97..639848763 100644 --- a/fhem/webfrontend/pgm2/95_FLOORPLAN.pm +++ b/fhem/webfrontend/pgm2/95_FLOORPLAN.pm @@ -1,5 +1,6 @@ ################################################################################ # 95 FLOORPLAN +# $Id $ # Feedback: http://groups.google.com/group/fhem-users # Define Custom Floorplans # Released : 26.02.2012 @@ -302,7 +303,7 @@ FP_htmlHeader($) { FW_pO "".$title.""; # Enable WebApp if($FW_tp || $FW_ss) { - FW_pO ""; + FW_pO ""; FW_pO ""; if($FW_ss) { FW_pO ""; @@ -314,13 +315,17 @@ FP_htmlHeader($) { my $rf = AttrVal($FW_wname, "refresh", ""); FW_pO "" if($rf); # use refresh-value from Web-Instance # stylesheet - if ($FP_name) { - my $prf = AttrVal($FP_name, "fp_stylesheetPrefix", ""); - FW_pO (""); #use floorplanstyle.css for floorplans, evtl. with fp_stylesheetPrefix #20120730 0017 - } else { - my $css = AttrVal($FW_wname, "stylesheetPrefix", "") . "floorplanstyle.css"; - FW_pO ""; #use floorplanstyle.css (incl. FW-stylesheetPrefix) for fp-start-screen #20120730 0017 - } + # removed the option to have different styles for FHEMWEB and FLOORPLAN + # if ($FP_name) { + # my $prf = AttrVal($FP_name, "fp_stylesheetPrefix", ""); + # FW_pO (""); #use floorplanstyle.css for floorplans, evtl. with fp_stylesheetPrefix #20120730 0017 + # } else { + # my $css = AttrVal($FW_wname, "stylesheetPrefix", "") . "floorplanstyle.css"; + # FW_pO ""; #use floorplanstyle.css (incl. FW-stylesheetPrefix) for fp-start-screen #20120730 0017 + # } + my $css = AttrVal($FW_wname, "stylesheetPrefix", "") . "floorplanstyle.css"; + FW_pO ""; + #set sripts FW_pO "" if($FW_plotmode eq "SVG"); @@ -354,7 +359,7 @@ FP_showStart() { FW_pO '
'; FW_pO "



No floorplans have been defined yet. For definition, use
"; FW_pO "
    define <name> FLOORPLAN
"; - FW_pO 'Also check the commandref
'; + FW_pO 'Also check the commandref
'; FW_pO "
"; } FW_pO ""; @@ -369,7 +374,7 @@ FP_show(){ ## body FW_pO "\n"; FW_pO "
"; - FW_pO ""; # alternative: jpg - how? #20120730 0017 + FW_pO FW_makeImage("fp_$FP_name"); FW_pO "
\n"; ## menus @@ -392,7 +397,7 @@ FP_show(){ foreach my $d (sort keys %defs) { # loop all devices my $type = $defs{$d}{TYPE}; my $attr = AttrVal("$d","fp_$FP_name", undef); - next if(!$attr || $type eq "weblink"); # skip if device-attribute not set for current floorplan-name + next if(!$attr || $type eq "weblink"); # skip if device-attribute not set for current floorplan-name my ($top, $left, $style, $text, $text2) = split(/,/ , $attr); # $top = position in px, top @@ -407,6 +412,7 @@ FP_show(){ FW_pO "
"; FW_pO " "; # Main table per device my ($allSets, $cmdlist, $txt) = FW_devState($d, ""); + #Debug "txt is \"$txt\""; $txt = ReadingsVal($d, $text, "Undefined Reading $d-$text") if ($style == 3); # Style3 = DeviceReading given in $text my $cols = ($cmdlist ? (split(":", $cmdlist)) : 0); # Need command-count for colspan of devicename+state @@ -430,20 +436,20 @@ FP_show(){ ######################## # Device-state per device - FW_pO ""; # For css: class=devicestate, id=devicename + FW_pO ""; # For css: class=devicestate, id=devicename $txt =~ s/measured-temp: ([\.\d]*) \(Celsius\)/$1/; # format FHT-temperature - ### use device-specific icons according to userattr fp_image or fp_.image - my $fp_image = AttrVal("$d", "fp_image", undef); # floorplan-independent icon + ### use device-specific icons according to userattr fp_image or fp_.image + my $fp_image = AttrVal("$d", "fp_image", undef); # floorplan-independent icon my $fp_fpimage = AttrVal("$d","fp_$FP_name".".image", undef); # floorplan-dependent icon if ($fp_image) { my $state = ReadingsVal($d, "state", undef); - $fp_image =~ s/\{state\}/$state/; # replace {state} by actual device-status - $txt =~ s/\$txt"; FW_pO ""; diff --git a/fhem/webfrontend/pgm2/darkfloorplanstyle.css b/fhem/webfrontend/pgm2/darkfloorplanstyle.css index c61b7cff5..8915658c8 100644 --- a/fhem/webfrontend/pgm2/darkfloorplanstyle.css +++ b/fhem/webfrontend/pgm2/darkfloorplanstyle.css @@ -1,8 +1,8 @@ -body { background-color: #444444; font-family:Verdana; font-size:9px; background-image:url(darklogo.png); background-repeat:no-repeat; } -body[id~=Media] { background-color: #A5A5A5; font-family:Verdana; font-size:9px; background-image:url(Media.bak.png); background-repeat:no-repeat; } +body { background-color: #444444; font-family:Verdana; font-size:9px; background-image:url(../icons/darklogo); background-repeat:no-repeat; } +body[id~=Media] { background-color: #A5A5A5; font-family:Verdana; font-size:9px; background-image:url(../icons/Media.bak); background-repeat:no-repeat; } #backimg {position:absolute; top:15px; left:190px;} -#logo { position:absolute; top: 10px; left: 10px; width:180px; height:600px; background-image:url(darklogo.png); visibility:hidden;} +#logo { position:absolute; top: 10px; left: 10px; width:180px; height:600px; background-image:url(../icons/darklogo); visibility:hidden;} #fpmenu.fp_arrange { position:absolute; bottom:20px; left:30px; min-width:310px; font-size:9px; border:1px solid #CCCCCC; background: #111111; -moz-border-radius:8px; border-radius:8px; border-spacing: 6px; padding: 6px; box-shadow:5px 5px 5px #000; } diff --git a/fhem/webfrontend/pgm2/darkstyle.css b/fhem/webfrontend/pgm2/darkstyle.css index 44ebebad7..36249f275 100644 --- a/fhem/webfrontend/pgm2/darkstyle.css +++ b/fhem/webfrontend/pgm2/darkstyle.css @@ -1,5 +1,5 @@ /* Author: Till */ -body { background-color: #444444; background-image:url(../icons/darklogo.png); background-repeat:no-repeat; color: #CCCCCC; font-family:Arial, Helvetica, sans-serif; font-size:13px;} +body { background-color: #444444; background-image:url(../icons/darklogo); background-repeat:no-repeat; color: #CCCCCC; font-family:Arial, Helvetica, sans-serif; font-size:13px;} #logo { position:absolute; top:10px; left:20px; width:140px; visibility:hidden; } #menu { position:absolute; top:170px;left:20px; width:140px; } #hdr { position:absolute; top:10px; left:180px; } diff --git a/fhem/webfrontend/pgm2/floorplanstyle.css b/fhem/webfrontend/pgm2/floorplanstyle.css index 03dcfa0ba..d76ee820b 100644 --- a/fhem/webfrontend/pgm2/floorplanstyle.css +++ b/fhem/webfrontend/pgm2/floorplanstyle.css @@ -1,16 +1,16 @@ body { background-color: #F0F0F0; font-family:Arial, sans-serif; - font-size:9px; background-image:url(Grundriss.bak.png); + font-size:9px; background-image:url(../icons/Grundriss.bak); background-repeat:no-repeat; } body[id~=Media] { background-color: #A5A5A5; font-family:Arial, sans-serif; font-size:9px; - background-image:url(Media.bak.png); + background-image:url(../icons/Media.bak); background-repeat:no-repeat; } #logo { position:absolute; top: 10px; left: 10px; - width:64px; height:67px; background-image:url(fhem_smallscreen.png); } + width:64px; height:67px; background-image:url(../icons/fhem_smallscreen); } #backimg {position:absolute; top:15px; left:190px;} #menu { position:absolute; top:120px; left:20px; min-width:60px; } #menu.floorplan { position:absolute; top:120px; left:20px; min-width:80px; font-size:14px; line-height:22px; } diff --git a/fhem/webfrontend/pgm2/smallscreenstyle.css b/fhem/webfrontend/pgm2/smallscreenstyle.css index 669a18eb1..d749e3024 100644 --- a/fhem/webfrontend/pgm2/smallscreenstyle.css +++ b/fhem/webfrontend/pgm2/smallscreenstyle.css @@ -5,7 +5,7 @@ input { font-family:Arial, sans-serif; font-size:16px;} select { font-family:Arial, sans-serif; font-size:16px;} #back { position:absolute; top: 2px; left:18px; } #logo { position:absolute; top: 2px; left: 2px; - width:64px; height:67px; background-image:url(../icons/fhemicon.png); } + width:64px; height:67px; background-image:url(../icons/fhemicon); } #menu { position:absolute; top: 2px; left:65px; } #hdr { position:absolute; top:40px; left:65px; } #content { position:absolute; top:85px; left: 0px; right: 0px;} diff --git a/fhem/webfrontend/pgm2/style.css b/fhem/webfrontend/pgm2/style.css index d2142787d..6aabfc123 100644 --- a/fhem/webfrontend/pgm2/style.css +++ b/fhem/webfrontend/pgm2/style.css @@ -4,7 +4,7 @@ input { font-family:Arial, sans-serif; font-size:16px; } select { font-family:Arial, sans-serif; font-size:16px; } #logo { position:fixed; top:10px; left:20px; - width:100px; height:105px; background-image:url(../icons/fhemicon.png); } + width:100px; height:105px; background-image:url(../icons/fhemicon); } #menu { position:fixed; top:120px;left:20px; width:140px; } #hdr { position:absolute; top:10px; left:180px; } #content { position:absolute; top:50px; left:180px; bottom:20px; right:10px; } diff --git a/fhem/webfrontend/pgm2/touchpadstyle.css b/fhem/webfrontend/pgm2/touchpadstyle.css index e0567d2a1..6c99f6cab 100644 --- a/fhem/webfrontend/pgm2/touchpadstyle.css +++ b/fhem/webfrontend/pgm2/touchpadstyle.css @@ -5,7 +5,7 @@ textarea { font-family:Arial, sans-serif; font-size:16px} input { font-family:Arial, sans-serif; font-size:16px} select { font-family:Arial, sans-serif; font-size:16px} #logo { position:absolute; top:10px; left:10px; - width:100px; height:105px; background-image:url(fhem.png); } + width:100px; height:105px; background-image:url(fhem); } #menu { position:absolute; top:120px;left:10px; width:100px; } #hdr { position:absolute; top:10px; left:140px; } #content { position:absolute; top:50px; left:140px; bottom:20px; right:10px; }