diff options
| author | Felix (xq) Queißner <git@mq32.de> | 2020-06-08 18:36:35 +0200 |
|---|---|---|
| committer | Felix (xq) Queißner <git@mq32.de> | 2020-06-08 18:36:35 +0200 |
| commit | 8c9480f6fc1b73b2f9ca5c1463a8ee10a579712d (patch) | |
| tree | 28d5880141380870d040481aeea0b6dab16852e4 /src | |
| parent | 75deaa0c850d374f526102b0b38402b2632f9751 (diff) | |
| download | kristall-8c9480f6fc1b73b2f9ca5c1463a8ee10a579712d.tar.gz | |
Improves gopher map rendering with icons and monospace font, adds status bar with more infos, fixes file dialog for older qt versions.
Diffstat (limited to 'src')
| -rw-r--r-- | src/browsertab.cpp | 38 | ||||
| -rw-r--r-- | src/browsertab.hpp | 3 | ||||
| -rw-r--r-- | src/gophermaprenderer.cpp | 66 | ||||
| -rw-r--r-- | src/icons.qrc | 12 | ||||
| -rw-r--r-- | src/icons/gopher/binary.svg | 1 | ||||
| -rw-r--r-- | src/icons/gopher/directory.svg | 1 | ||||
| -rw-r--r-- | src/icons/gopher/dns.svg | 1 | ||||
| -rw-r--r-- | src/icons/gopher/error.svg | 1 | ||||
| -rw-r--r-- | src/icons/gopher/gif.svg | 1 | ||||
| -rw-r--r-- | src/icons/gopher/html.svg | 1 | ||||
| -rw-r--r-- | src/icons/gopher/image.svg | 1 | ||||
| -rw-r--r-- | src/icons/gopher/mirror.svg | 1 | ||||
| -rw-r--r-- | src/icons/gopher/search.svg | 1 | ||||
| -rw-r--r-- | src/icons/gopher/sound.svg | 1 | ||||
| -rw-r--r-- | src/icons/gopher/telnet.svg | 1 | ||||
| -rw-r--r-- | src/icons/gopher/text.svg | 1 | ||||
| -rw-r--r-- | src/ioutil.cpp | 20 | ||||
| -rw-r--r-- | src/ioutil.hpp | 2 | ||||
| -rw-r--r-- | src/mainwindow.cpp | 52 | ||||
| -rw-r--r-- | src/mainwindow.hpp | 5 |
20 files changed, 158 insertions, 52 deletions
diff --git a/src/browsertab.cpp b/src/browsertab.cpp index 26f1ab2..412c652 100644 --- a/src/browsertab.cpp +++ b/src/browsertab.cpp @@ -4,6 +4,8 @@ #include "geminirenderer.hpp" #include "settingsdialog.hpp" #include "gophermaprenderer.hpp" +#include "ioutil.hpp" + #include <cassert> #include <QTabWidget> #include <QMenu> @@ -67,6 +69,8 @@ void BrowserTab::navigateTo(const QUrl &url, PushToHistory mode) return; } + this->timer.start(); + this->current_location = url; this->ui->url_bar->setText(url.toString()); @@ -233,23 +237,6 @@ void BrowserTab::on_requestFailed(const QString &reason) this->setErrorMessage(QString("Request failed:\n%1").arg(reason)); } -QString size_human(int size) -{ - float num = size; - QStringList list; - list << "KB" << "MB" << "GB" << "TB"; - - QStringListIterator i(list); - QString unit("bytes"); - - while(num >= 1024.0 && i.hasNext()) - { - unit = i.next(); - num /= 1024.0; - } - return QString().setNum(num,'f',2)+" "+unit; -} - void BrowserTab::on_requestComplete(const QByteArray &data, const QString &mime) { qDebug() << "Loaded" << data.length() << "bytes of type" << mime; @@ -339,7 +326,7 @@ Use the *File* menu to save the file to your local disk or navigate somewhere el Info: MIME Type: %1 File Size: %2 -)md").arg(mime).arg(size_human(data.size()))); +)md").arg(mime).arg(IoUtil::size_human(data.size()))); } assert((document != nullptr) == (doc_type == Text)); @@ -356,6 +343,8 @@ File Size: %2 QString title = this->current_location.toString(); emit this->titleChanged(title); + emit this->fileLoaded(data.size(), mime, this->timer.elapsed()); + this->successfully_loaded = true; if(this->push_to_history_after_load) { @@ -520,10 +509,15 @@ void BrowserTab::on_text_browser_anchorClicked(const QUrl &url) void BrowserTab::on_text_browser_highlighted(const QUrl &url) { - QUrl real_url = url; - if(real_url.isRelative()) - real_url = this->current_location.resolved(url); - this->mainWindow->setUrlPreview(real_url); + if(url.isValid()) { + QUrl real_url = url; + if(real_url.isRelative()) + real_url = this->current_location.resolved(url); + this->mainWindow->setUrlPreview(real_url); + } + else { + this->mainWindow->setUrlPreview(QUrl { }); + } } void BrowserTab::on_stop_button_clicked() diff --git a/src/browsertab.hpp b/src/browsertab.hpp index 815f239..7fc39f6 100644 --- a/src/browsertab.hpp +++ b/src/browsertab.hpp @@ -7,6 +7,7 @@ #include <QGraphicsScene> #include <QTextDocument> #include <QNetworkAccessManager> +#include <QElapsedTimer> #include "geminiclient.hpp" #include "documentoutlinemodel.hpp" @@ -54,6 +55,7 @@ public: signals: void titleChanged(QString const & title); void locationChanged(QUrl const & url); + void fileLoaded(qint64 fileSize, QString const & mime, int msec); private slots: void on_url_bar_returnPressed(); @@ -123,6 +125,7 @@ public: QByteArray current_buffer; QString current_mime; + QElapsedTimer timer; }; #endif // BROWSERTAB_HPP diff --git a/src/gophermaprenderer.cpp b/src/gophermaprenderer.cpp index 96e0557..52f4442 100644 --- a/src/gophermaprenderer.cpp +++ b/src/gophermaprenderer.cpp @@ -7,6 +7,7 @@ #include <QTextImageFormat> #include <QDebug> +#include <QImage> //Canonical Types //0 Text File @@ -31,11 +32,11 @@ std::unique_ptr<QTextDocument> GophermapRenderer::render(const QByteArray &input, const QUrl &root_url, const DocumentStyle &themed_style) { QTextCharFormat standard; - standard.setFont(themed_style.standard_font); - standard.setForeground(themed_style.standard_color); + standard.setFont(themed_style.preformatted_font); + standard.setForeground(themed_style.preformatted_color); QTextCharFormat standard_link; - standard_link.setFont(themed_style.standard_font); + standard_link.setFont(themed_style.preformatted_font); standard_link.setForeground(QBrush(themed_style.internal_link_color)); QTextCharFormat external_link; @@ -45,21 +46,34 @@ std::unique_ptr<QTextDocument> GophermapRenderer::render(const QByteArray &input std::unique_ptr<QTextDocument> result = std::make_unique<QTextDocument>(); result->setDocumentMargin(themed_style.margin); + result->addResource(QTextDocument::ImageResource, QUrl("gopher/binary"), QVariant::fromValue(QImage(":/icons/gopher/binary.svg"))); + result->addResource(QTextDocument::ImageResource, QUrl("gopher/directory"), QVariant::fromValue(QImage(":/icons/gopher/directory.svg"))); + result->addResource(QTextDocument::ImageResource, QUrl("gopher/dns"), QVariant::fromValue(QImage(":/icons/gopher/dns.svg"))); + result->addResource(QTextDocument::ImageResource, QUrl("gopher/error"), QVariant::fromValue(QImage(":/icons/gopher/error.svg"))); + result->addResource(QTextDocument::ImageResource, QUrl("gopher/gif"), QVariant::fromValue(QImage(":/icons/gopher/gif.svg"))); + result->addResource(QTextDocument::ImageResource, QUrl("gopher/html"), QVariant::fromValue(QImage(":/icons/gopher/html.svg"))); + result->addResource(QTextDocument::ImageResource, QUrl("gopher/image"), QVariant::fromValue(QImage(":/icons/gopher/image.svg"))); + result->addResource(QTextDocument::ImageResource, QUrl("gopher/mirror"), QVariant::fromValue(QImage(":/icons/gopher/mirror.svg"))); + result->addResource(QTextDocument::ImageResource, QUrl("gopher/search"), QVariant::fromValue(QImage(":/icons/gopher/search.svg"))); + result->addResource(QTextDocument::ImageResource, QUrl("gopher/sound"), QVariant::fromValue(QImage(":/icons/gopher/sound.svg"))); + result->addResource(QTextDocument::ImageResource, QUrl("gopher/telnet"), QVariant::fromValue(QImage(":/icons/gopher/telnet.svg"))); + result->addResource(QTextDocument::ImageResource, QUrl("gopher/text"), QVariant::fromValue(QImage(":/icons/gopher/text.svg"))); + QTextCursor cursor{result.get()}; QTextBlockFormat non_list_format = cursor.blockFormat(); QList<QByteArray> lines = input.split('\n'); - for (auto const & line : lines) + for (auto const &line : lines) { if (line.length() < 2) // skip lines without continue; - if(line[line.size() - 1] != '\r') + if (line[line.size() - 1] != '\r') continue; auto items = line.mid(1, line.length() - 2).split('\t'); - if(items.size() < 2) // invalid + if (items.size() < 2) // invalid continue; QString icon; @@ -72,22 +86,22 @@ std::unique_ptr<QTextDocument> GophermapRenderer::render(const QByteArray &input icon = "directory"; break; case '2': // CCSO Nameserver - icon = "ns"; + icon = "dns"; break; case '3': // Error code returned by a Gopher server to indicate failure icon = "error"; break; case '4': // BinHex-encoded file (primarily for Macintosh computers) - icon = "binhex"; + icon = "binary"; break; case '5': // DOS file - icon = "dos"; + icon = "binary"; break; case '6': // uuencoded file - icon = "uuencoded"; + icon = "binary"; break; case '7': // Gopher full-text search - icon = "full-text"; + icon = "search"; break; case '8': // Telnet icon = "telnet"; @@ -117,7 +131,7 @@ std::unique_ptr<QTextDocument> GophermapRenderer::render(const QByteArray &input case 's': // Sound file icon = "sound"; break; - default: // unknown + default: // unknown continue; } @@ -125,34 +139,46 @@ std::unique_ptr<QTextDocument> GophermapRenderer::render(const QByteArray &input // 1Phlog /phlog octotherp.org 70 + - if(line.at(0) == 'i') + if (line.at(0) == 'i') { cursor.insertText(title + "\n", standard); } else { QString dst_url; - switch(items.size()) + switch (items.size()) { - case 0: assert(false); - case 1: assert(false); + case 0: + assert(false); + case 1: + assert(false); case 2: dst_url = root_url.resolved(QUrl(items.at(1))).toString(); break; case 3: - dst_url = "gopher://" + items.at(2) + "/" + line.mid(0,1) + items.at(1); + dst_url = "gopher://" + items.at(2) + "/" + line.mid(0, 1) + items.at(1); break; default: - dst_url = "gopher://" + items.at(2) + ":" + items.at(3) + "/" + line.mid(0,1) + items.at(1); + dst_url = "gopher://" + items.at(2) + ":" + items.at(3) + "/" + line.mid(0, 1) + items.at(1); break; } - if(not QUrl(dst_url).isValid()) { + if (not QUrl(dst_url).isValid()) + { // invlaid URL generated qDebug() << line << dst_url; } - cursor.insertText("[" + icon + "] ", standard); + QTextImageFormat icon_fmt; + icon_fmt.setName(QString("gopher/%1").arg(icon)); + icon_fmt.setVerticalAlignment(QTextImageFormat::AlignTop); + + cursor.insertImage(icon_fmt); + + // cursor.insertImage(QImage(QString(":/icons/gopher/%1.svg").arg(icon))); + + cursor.insertText(" "); + // cursor.insertText("[" + icon + "] ", standard); QTextCharFormat fmt = standard_link; fmt.setAnchor(true); diff --git a/src/icons.qrc b/src/icons.qrc index a475b23..028e0db 100644 --- a/src/icons.qrc +++ b/src/icons.qrc @@ -21,5 +21,17 @@ <file>icons/volume-off.svg</file> <file>icons/play.svg</file> <file>icons/pause.svg</file> + <file>icons/gopher/binary.svg</file> + <file>icons/gopher/directory.svg</file> + <file>icons/gopher/dns.svg</file> + <file>icons/gopher/error.svg</file> + <file>icons/gopher/gif.svg</file> + <file>icons/gopher/html.svg</file> + <file>icons/gopher/image.svg</file> + <file>icons/gopher/mirror.svg</file> + <file>icons/gopher/search.svg</file> + <file>icons/gopher/sound.svg</file> + <file>icons/gopher/telnet.svg</file> + <file>icons/gopher/text.svg</file> </qresource> </RCC> diff --git a/src/icons/gopher/binary.svg b/src/icons/gopher/binary.svg new file mode 100644 index 0000000..e731a17 --- /dev/null +++ b/src/icons/gopher/binary.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M5.12,5H18.87L17.93,4H5.93L5.12,5M20.54,5.23C20.83,5.57 21,6 21,6.5V19A2,2 0 0,1 19,21H5A2,2 0 0,1 3,19V6.5C3,6 3.17,5.57 3.46,5.23L4.84,3.55C5.12,3.21 5.53,3 6,3H18C18.47,3 18.88,3.21 19.15,3.55L20.54,5.23M6,18H12V15H6V18Z" /></svg>
\ No newline at end of file diff --git a/src/icons/gopher/directory.svg b/src/icons/gopher/directory.svg new file mode 100644 index 0000000..09ce7cc --- /dev/null +++ b/src/icons/gopher/directory.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M19,20H4C2.89,20 2,19.1 2,18V6C2,4.89 2.89,4 4,4H10L12,6H19A2,2 0 0,1 21,8H21L4,8V18L6.14,10H23.21L20.93,18.5C20.7,19.37 19.92,20 19,20Z" /></svg>
\ No newline at end of file diff --git a/src/icons/gopher/dns.svg b/src/icons/gopher/dns.svg new file mode 100644 index 0000000..ec52048 --- /dev/null +++ b/src/icons/gopher/dns.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M7,9A2,2 0 0,1 5,7A2,2 0 0,1 7,5A2,2 0 0,1 9,7A2,2 0 0,1 7,9M20,3H4A1,1 0 0,0 3,4V10A1,1 0 0,0 4,11H20A1,1 0 0,0 21,10V4A1,1 0 0,0 20,3M7,19A2,2 0 0,1 5,17A2,2 0 0,1 7,15A2,2 0 0,1 9,17A2,2 0 0,1 7,19M20,13H4A1,1 0 0,0 3,14V20A1,1 0 0,0 4,21H20A1,1 0 0,0 21,20V14A1,1 0 0,0 20,13Z" /></svg>
\ No newline at end of file diff --git a/src/icons/gopher/error.svg b/src/icons/gopher/error.svg new file mode 100644 index 0000000..8cd654a --- /dev/null +++ b/src/icons/gopher/error.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M13,13H11V7H13M13,17H11V15H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z" /></svg>
\ No newline at end of file diff --git a/src/icons/gopher/gif.svg b/src/icons/gopher/gif.svg new file mode 100644 index 0000000..5a53e14 --- /dev/null +++ b/src/icons/gopher/gif.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M11,8H13V16H11V8M7.67,8H4.33C3.53,8 3,8.67 3,9.33V14.67C3,15.33 3.53,16 4.33,16H7.67C8.47,16 9,15.33 9,14.67V12H7V14H5V10H9V9.33C9,8.67 8.47,8 7.67,8M21,10V8H15V16H17V14H19.5V12H17V10H21Z" /></svg>
\ No newline at end of file diff --git a/src/icons/gopher/html.svg b/src/icons/gopher/html.svg new file mode 100644 index 0000000..2c65f32 --- /dev/null +++ b/src/icons/gopher/html.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M16.36,14C16.44,13.34 16.5,12.68 16.5,12C16.5,11.32 16.44,10.66 16.36,10H19.74C19.9,10.64 20,11.31 20,12C20,12.69 19.9,13.36 19.74,14M14.59,19.56C15.19,18.45 15.65,17.25 15.97,16H18.92C17.96,17.65 16.43,18.93 14.59,19.56M14.34,14H9.66C9.56,13.34 9.5,12.68 9.5,12C9.5,11.32 9.56,10.65 9.66,10H14.34C14.43,10.65 14.5,11.32 14.5,12C14.5,12.68 14.43,13.34 14.34,14M12,19.96C11.17,18.76 10.5,17.43 10.09,16H13.91C13.5,17.43 12.83,18.76 12,19.96M8,8H5.08C6.03,6.34 7.57,5.06 9.4,4.44C8.8,5.55 8.35,6.75 8,8M5.08,16H8C8.35,17.25 8.8,18.45 9.4,19.56C7.57,18.93 6.03,17.65 5.08,16M4.26,14C4.1,13.36 4,12.69 4,12C4,11.31 4.1,10.64 4.26,10H7.64C7.56,10.66 7.5,11.32 7.5,12C7.5,12.68 7.56,13.34 7.64,14M12,4.03C12.83,5.23 13.5,6.57 13.91,8H10.09C10.5,6.57 11.17,5.23 12,4.03M18.92,8H15.97C15.65,6.75 15.19,5.55 14.59,4.44C16.43,5.07 17.96,6.34 18.92,8M12,2C6.47,2 2,6.5 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z" /></svg>
\ No newline at end of file diff --git a/src/icons/gopher/image.svg b/src/icons/gopher/image.svg new file mode 100644 index 0000000..5c61724 --- /dev/null +++ b/src/icons/gopher/image.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M8.5,13.5L11,16.5L14.5,12L19,18H5M21,19V5C21,3.89 20.1,3 19,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19Z" /></svg>
\ No newline at end of file diff --git a/src/icons/gopher/mirror.svg b/src/icons/gopher/mirror.svg new file mode 100644 index 0000000..c879c79 --- /dev/null +++ b/src/icons/gopher/mirror.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M12 1C16.69 1 20.5 5.93 20.5 12C20.5 18.08 16.69 23 12 23C7.31 23 3.5 18.08 3.5 12C3.5 5.93 7.31 1 12 1M12 3C8.41 3 5.5 7.03 5.5 12C5.5 16.97 8.41 21 12 21C15.59 21 18.5 16.97 18.5 12C18.5 7.03 15.59 3 12 3M8.29 10.28L11.53 7.03L12.59 8.09L9.35 11.34L8.29 10.28M8.7 14.61L14.36 8.95L15.42 10L9.76 15.67L8.7 14.61Z" /></svg>
\ No newline at end of file diff --git a/src/icons/gopher/search.svg b/src/icons/gopher/search.svg new file mode 100644 index 0000000..eb42571 --- /dev/null +++ b/src/icons/gopher/search.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z" /></svg>
\ No newline at end of file diff --git a/src/icons/gopher/sound.svg b/src/icons/gopher/sound.svg new file mode 100644 index 0000000..36d700f --- /dev/null +++ b/src/icons/gopher/sound.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M21,3V15.5A3.5,3.5 0 0,1 17.5,19A3.5,3.5 0 0,1 14,15.5A3.5,3.5 0 0,1 17.5,12C18.04,12 18.55,12.12 19,12.34V6.47L9,8.6V17.5A3.5,3.5 0 0,1 5.5,21A3.5,3.5 0 0,1 2,17.5A3.5,3.5 0 0,1 5.5,14C6.04,14 6.55,14.12 7,14.34V6L21,3Z" /></svg>
\ No newline at end of file diff --git a/src/icons/gopher/telnet.svg b/src/icons/gopher/telnet.svg new file mode 100644 index 0000000..77b5d13 --- /dev/null +++ b/src/icons/gopher/telnet.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M20,19V7H4V19H20M20,3A2,2 0 0,1 22,5V19A2,2 0 0,1 20,21H4A2,2 0 0,1 2,19V5C2,3.89 2.9,3 4,3H20M13,17V15H18V17H13M9.58,13L5.57,9H8.4L11.7,12.3C12.09,12.69 12.09,13.33 11.7,13.72L8.42,17H5.59L9.58,13Z" /></svg>
\ No newline at end of file diff --git a/src/icons/gopher/text.svg b/src/icons/gopher/text.svg new file mode 100644 index 0000000..4a23bd3 --- /dev/null +++ b/src/icons/gopher/text.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M13,9H18.5L13,3.5V9M6,2H14L20,8V20A2,2 0 0,1 18,22H6C4.89,22 4,21.1 4,20V4C4,2.89 4.89,2 6,2M15,18V16H6V18H15M18,14V12H6V14H18Z" /></svg>
\ No newline at end of file diff --git a/src/ioutil.cpp b/src/ioutil.cpp index 047a901..00caba6 100644 --- a/src/ioutil.cpp +++ b/src/ioutil.cpp @@ -14,3 +14,23 @@ bool IoUtil::writeAll(QIODevice &dst, QByteArray const & src) return true; } + +QString IoUtil::size_human(qint64 size) +{ + if(size < 1024) + return QString("%1 B").arg(size); + + float num = size; + QStringList list; + list << "KB" << "MB" << "GB" << "TB"; + + QStringListIterator i(list); + QString unit("B"); + + while(num >= 1024.0 && i.hasNext()) + { + unit = i.next(); + num /= 1024.0; + } + return QString().setNum(num,'f',2)+" "+unit; +} diff --git a/src/ioutil.hpp b/src/ioutil.hpp index 487c66e..260a556 100644 --- a/src/ioutil.hpp +++ b/src/ioutil.hpp @@ -6,6 +6,8 @@ struct IoUtil { static bool writeAll(QIODevice & dst, QByteArray const & src); + + static QString size_human(qint64 size); }; #endif // IOUTIL_HPP diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 9171924..96ae1da 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -10,13 +10,17 @@ #include <QFile> #include <QTextStream> #include <QFileDialog> +#include "ioutil.hpp" MainWindow::MainWindow(QApplication * app, QWidget *parent) : QMainWindow(parent), application(app), settings("xqTechnologies", "Kristall"), ui(new Ui::MainWindow), - url_status(new QLabel()) + url_status(new QLabel(this)), + file_size(new QLabel(this)), + file_mime(new QLabel(this)), + load_time(new QLabel(this)) { if(not this->settings.contains("start_page")) { this->settings.setValue("start_page", "about:favourites"); @@ -25,6 +29,9 @@ MainWindow::MainWindow(QApplication * app, QWidget *parent) : ui->setupUi(this); this->statusBar()->addWidget(this->url_status); + this->statusBar()->addPermanentWidget(this->file_mime); + this->statusBar()->addPermanentWidget(this->file_size); + this->statusBar()->addPermanentWidget(this->load_time); this->favourites.load(settings); this->current_style.load(settings); @@ -87,6 +94,7 @@ BrowserTab * MainWindow::addEmptyTab(bool focus_new, bool load_default) BrowserTab * tab = new BrowserTab(this); connect(tab, &BrowserTab::titleChanged, this, &MainWindow::on_tab_titleChanged); + connect(tab, &BrowserTab::fileLoaded, this, &MainWindow::on_tab_fileLoaded); int index = this->ui->browser_tabs->addTab(tab, "Page"); @@ -322,15 +330,25 @@ void MainWindow::on_actionSave_as_triggered() { BrowserTab * tab = qobject_cast<BrowserTab*>(this->ui->browser_tabs->currentWidget()); if(tab != nullptr) { -#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) - QFileDialog::saveFileContent( - tab->current_buffer, - tab->current_location.fileName() - ); -#else - // TODO: Implement without saveFileContent - QMessageBox::warning(this, "Kristall", "Not support in your Qt version."); -#endif + QFileDialog dialog { this }; + dialog.setAcceptMode(QFileDialog::AcceptSave); + dialog.selectFile(tab->current_location.fileName()); + + if(dialog.exec() !=QFileDialog::Accepted) + return; + + QString fileName = dialog.selectedFiles().at(0); + + QFile file { fileName }; + + if(file.open(QFile::WriteOnly)) + { + IoUtil::writeAll(file, tab->current_buffer); + } + else + { + QMessageBox::warning(this, "Kristall", QString("Could not save file:\r\n%1").arg(file.errorString())); + } } } @@ -349,3 +367,17 @@ void MainWindow::on_actionAdd_to_favourites_triggered() tab->toggleIsFavourite(); } } + +void MainWindow::on_tab_fileLoaded(qint64 fileSize, const QString &mime, int msec) +{ + auto * tab = qobject_cast<BrowserTab*>(sender()); + if(tab != nullptr) { + int index = this->ui->browser_tabs->indexOf(tab); + assert(index >= 0); + if(index == this->ui->browser_tabs->currentIndex()) { + this->file_size->setText(IoUtil::size_human(fileSize)); + this->file_mime->setText(mime); + this->load_time->setText(QString("%1 ms").arg(msec)); + } + } +} diff --git a/src/mainwindow.hpp b/src/mainwindow.hpp index 9a460a8..557744d 100644 --- a/src/mainwindow.hpp +++ b/src/mainwindow.hpp @@ -73,6 +73,8 @@ private slots: void on_actionAdd_to_favourites_triggered(); + void on_tab_fileLoaded(qint64 fileSize, QString const & mime, int msec); + private: void reloadTheme(); @@ -86,5 +88,8 @@ private: Ui::MainWindow *ui; QLabel * url_status; + QLabel * file_size; + QLabel * file_mime; + QLabel * load_time; }; #endif // MAINWINDOW_HPP |
