Skip to content

Commit 8ec440b

Browse files
authored
Merge f563381 into 85235ee
2 parents 85235ee + f563381 commit 8ec440b

3 files changed

Lines changed: 91 additions & 49 deletions

File tree

NEWS.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ https://github.com/networkupstools/nut/milestone/13
104104
* Introduced support for `CERTFILE` option, so the client can identify
105105
itself to the data server also in OpenSSL builds. [issue #3331]
106106

107+
- `NUT-Monitor` Python GUI client:
108+
* Fixed Qt tray tooltips to render in plain text, not rich text which
109+
ended up as literal HTML on KDE Plasma 6; now that rich text formatting
110+
is only used for main window status labels. [PR #3430]
111+
107112
- Introduced `ci_build.sh` settings and respective CI workflow settings
108113
to optionally re-use a `config.cache` file from older runs, and similar
109114
logic for NIT `nit.sh` to re-use generated certificate and private key

scripts/python/app/NUT-Monitor-py3qt5.in

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,16 @@ except Exception as ignored:
100100
os.chdir(os.path.dirname(os.path.abspath(os.path.realpath(__file__))))
101101
# print(os.getcwd())
102102

103+
def plain_status_text( text ) :
104+
document = QTextDocument()
105+
document.setHtml( text )
106+
return document.toPlainText()
107+
108+
def tooltip_value( value, unit="" ) :
109+
if isinstance( value, bytes ) :
110+
value = value.decode( 'ascii' )
111+
return "%s%s" % ( value, unit )
112+
103113
class interface :
104114

105115
DESIRED_FAVORITES_DIRECTORY_MODE = 0o700
@@ -858,7 +868,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
858868
self.__widgets["ups_infos"].hide()
859869
self.__widgets["ups_params_box"].setEnabled( True )
860870
self.__widgets["menu_favorites_root"].setEnabled( True )
861-
self.__widgets["status_icon"].setToolTip( _("<i>Not connected</i>") )
871+
self.__widgets["status_icon"].setToolTip( _("Not connected") )
862872
self.__widgets["ups_params_box"].show()
863873

864874
# Try to resize the main window...
@@ -900,16 +910,16 @@ class gui_updater :
900910
ups = self.__parent_class._interface__current_ups
901911

902912
# Define a dict containing different UPS status
903-
status_mapper = { b"LB" : "<font color=\"#BB0000\"><b>%s</b></font>" % _("Low batteries"),
904-
b"RB" : "<font color=\"#FF0000\"><b>%s</b></font>" % _("Replace batteries !"),
905-
b"ALARM" : "<font color=\"#FF0000\"><b>%s</b></font>" % _("Active alarms !"),
906-
b"BYPASS" : "<font color=\"#BB0000\">Bypass</font> <i>%s</i>" % _("(no battery protection)"),
907-
b"ECO" : _("In ECO mode (as defined by vendor)"),
908-
b"CAL" : _("Performing runtime calibration"),
909-
b"OFF" : "<font color=\"#000090\">%s</font> <i>(%s)</i>" % ( _("Offline"), _("not providing power to the load") ),
910-
b"OVER" : "<font color=\"#BB0000\">%s</font> <i>(%s)</i>" % ( _("Overloaded !"), _("there is too much load for device") ),
911-
b"TRIM" : _("Triming <i>(UPS is triming incoming voltage)</i>"),
912-
b"BOOST" : _("Boost <i>(UPS is boosting incoming voltage)</i>")
913+
status_mapper = { b"LB" : ( "<font color=\"#BB0000\"><b>%s</b></font>" % _("Low batteries"), _("Low batteries") ),
914+
b"RB" : ( "<font color=\"#FF0000\"><b>%s</b></font>" % _("Replace batteries !"), _("Replace batteries !") ),
915+
b"ALARM" : ( "<font color=\"#FF0000\"><b>%s</b></font>" % _("Active alarms !"), _("Active alarms !") ),
916+
b"BYPASS" : ( "<font color=\"#BB0000\">Bypass</font> <i>%s</i>" % _("(no battery protection)"), "%s %s" % ( _("Bypass"), _("(no battery protection)") ) ),
917+
b"ECO" : ( _("In ECO mode (as defined by vendor)"), _("In ECO mode (as defined by vendor)") ),
918+
b"CAL" : ( _("Performing runtime calibration"), _("Performing runtime calibration") ),
919+
b"OFF" : ( "<font color=\"#000090\">%s</font> <i>(%s)</i>" % ( _("Offline"), _("not providing power to the load") ), "%s (%s)" % ( _("Offline"), _("not providing power to the load") ) ),
920+
b"OVER" : ( "<font color=\"#BB0000\">%s</font> <i>(%s)</i>" % ( _("Overloaded !"), _("there is too much load for device") ), "%s (%s)" % ( _("Overloaded !"), _("there is too much load for device") ) ),
921+
b"TRIM" : ( _("Triming <i>(UPS is triming incoming voltage)</i>"), plain_status_text( _("Triming <i>(UPS is triming incoming voltage)</i>") ) ),
922+
b"BOOST" : ( _("Boost <i>(UPS is boosting incoming voltage)</i>"), plain_status_text( _("Boost <i>(UPS is boosting incoming voltage)</i>") ) )
913923
}
914924

915925
if not self.__stop_thread :
@@ -920,18 +930,22 @@ class gui_updater :
920930
# Text displayed on the status frame
921931
text_left = ""
922932
text_right = ""
923-
status_text = ""
933+
status_parts = []
934+
tooltip_status_parts = []
935+
tooltip_lines = []
924936

925937
text_left += "<b>%s</b><br>" % _("Device status :")
926938

927939
if ( vars.get(b"ups.status").find(b"OL") != -1 ) :
928-
text_right += "<font color=\"#009000\"><b>%s</b></font>" % _("Online")
940+
status_parts.append( "<font color=\"#009000\"><b>%s</b></font>" % _("Online") )
941+
tooltip_status_parts.append( _("Online") )
929942
if not self.was_online :
930943
self.__parent_class.change_status_icon( "on_line", blink=False )
931944
self.was_online = True
932945

933946
if ( vars.get(b"ups.status").find(b"OB") != -1 ) :
934-
text_right += "<font color=\"#900000\"><b>%s</b></font>" % _("On batteries")
947+
status_parts.append( "<font color=\"#900000\"><b>%s</b></font>" % _("On batteries") )
948+
tooltip_status_parts.append( _("On batteries") )
935949
if self.was_online :
936950
self.__parent_class.change_status_icon( "on_battery", blink=True )
937951
self.__parent_class.gui_status_notification( _("Device is running on batteries"), "on_battery.png" )
@@ -940,18 +954,19 @@ class gui_updater :
940954
# Check for additionnal information
941955
for k,v in status_mapper.items() :
942956
if vars.get(b"ups.status").find(k) != -1 :
943-
if ( text_right != "" ) :
944-
text_right += " - %s" % v
945-
else :
946-
text_right += "%s" % v
957+
status_parts.append( v[0] )
958+
tooltip_status_parts.append( v[1] )
947959

948960
# CHRG and DISCHRG cannot be trated with the previous loop ;)
949961
if ( vars.get(b"ups.status").find(b"DISCHRG") != -1 ) :
950-
text_right += " - <i>%s</i>" % _("discharging")
962+
status_parts.append( "<i>%s</i>" % _("discharging") )
963+
tooltip_status_parts.append( _("discharging") )
951964
elif ( vars.get(b"ups.status").find(b"CHRG") != -1 ) :
952-
text_right += " - <i>%s</i>" % _("charging")
965+
status_parts.append( "<i>%s</i>" % _("charging") )
966+
tooltip_status_parts.append( _("charging") )
953967

954-
status_text += text_right
968+
text_right += " - ".join( status_parts )
969+
tooltip_lines.append( "%s %s" % ( _("Device status :"), " - ".join( tooltip_status_parts ) ) )
955970
text_right += "<br>"
956971

957972
if ( b"ups.mfr" in vars ) :
@@ -960,14 +975,17 @@ class gui_updater :
960975
vars.get(b"ups.mfr",b"").decode('ascii'),
961976
vars.get(b"ups.model",b"").decode('ascii'),
962977
)
978+
tooltip_lines.append( "%s %s %s" % ( _("Model :"), tooltip_value( vars.get(b"ups.mfr",b"") ), tooltip_value( vars.get(b"ups.model",b"") ) ) )
963979

964980
if ( b"ups.temperature" in vars ) :
965981
text_left += "<b>%s</b><br>" % _("Temperature :")
966982
text_right += "%s<br>" % int( float( vars.get( b"ups.temperature", 0 ) ) )
983+
tooltip_lines.append( "%s %s" % ( _("Temperature :"), int( float( vars.get( b"ups.temperature", 0 ) ) ) ) )
967984

968985
if ( b"battery.voltage" in vars ) :
969986
text_left += "<b>%s</b><br>" % _("Battery voltage :")
970987
text_right += "%sv<br>" % (vars.get( b"battery.voltage", 0 ).decode('ascii'),)
988+
tooltip_lines.append( "%s %s" % ( _("Battery voltage :"), tooltip_value( vars.get( b"battery.voltage", 0 ), "v" ) ) )
971989

972990
self.__parent_class._interface__widgets["ups_status_left"].setText( text_left[:-4] )
973991
self.__parent_class._interface__widgets["ups_status_right"].setText( text_right[:-4] )
@@ -978,7 +996,7 @@ class gui_updater :
978996
charge = vars.get( b"battery.charge", "0" )
979997
self.__parent_class._interface__widgets["progress_battery_charge"].setValue( int( float( charge ) ) )
980998
self.__parent_class._interface__widgets["progress_battery_charge"].resetFormat()
981-
status_text += "<br>%s %s%%" % ( _("Battery charge :"), int( float( charge ) ) )
999+
tooltip_lines.append( "%s %s%%" % ( _("Battery charge :"), int( float( charge ) ) ) )
9821000
else :
9831001
self.__parent_class._interface__widgets["progress_battery_charge"].setValue( 0 )
9841002
self.__parent_class._interface__widgets["progress_battery_charge"].setFormat( _("Not available") )
@@ -989,7 +1007,7 @@ class gui_updater :
9891007
load = vars.get( b"ups.load", "0" )
9901008
self.__parent_class._interface__widgets["progress_battery_load"].setValue( int( float( load ) ) )
9911009
self.__parent_class._interface__widgets["progress_battery_load"].resetFormat()
992-
status_text += "<br>%s %s%%" % ( _("UPS load :"), int( float( load ) ) )
1010+
tooltip_lines.append( "%s %s%%" % ( _("UPS load :"), int( float( load ) ) ) )
9931011
else :
9941012
self.__parent_class._interface__widgets["progress_battery_load"].setValue( 0 )
9951013
self.__parent_class._interface__widgets["progress_battery_load"].setFormat( _("Not available") )
@@ -1008,9 +1026,10 @@ class gui_updater :
10081026
info = _("Not available")
10091027

10101028
self.__parent_class._interface__widgets["ups_status_time"].setText( info )
1029+
tooltip_lines.append( "%s %s" % ( _("Autonomy :"), plain_status_text( info ) ) )
10111030

10121031
# Display UPS status as tooltip for tray icon
1013-
self.__parent_class._interface__widgets["status_icon"].setToolTip( status_text )
1032+
self.__parent_class._interface__widgets["status_icon"].setToolTip( "\n".join( tooltip_lines ) )
10141033

10151034
except :
10161035
self.__parent_class.gui_status_message( _("Error from '{0}' ({1})").format( ups, sys.exc_info()[1] ) )
@@ -1038,4 +1057,3 @@ if __name__ == "__main__" :
10381057

10391058
gui = interface(sys.argv)
10401059
gui.exec()
1041-

0 commit comments

Comments
 (0)