Changeset 964dacd


Ignore:
Timestamp:
Mar 6, 2017 4:47:51 AM (4 years ago)
Author:
str4d <str4d@…>
Branches:
master
Children:
a65722f
Parents:
25b03979
Message:

I2PSnark:

  • More tooltips
  • Remove "if checked" from checkbox strings
  • Checkbox layout tweaks
File:
1 edited

Legend:

Unmodified
Added
Removed
  • apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java

    r25b03979 r964dacd  
    705705                out.write(";&nbsp;");
    706706                out.write(_t("Dest"));
    707                 out.write(":&nbsp;<tt>");
     707                out.write(":&nbsp;<tt title=\"");
     708                out.write(_t("Our destination (identity) for this session"));
     709                out.write("\">");
    708710                out.write(IPString.substring(0, 4));
    709711                out.write("</tt>");
     
    17881790                if (!peer.isConnected())
    17891791                    continue;
    1790                 out.write("<tr class=\"" + rowClass + "\"><td></td>");
    1791                 out.write("<td colspan=\"4\" align=\"right\">");
     1792                out.write("<tr class=\"peerinfo " + rowClass + "\"><td title=\"");
     1793                out.write(_t("Peer attached to swarm"));
     1794                out.write("\"></td><td colspan=\"4\" align=\"right\">");
    17921795                PeerID pid = peer.getPeerID();
    17931796                String ch = pid != null ? pid.toString().substring(0, 4) : "????";
     
    18111814                else
    18121815                    client = _t("Unknown") + " (" + ch + ')';
    1813                 out.write(client + "&nbsp;&nbsp;<tt>" + peer.toString().substring(5, 9)+ "</tt>");
     1816                out.write(client + "&nbsp;<tt title=\"");
     1817                out.write(_t("Destination (identity) of peer"));
     1818                out.write("\">" + peer.toString().substring(5, 9)+ "</tt>");
    18141819                if (showDebug)
    18151820                    out.write(" inactive " + (peer.getInactiveTime() / 1000) + "s");
     
    18431848                        out.write(formatSize(peer.getDownloadRate()) + "ps</span>");
    18441849                    } else {
    1845                         out.write("<span class=\"choked\"><a title=\"");
     1850                        out.write("<span class=\"choked\" title=\"");
    18461851                        if (!peer.isInteresting())
    18471852                            out.write(_t("Uninteresting (The peer has no pieces we need)"));
     
    18491854                            out.write(_t("Choked (The peer is not allowing us to request pieces)"));
    18501855                        out.write("\">");
    1851                         out.write(formatSize(peer.getDownloadRate()) + "ps</a></span>");
     1856                        out.write(formatSize(peer.getDownloadRate()) + "ps</span>");
    18521857                    }
    18531858                } else if (!isValid) {
     
    18651870                        out.write(formatSize(peer.getUploadRate()) + "ps</span>");
    18661871                    } else {
    1867                         out.write("<span class=\"choked\"><a title=\"");
     1872                        out.write("<span class=\"choked\" title=\"");
    18681873                        if (!peer.isInterested())
    18691874                            out.write(_t("Uninterested (We have no pieces the peer needs)"));
     
    18711876                            out.write(_t("Choking (We are not allowing the peer to request pieces)"));
    18721877                        out.write("\">");
    1873                         out.write(formatSize(peer.getUploadRate()) + "ps</a></span>");
     1878                        out.write(formatSize(peer.getUploadRate()) + "ps</span>");
    18741879                    }
    18751880                }
     
    21952200
    21962201        out.write(_t("Data directory"));
    2197         out.write(": <td><input name=\"nofilter_dataDir\" size=\"80\" value=\"" +
     2202        out.write(":<td colspan=\"2\"><input name=\"nofilter_dataDir\" size=\"80\""
     2203                  + " title=\"");
     2204        out.write(_t("Directory where torrents and downloaded/shared files are stored"));
     2205        out.write("\" value=\"" +
    21982206                  DataHelper.escapeHTML(dataDir) + "\" spellcheck=\"false\"></td>\n" +
    21992207
    22002208                  "<tr><td>");
    22012209        out.write(_t("Files readable by all"));
    2202         out.write(": <td><input type=\"checkbox\" class=\"optbox\" name=\"filesPublic\" value=\"true\" "
     2210        out.write(":<td colspan=\"2\"><input type=\"checkbox\" class=\"optbox\" name=\"filesPublic\" value=\"true\" "
    22032211                  + (filesPublic ? "checked " : "")
    22042212                  + "title=\"");
    2205         out.write(_t("If checked, other users may access the downloaded files"));
     2213        out.write(_t("Set file permissions to allow other local users to access the downloaded files"));
    22062214        out.write("\" >" +
    22072215
    22082216                  "<tr><td>");
    22092217        out.write(_t("Auto start torrents"));
    2210         out.write(": <td><input type=\"checkbox\" class=\"optbox\" name=\"autoStart\" value=\"true\" "
     2218        out.write(":<td colspan=\"2\"><input type=\"checkbox\" class=\"optbox\" name=\"autoStart\" value=\"true\" "
    22112219                  + (autoStart ? "checked " : "")
    22122220                  + "title=\"");
    2213         out.write(_t("If checked, automatically start torrents that are added"));
     2221        out.write(_t("Automatically start torrents when added and restart torrents when I2PSnark starts"));
    22142222        out.write("\" >" +
    22152223
    22162224                  "<tr><td>");
    22172225        out.write(_t("Smart torrent sorting"));
    2218         out.write(": <td><input type=\"checkbox\" class=\"optbox\" name=\"smartSort\" value=\"true\" "
     2226        out.write(":<td colspan=\"2\"><input type=\"checkbox\" class=\"optbox\" name=\"smartSort\" value=\"true\" "
    22192227                  + (smartSort ? "checked " : "")
    22202228                  + "title=\"");
    2221         out.write(_t("If checked, ignore words such as 'the' when sorting"));
     2229        out.write(_t("Ignore words such as 'a' and 'the' when sorting"));
    22222230        out.write("\" >");
    22232231
     
    22262234                out.write("<tr><td>");
    22272235                out.write(_t("Language"));
    2228                 out.write(": <td>");
     2236                out.write(": <td colspan=\"2\">");
    22292237                // class only in standalone builds
    22302238                out.write(ConfigUIHelper.getLangSettings(_context));
     
    22342242        out.write("<tr><td>");
    22352243        out.write(_t("Theme"));
    2236         out.write(": <td><select name='theme'>");
     2244        out.write(":<td colspan=\"2\"><select name='theme'>");
    22372245        String theme = _manager.getTheme();
    22382246        String[] themes = _manager.getThemes();
     
    22482256                  "<tr><td>");
    22492257        out.write(_t("Refresh time"));
    2250         out.write(": <td><select name=\"refreshDelay\">");
     2258        out.write(":<td colspan=\"2\"><select name=\"refreshDelay\""
     2259                  + " title=\"");
     2260        out.write(_t("How frequently torrent status is updated on the main page"));
     2261        out.write("\">");
    22512262        int delay = _manager.getRefreshDelaySeconds();
    22522263        for (int i = 0; i < times.length; i++) {
     
    22682279        if (_context.isRouterContext()) {
    22692280            out.write(_t("Startup delay"));
    2270             out.write(": <td><input name=\"startupDelay\" size=\"4\" class=\"r\" value=\"" + _manager.util().getStartupDelay() + "\"> ");
     2281            out.write(": <td colspan=\"2\"><input name=\"startupDelay\" size=\"4\" class=\"r\""
     2282                      + " title=\"");
     2283            out.write(_t("How long before auto-started torrents are loaded when I2PSnark starts"));
     2284            out.write("\" value=\"" + _manager.util().getStartupDelay() + "\"> ");
    22712285            out.write(_t("minutes"));
    22722286            out.write("\n" +
     
    22752289        }
    22762290        out.write(_t("Page size"));
    2277         out.write(": <td><input name=\"pageSize\" size=\"4\" maxlength=\"6\" class=\"r\" value=\"" + _manager.getPageSize() + "\"> ");
     2291        out.write(":<td colspan=\"2\"><input name=\"pageSize\" size=\"4\" maxlength=\"6\" class=\"r\""
     2292                  + " title=\"");
     2293        out.write(_t("Maximum number of torrents to display per page"));
     2294        out.write("\" value=\"" + _manager.getPageSize() + "\"> ");
    22782295        out.write(_t("torrents"));
    22792296        out.write("\n");
     
    23012318        out.write("<tr><td>");
    23022319        out.write(_t("Total uploader limit"));
    2303         out.write(": <td><input type=\"text\" name=\"upLimit\" class=\"r\" value=\""
    2304                   + _manager.util().getMaxUploaders() + "\" size=\"4\" maxlength=\"3\" > ");
     2320        out.write(":<td colspan=\"2\"><input type=\"text\" name=\"upLimit\" class=\"r\" value=\""
     2321                  + _manager.util().getMaxUploaders() + "\" size=\"4\" maxlength=\"3\""
     2322                  + " title=\"");
     2323        out.write(_t("Maximum number of peers to upload to"));
     2324        out.write("\"> ");
    23052325        out.write(_t("peers"));
    23062326        out.write("\n" +
     
    23082328                  "<tr><td>");
    23092329        out.write(_t("Up bandwidth limit"));
    2310         out.write(": <td><input type=\"text\" name=\"upBW\" class=\"r\" value=\""
    2311                   + _manager.util().getMaxUpBW() + "\" size=\"4\" maxlength=\"4\" > KBps <i>");
     2330        out.write(":<td><input type=\"text\" name=\"upBW\" class=\"r\" value=\""
     2331                  + _manager.util().getMaxUpBW() + "\" size=\"4\" maxlength=\"4\""
     2332                  + " title=\"");
     2333        out.write(_t("Maximum bandwidth allocated for uploading"));
     2334        out.write("\"> KBps <td id=\"bwHelp\"><i>");
    23122335        out.write(_t("Half available bandwidth recommended."));
    23132336        if (_context.isRouterContext()) {
     
    23182341        out.write("\n<tr><td>");
    23192342        out.write(_t("Use open trackers also"));
    2320         out.write(": <td><input type=\"checkbox\" class=\"optbox\" name=\"useOpenTrackers\" value=\"true\" "
    2321                   + (useOpenTrackers ? "checked " : "") 
     2343        out.write(":<td colspan=\"2\"><input type=\"checkbox\" class=\"optbox\" name=\"useOpenTrackers\" value=\"true\" "
     2344                  + (useOpenTrackers ? "checked " : "")
    23222345                  + "title=\"");
    2323         out.write(_t("If checked, announce torrents to open trackers as well as the tracker listed in the torrent file"));
     2346        out.write(_t("Announce torrents to open trackers as well as tracker(s) listed in the torrent file"));
    23242347        out.write("\" ></td></tr>\n" +
    2325        
     2348
    23262349                  "<tr><td>");
    23272350        out.write(_t("Enable DHT"));
    2328         out.write(": <td><input type=\"checkbox\" class=\"optbox\" name=\"useDHT\" value=\"true\" "
    2329                   + (useDHT ? "checked " : "") 
     2351        out.write(":<td colspan=\"2\"><input type=\"checkbox\" class=\"optbox\" name=\"useDHT\" value=\"true\" "
     2352                  + (useDHT ? "checked " : "")
    23302353                  + "title=\"");
    2331         out.write(_t("If checked, use DHT"));
     2354        out.write(_t("Use DHT to find additional peers"));
    23322355        out.write("\" ></td></tr>\n");
    23332356
     
    23462369        out.write("<tr><td>");
    23472370        out.write(_t("Inbound Settings"));
    2348         out.write(":<td>");
     2371        out.write(":<td colspan=\"2\">");
    23492372        out.write(renderOptions(1, 10, SnarkManager.DEFAULT_TUNNEL_QUANTITY,
    23502373                                options.remove("inbound.quantity"), "inbound.quantity", TUNNEL));
     
    23532376        out.write("<tr><td>");
    23542377        out.write(_t("Outbound Settings"));
    2355         out.write(":<td>");
     2378        out.write(":<td colspan=\"2\">");
    23562379        out.write(renderOptions(1, 10, SnarkManager.DEFAULT_TUNNEL_QUANTITY,
    23572380                                options.remove("outbound.quantity"), "outbound.quantity", TUNNEL));
     
    23622385            out.write("<tr><td>");
    23632386            out.write(_t("I2CP host"));
    2364             out.write(": <td><input type=\"text\" name=\"i2cpHost\" value=\""
     2387            out.write(":<td colspan=\"2\"><input type=\"text\" name=\"i2cpHost\" value=\""
    23652388                      + _manager.util().getI2CPHost() + "\" size=\"15\" > " +
    23662389
    23672390                      "<tr><td>");
    23682391            out.write(_t("I2CP port"));
    2369             out.write(": <td><input type=\"text\" name=\"i2cpPort\" class=\"r\" value=\"" +
    2370                       + _manager.util().getI2CPPort() + "\" size=\"5\" maxlength=\"5\" > <br>\n");
     2392            out.write(":<td colspan=\"2\"><input type=\"text\" name=\"i2cpPort\" class=\"r\" value=\"" +
     2393                      + _manager.util().getI2CPPort() + "\" size=\"5\" maxlength=\"5\" >\n");
    23712394        }
    23722395
     
    23822405        out.write("<tr><td>");
    23832406        out.write(_t("I2CP options"));
    2384         out.write(": <td><textarea name=\"i2cpOpts\" cols=\"60\" rows=\"1\" wrap=\"off\" spellcheck=\"false\" >"
    2385                   + opts.toString() + "</textarea><br>\n" +
    2386                   "<tr><td colspan=\"2\">&nbsp;\n" +  // spacer
    2387                   "<tr><td>&nbsp;<td><input type=\"submit\" class=\"accept\" value=\"");
     2407        out.write(":<td colspan=\"2\"><textarea name=\"i2cpOpts\" cols=\"60\" rows=\"1\" wrap=\"off\" spellcheck=\"false\" >"
     2408                  + opts.toString() + "</textarea>\n" +
     2409                  "<tr class=\"spacer\"><td colspan=\"3\">&nbsp;\n" +  // spacer
     2410                  "<tr><td colspan=\"3\"><input type=\"submit\" class=\"accept\" value=\"");
    23882411        out.write(_t("Save configuration"));
    23892412        out.write("\" name=\"foo\" >\n" +
    2390                   "<tr><td colspan=\"2\">&nbsp;\n" +  // spacer
     2413                  "<tr class=\"spacer\"><td colspan=\"3\">&nbsp;\n" +  // spacer
    23912414                  "</table></div></div></form>");
    23922415    }
     
    29182941            //   .append(MAGGOT).append(hex).append(':').append(hex).append("</a></td></tr>");
    29192942
    2920             buf.append("<tr><td>");
     2943            buf.append("<tr id=\"torrentInfoStats\"><td colspan=\"2\"><span>");
    29212944            toThemeImg(buf, "size");
    2922             buf.append("</td><td><b>")
     2945            buf.append("<b>")
    29232946               .append(_t("Size"))
    29242947               .append(":</b> ")
     
    29262949            int pieces = snark.getPieces();
    29272950            double completion = (pieces - snark.getNeeded()) / (double) pieces;
    2928             buf.append("&nbsp;");
     2951            buf.append("</span>&nbsp;<span>");
    29292952            toThemeImg(buf, "head_rx");
    2930             buf.append("&nbsp;<b>");
     2953            buf.append("<b>");
    29312954            if (completion < 1.0)
    29322955                buf.append(_t("Completion"))
     
    29362959                buf.append(_t("Complete")).append("</b>");
    29372960            // up ratio
    2938             buf.append("&nbsp;");
     2961            buf.append("</span>&nbsp;<span>");
    29392962            toThemeImg(buf, "head_tx");
    2940             buf.append("&nbsp;<b>")
     2963            buf.append("<b>")
    29412964               .append(_t("Upload ratio"))
    29422965               .append(":</b> ");
     
    29562979            }
    29572980            if (needed > 0) {
    2958                 buf.append("&nbsp;");
     2981                buf.append("</span>&nbsp;<span>");
    29592982                toThemeImg(buf, "head_rx");
    2960                 buf.append("&nbsp;<b>")
     2983                buf.append("<b>")
    29612984                   .append(_t("Remaining"))
    29622985                   .append(":</b> ")
     
    29652988            long skipped = snark.getSkippedLength();
    29662989            if (skipped > 0) {
    2967                 buf.append("&nbsp;");
     2990                buf.append("</span>&nbsp;<span>");
    29682991                toThemeImg(buf, "head_rx");
    2969                 buf.append("&nbsp;<b>")
     2992                buf.append("<b>")
    29702993                   .append(_t("Skipped"))
    29712994                   .append(":</b> ")
     
    29752998                List<List<String>> files = meta.getFiles();
    29762999                int fileCount = files != null ? files.size() : 1;
    2977                 buf.append("&nbsp;");
     3000                buf.append("</span>&nbsp;<span>");
    29783001                toThemeImg(buf, "file");
    2979                 buf.append("&nbsp;<b>")
     3002                buf.append("<b>")
    29803003                   .append(_t("Files"))
    29813004                   .append(":</b> ")
    29823005                   .append(fileCount);
    29833006            }
    2984             buf.append("&nbsp;");
     3007            buf.append("</span>&nbsp;<span>");
    29853008            toThemeImg(buf, "file");
    2986             buf.append("&nbsp;<b>")
     3009            buf.append("<b>")
    29873010               .append(_t("Pieces"))
    29883011               .append(":</b> ")
    29893012               .append(pieces);
    2990             buf.append("&nbsp;");
     3013            buf.append("</span>&nbsp;<span>");
    29913014            toThemeImg(buf, "file");
    2992             buf.append("&nbsp;<b>")
     3015            buf.append("<b>")
    29933016               .append(_t("Piece size"))
    29943017               .append(":</b> ")
    29953018               .append(formatSize(snark.getPieceLength(0)))
    2996                .append("</td></tr>\n");
     3019               .append("</span></td></tr>\n");
    29973020
    29983021            // buttons
    29993022            if (showStopStart) {
    3000                 buf.append("<tr><td></td><td>");
     3023                buf.append("<tr id=\"torrentInfoControl\"><td colspan=\"2\">");
    30013024                if (snark.isChecking()) {
    3002                     buf.append("<b>").append(_t("Checking")).append("&hellip; ")
     3025                    buf.append("<span id=\"fileCheck\"><b>").append(_t("Checking")).append("&hellip; ")
    30033026                       .append((new DecimalFormat("0.00%")).format(snark.getCheckingProgress()))
    3004                        .append("&nbsp;&nbsp;&nbsp;<a href=\"").append(base).append("\">")
    3005                        .append(_t("Refresh page for results")).append("</a>");
     3027                       .append("&nbsp;<a href=\"").append(base).append("\">")
     3028                       .append(_t("Refresh page for results")).append("</a></span>");
    30063029                } else if (snark.isStarting()) {
    30073030                    buf.append("<b>").append(_t("Starting")).append("&hellip;</b>");
     
    30173040                    buf.append("<input type=\"submit\" name=\"recheck\" value=\"").append(_t("Force Recheck"));
    30183041                    if (isRunning)
    3019                         buf.append("\" class=\"disabled\" disabled=\"disabled\">\n");
     3042                        buf.append("\" class=\"disabled\" disabled=\"disabled\" title=\"")
     3043                           .append(_t("Stop the torrent in order to check file integrity"))
     3044                           .append("\">\n");
    30203045                    else
    3021                         buf.append("\" class=\"reload\">\n");
     3046                        buf.append("\" class=\"reload\" title=\"")
     3047                           .append(_t("Check integrity of the downloaded file(s)"))
     3048                           .append("\">\n");
    30223049                }
    30233050                buf.append("</td></tr>\n");
     
    31233150               .append(getQueryString(sort)).append("\">");
    31243151        }
    3125         tx = _t("Status");
     3152        tx = _t("Download Status");
    31263153        toThemeImg(buf, "status", tx,
    31273154                   showRemainingSort ? _t("Sort by {0}", _t("Remaining")) : tx);
     
    31353162                   .append(getQueryString(sort)).append("\">");
    31363163            }
    3137             tx = _t("Priority");
     3164            tx = _t("Download Priority");
    31383165            toThemeImg(buf, "priority", tx,
    31393166                       showSort ? _t("Sort by {0}", tx) : tx);
     
    32003227                                    status = toImg("clock_red");
    32013228                                status += " " +
    3202                                          (100 * (length - remaining) / length) + "% " + _t("complete") +
     3229                                         ("<span class=\"percentDownloaded\" title=\"") + _t("Percentage of file downloaded") + ("\">") +
     3230                                         (100 * (length - remaining) / length) + "% " + ("</span><span class=\"dirInfoComplete\">") + _t("complete") + ("</span>") +
    32033231                                         " (" + DataHelper.formatSize2(remaining) + "B " + _t("remaining") + ")";
    32043232                            }
     
    32443272                buf.append("<td class=\"priority\">");
    32453273                if ((!complete) && (!item.isDirectory())) {
    3246                     buf.append("\n<input type=\"radio\" onclick=\"priorityclicked();\" class=\"prihigh\" value=\"5\" name=\"pri.").append(fileIndex).append("\" ");
     3274                    buf.append("<span class=\"priorityHigh\" title=\"").append(_t("Download file at high priority")).append("\">")
     3275                       .append("\n<input type=\"radio\" onclick=\"priorityclicked();\" class=\"prihigh\" value=\"5\" name=\"pri.").append(fileIndex).append("\" ");
    32473276                    if (priority > 0)
    32483277                        buf.append("checked=\"checked\"");
    3249                     buf.append('>').append(_t("High"));
    3250 
    3251                     buf.append("\n<input type=\"radio\" onclick=\"priorityclicked();\" class=\"prinorm\" value=\"0\" name=\"pri.").append(fileIndex).append("\" ");
     3278                    buf.append('>')
     3279                       .append(_t("High")).append("</span>");
     3280
     3281                    buf.append("<span class=\"priorityNormal\" title=\"").append(_t("Download file at normal priority")).append("\">")
     3282                    .append("\n<input type=\"radio\" onclick=\"priorityclicked();\" class=\"prinorm\" value=\"0\" name=\"pri.").append(fileIndex).append("\" ");
    32523283                    if (priority == 0)
    32533284                        buf.append("checked=\"checked\"");
    3254                     buf.append('>').append(_t("Normal"));
    3255 
    3256                     buf.append("\n<input type=\"radio\" onclick=\"priorityclicked();\" class=\"priskip\" value=\"-9\" name=\"pri.").append(fileIndex).append("\" ");
     3285                    buf.append('>')
     3286                       .append(_t("Normal")).append("</span>");
     3287
     3288                    buf.append("<span class=\"prioritySkip\" title=\"").append(_t("Do not download this file")).append("\">")
     3289                    .append("\n<input type=\"radio\" onclick=\"priorityclicked();\" class=\"priskip\" value=\"-9\" name=\"pri.").append(fileIndex).append("\" ");
    32573290                    if (priority < 0)
    32583291                        buf.append("checked=\"checked\"");
    3259                     buf.append('>').append(_t("Skip"));
     3292                    buf.append('>')
     3293                       .append(_t("Skip")).append("</span>");
    32603294                    showSaveButton = true;
    32613295                }
     
    32653299        }
    32663300        if (showSaveButton) {
    3267             buf.append("<thead><tr><th colspan=\"4\">&nbsp;</th><th class=\"headerpriority\">" +
    3268                        "<a class=\"control\" id=\"setallhigh\" href=\"javascript:void(null);\" onclick=\"setallhigh();\">")
     3301            buf.append("<thead><tr id=\"setPriority\"><th class=\"headerpriority\" colspan=\"5\">" +
     3302                       "<span class=\"script\"><a class=\"control\" id=\"setallhigh\" href=\"javascript:void(null);\" onclick=\"setallhigh();\">")
    32693303               .append(toImg("clock_red")).append(_t("Set all high")).append("</a>\n" +
    32703304                       "<a class=\"control\" id=\"setallnorm\" href=\"javascript:void(null);\" onclick=\"setallnorm();\">")
    32713305               .append(toImg("clock")).append(_t("Set all normal")).append("</a>\n" +
    32723306                       "<a class=\"control\" id=\"setallskip\" href=\"javascript:void(null);\" onclick=\"setallskip();\">")
    3273                .append(toImg("cancel")).append(_t("Skip all")).append("</a>\n" +
    3274                        "<br><br><input type=\"submit\" class=\"accept\" value=\"").append(_t("Save priorities"))
     3307               .append(toImg("cancel")).append(_t("Skip all")).append("</a></span>\n" +
     3308                       "<input type=\"submit\" class=\"accept\" value=\"").append(_t("Save priorities"))
    32753309               .append("\" name=\"savepri\" >\n" +
    32763310                       "</th></tr></thead>\n");
Note: See TracChangeset for help on using the changeset viewer.