1
mirror of https://invent.kde.org/network/falkon.git synced 2024-12-19 18:26:34 +01:00

Added support for listing directories with file: scheme

closes #435
This commit is contained in:
nowrep 2012-08-23 16:17:56 +02:00
parent e965363a7c
commit 6d997220c7
13 changed files with 433 additions and 41 deletions

View File

@ -23,5 +23,7 @@
<file>html/setting.png</file>
<file>html/config.html</file>
<file>html/restore.html</file>
<file>html/dirlist.html</file>
<file>html/hdd-icon.png</file>
</qresource>
</RCC>

View File

@ -0,0 +1,69 @@
<html><head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>%TITLE%</title>
<style>
html {background: #eeeeee;font: 13px/22px "Helvetica Neue", Helvetica, Arial, sans-serif;color: #525c66;}
html * {font-size: 100%;line-height: 1.6;}
#box {max-width:650px;min-width:400px;overflow:auto;margin: 25px auto 10px auto;padding: 10px 40px;border-width: 20px;-webkit-border-image: url(%BOX-BORDER%) 25;text-align: %LEFT_STR%;}
h1 {color:#1a4ba4;font-size:120%;margin-bottom:0px;word-wrap:break-word;}
a{text-decoration:none;}
a:hover{text-decoration:underline;}
p{margin-bottom:0;}
.dir-up{float:%LEFT_STR%;padding-%LEFT_STR%:22px;font-size:105%;height:30px;background:transparent url(data:image/png;base64,%UP-IMG%) no-repeat;}
.show-hidden{float:%RIGHT_STR%;font-size:105%;height:30px;}
.tr-hidden{display:none;}
.tr-visible{display:table-row;}
.file-table{width:95%;margin-left:auto;margin-right:auto;}
.file-table th{font-size:105%;}
.file-table td{padding-%LEFT_STR%:8px;}
.name{width:100%;text-align:%LEFT_STR%;}
.size{min-width:80px;}
.modif{min-width:120px;}
.td-size{text-align:%RIGHT_STR%;}
.td-name{padding-%LEFT_STR%:20px !important;background-color:transparent;background-repeat:no-repeat;background-position:center %LEFT_STR%;}
</style>
<script>
function showHidden()
{
var hElems = document.getElementsByClassName('tr-hidden');
var vElems = document.getElementsByClassName('tr-visible');
var dest = new Array();
if (hElems.length > 0) {
for(var i = 0; i < hElems.length; ++i)
dest[i] = hElems[i];
for (var s = 0; s < dest.length; ++s)
dest[s].className = "tr-visible";
}
else if (vElems.length > 0) {
for(var i = 0; i < vElems.length; ++i)
dest[i] = vElems[i];
for (var s = 0; s < dest.length; ++s)
dest[s].className = "tr-hidden";
}
}
</script>
</head>
<body>
<div id="box">
<h1>%TITLE%</h1>
<p class="dir-up" style="display:%UP-DIR-DISPLAY%"><a href="%UP-DIR-LINK%">%UP-DIR-TEXT%</a></p>
<p class="show-hidden" style="display:%SHOW-HIDDEN-DISPLAY%"><label><input type="checkbox" onchange="showHidden()">%SHOW-HIDDEN-TEXT%</label></p>
<span style="clear:both;display:block;visibility:hidden;"></span>
<table class="file-table">
<thead>
<tr>
<th class="name">%NAME%</th>
<th class="size">%SIZE%</th>
<th class="modif" colspan="2">%MODIFIED%</th>
</tr>
</thead>
<tbody>
%T-BODY%
</tbody>
</table>
</div>
</body></html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 703 B

View File

@ -45,6 +45,11 @@ void DownloadOptionsDialog::showExternalManagerOption(bool show)
ui->radioExternal->setVisible(show);
}
void DownloadOptionsDialog::showFromLine(bool show)
{
ui->fromFrame->setVisible(show);
}
void DownloadOptionsDialog::setLastDownloadOption(const DownloadManager::DownloadOption &option)
{
switch (option) {
@ -67,6 +72,25 @@ void DownloadOptionsDialog::setLastDownloadOption(const DownloadManager::Downloa
}
}
int DownloadOptionsDialog::exec()
{
int status = QDialog::exec();
if (status != 0) {
if (ui->radioOpen->isChecked()) {
status = 1;
}
else if (ui->radioSave->isChecked()) {
status = 2;
}
else if (ui->radioExternal->isChecked()) {
status = 3;
}
}
return status;
}
void DownloadOptionsDialog::emitDialogFinished(int status)
{
if (status != 0) {

View File

@ -37,8 +37,12 @@ public:
~DownloadOptionsDialog();
void showExternalManagerOption(bool show);
void showFromLine(bool show);
void setLastDownloadOption(const DownloadManager::DownloadOption &option);
int exec();
private slots:
void emitDialogFinished(int status);

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>410</width>
<height>251</height>
<height>267</height>
</rect>
</property>
<property name="minimumSize">
@ -83,33 +83,6 @@
</item>
</layout>
</item>
<item row="3" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>from:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="fromServer">
<property name="text">
<string/>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0" colspan="3">
<widget class="QGroupBox" name="groupBox">
<property name="title">
@ -169,6 +142,38 @@
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QFrame" name="fromFrame">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>from:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="fromServer">
<property name="text">
<string/>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>

View File

@ -186,6 +186,7 @@ SOURCES += \
session/restoremanager.cpp \
network/schemehandlers/qupzillaschemehandler.cpp \
network/schemehandlers/adblockschemehandler.cpp \
network/schemehandlers/fileschemehandler.cpp
HEADERS += \
webview/tabpreview.h \
@ -342,6 +343,7 @@ HEADERS += \
network/schemehandlers/schemehandler.h \
network/schemehandlers/qupzillaschemehandler.h \
network/schemehandlers/adblockschemehandler.h \
network/schemehandlers/fileschemehandler.h
FORMS += \
preferences/autofillmanager.ui \

View File

@ -31,6 +31,7 @@
#include "settings.h"
#include "schemehandlers/adblockschemehandler.h"
#include "schemehandlers/qupzillaschemehandler.h"
#include "schemehandlers/fileschemehandler.h"
#include <QFormLayout>
#include <QLabel>
@ -70,6 +71,7 @@ NetworkManager::NetworkManager(QupZilla* mainClass, QObject* parent)
m_schemeHandlers["qupzilla"] = new QupZillaSchemeHandler();
m_schemeHandlers["abp"] = new AdBlockSchemeHandler();
m_schemeHandlers["file"] = new FileSchemeHandler();
m_proxyFactory = new NetworkProxyFactory();
setProxyFactory(m_proxyFactory);

View File

@ -0,0 +1,211 @@
/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2010-2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "fileschemehandler.h"
#include "globalfunctions.h"
#include "iconprovider.h"
#include "downloadoptionsdialog.h"
#include "mainapplication.h"
#include "qupzilla.h"
#include <QFileIconProvider>
#include <QFileDialog>
#include <QFileInfo>
#include <QDesktopServices>
#include <QTextStream>
#include <QDateTime>
#include <QTimer>
#include <QDir>
FileSchemeHandler::FileSchemeHandler()
{
}
QNetworkReply* FileSchemeHandler::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice* outgoingData)
{
Q_UNUSED(outgoingData)
if (op != QNetworkAccessManager::GetOperation) {
return 0;
}
// Only list directories
QFileInfo fileInfo(request.url().toLocalFile());
if (!fileInfo.isDir() && fileInfo.isReadable()) {
return 0;
}
FileSchemeReply* reply = new FileSchemeReply(request);
return reply;
}
void FileSchemeHandler::handleUrl(const QUrl &url)
{
QFileIconProvider iconProvider;
QFile file(url.toLocalFile());
QFileInfo info(file);
if (!info.exists() || info.isDir() || !info.isReadable()) {
return;
}
const QString &fileName = info.fileName();
const QPixmap &pixmap = iconProvider.icon(info).pixmap(30);
const QString &type = iconProvider.type(info);
DownloadOptionsDialog dialog(fileName, pixmap, type, url, mApp->getWindow());
dialog.showExternalManagerOption(false);
dialog.showFromLine(false);
int status = dialog.exec();
if (status == 1) {
// Open
QDesktopServices::openUrl(url);
}
else if (status == 2) {
// Save
const QString &savePath = QFileDialog::getSaveFileName(mApp->getWindow(),
QObject::tr("Save file as..."),
QDir::homePath() + "/" + qz_getFileNameFromUrl(url));
if (!savePath.isEmpty()) {
file.copy(savePath);
}
}
}
FileSchemeReply::FileSchemeReply(const QNetworkRequest &req, QObject* parent)
: QNetworkReply(parent)
{
setOperation(QNetworkAccessManager::GetOperation);
setRequest(req);
setUrl(req.url());
m_buffer.open(QIODevice::ReadWrite);
setError(QNetworkReply::NoError, tr("No Error"));
open(QIODevice::ReadOnly);
QTimer::singleShot(0, this, SLOT(loadPage()));
}
qint64 FileSchemeReply::bytesAvailable() const
{
return m_buffer.bytesAvailable() + QNetworkReply::bytesAvailable();
}
qint64 FileSchemeReply::readData(char* data, qint64 maxSize)
{
return m_buffer.read(data, maxSize);
}
void FileSchemeReply::loadPage()
{
QTextStream stream(&m_buffer);
stream.setCodec("UTF-8");
stream << loadDirectory();
stream.flush();
m_buffer.reset();
setHeader(QNetworkRequest::ContentTypeHeader, QByteArray("text/html"));
setHeader(QNetworkRequest::ContentLengthHeader, m_buffer.bytesAvailable());
setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 200);
setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, QByteArray("Ok"));
emit metaDataChanged();
emit downloadProgress(m_buffer.size(), m_buffer.size());
emit readyRead();
emit finished();
}
QString FileSchemeReply::loadDirectory()
{
const QDir &dir = QDir(request().url().toLocalFile());
const QFileInfoList &list = dir.entryInfoList(QDir::AllEntries | QDir::Hidden, QDir::Name | QDir::DirsFirst);
const QFileIconProvider &iconProvider = QFileIconProvider();
static QString sPage;
if (sPage.isEmpty()) {
sPage = qz_readAllFileContents(":/html/dirlist.html");
sPage.replace("%BOX-BORDER%", "qrc:html/box-border.png");
sPage.replace("%UP-IMG%", qz_pixmapToByteArray(qIconProvider->standardIcon(QStyle::SP_FileDialogToParent).pixmap(22)));
sPage.replace("%UP-DIR-TEXT%", tr("Up to higher level directory"));
sPage.replace("%SHOW-HIDDEN-TEXT%", tr("Show hidden files"));
sPage.replace("%NAME%", tr("Name"));
sPage.replace("%SIZE%", tr("Size"));
sPage.replace("%MODIFIED%", tr("Last modified"));
sPage = qz_applyDirectionToPage(sPage);
}
QString page = sPage;
page.replace("%TITLE%", tr("Index for %1").arg(request().url().toLocalFile()));
QString upDirDisplay = "none";
QString showHiddenDisplay = "none";
QString tBody;
if (!dir.isRoot()) {
QDir upDir = dir;
upDir.cdUp();
upDirDisplay = "inline";
page.replace("%UP-DIR-LINK%", QUrl::fromLocalFile(upDir.absolutePath()).toEncoded());
}
foreach(const QFileInfo & info, list) {
if (info.fileName() == "." || info.fileName() == "..") {
continue;
}
QString line = "<tr";
if (info.isHidden()) {
showHiddenDisplay = "inline";
line += " class=\"tr-hidden\"";
}
line += "><td class=\"td-name\" style=\"background-image:url(data:image/png;base64,";
line += qz_pixmapToByteArray(iconProvider.icon(info).pixmap(16));
line += ");\">";
line += "<a href=\"";
line += QUrl::fromLocalFile(info.absoluteFilePath()).toEncoded();
line += "\">";
line += info.fileName();
line += "</a></td><td class=\"td-size\">";
line += qz_fileSizeToString(info.size());
line += "</td><td>";
line += info.lastModified().toString("dd.MM.yyyy");
line += "</td><td>";
line += info.lastModified().toString("hh:mm:ss");
line += "</td></tr>\n";
tBody.append(line);
}
if (tBody.isEmpty()) {
tBody = QString("<tr><td colspan='4'>%1</td></tr>").arg(tr("Folder is empty."));
}
page.replace("%T-BODY%", tBody);
page.replace("%UP-DIR-DISPLAY%", upDirDisplay);
page.replace("%SHOW-HIDDEN-DISPLAY%", showHiddenDisplay);
return page;
}

View File

@ -0,0 +1,60 @@
/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2010-2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#ifndef FILESCHEMEHANDLER_H
#define FILESCHEMEHANDLER_H
#include <QNetworkReply>
#include <QBuffer>
#include "schemehandler.h"
#include "qz_namespace.h"
class QT_QUPZILLA_EXPORT FileSchemeHandler : public SchemeHandler
{
public:
explicit FileSchemeHandler();
QNetworkReply* createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice* outgoingData);
static void handleUrl(const QUrl &url);
};
class QT_QUPZILLA_EXPORT FileSchemeReply : public QNetworkReply
{
Q_OBJECT
public:
explicit FileSchemeReply(const QNetworkRequest &req, QObject* parent = 0);
qint64 bytesAvailable() const;
protected:
qint64 readData(char* data, qint64 maxSize);
void abort() { }
private slots:
void loadPage();
private:
QString loadDirectory();
QBuffer m_buffer;
QString m_pageName;
};
#endif // FILESCHEMEHANDLER_H

View File

@ -36,6 +36,7 @@
#include "qzsettings.h"
#include "useragentmanager.h"
#include "recoverywidget.h"
#include "schemehandlers/fileschemehandler.h"
#ifdef NONBLOCK_JS_DIALOGS
#include "ui_jsconfirm.h"
@ -213,15 +214,18 @@ void WebPage::finished()
}
if (url().scheme() == "file") {
if (!m_fileWatcher) {
m_fileWatcher = new QFileSystemWatcher(this);
connect(m_fileWatcher, SIGNAL(fileChanged(QString)), this, SLOT(watchedFileChanged(QString)));
}
QFileInfo info(url().toLocalFile());
if (info.isFile()) {
if (!m_fileWatcher) {
m_fileWatcher = new QFileSystemWatcher(this);
connect(m_fileWatcher, SIGNAL(fileChanged(QString)), this, SLOT(watchedFileChanged(QString)));
}
const QString &filePath = url().toLocalFile();
const QString &filePath = url().toLocalFile();
if (QFile::exists(filePath) && !m_fileWatcher->files().contains(filePath)) {
m_fileWatcher->addPath(filePath);
if (QFile::exists(filePath) && !m_fileWatcher->files().contains(filePath)) {
m_fileWatcher->addPath(filePath);
}
}
}
else if (m_fileWatcher && !m_fileWatcher->files().isEmpty()) {
@ -287,6 +291,11 @@ void WebPage::handleUnsupportedContent(QNetworkReply* reply)
}
case QNetworkReply::ProtocolUnknownError: {
if (url.scheme() == "file") {
FileSchemeHandler::handleUrl(url);
return;
}
qDebug() << "WebPage::UnsupportedContent" << url << "ProtocolUnknowError";
desktopServicesOpen(url);
@ -691,9 +700,7 @@ bool WebPage::extension(Extension extension, const ExtensionOption* option, Exte
QString rule = exOption->errorString;
rule.remove("AdBlock: ");
QFile file(":/html/adblockPage.html");
file.open(QFile::ReadOnly);
QString errString = file.readAll();
QString errString = qz_readAllFileContents(":/html/adblockPage.html");
errString.replace("%TITLE%", tr("AdBlocked Content"));
errString.replace("%IMAGE%", "qrc:html/adblock_big.png");
errString.replace("%FAVICON%", "qrc:html/adblock_big.png");
@ -748,8 +755,10 @@ bool WebPage::extension(Extension extension, const ExtensionOption* option, Exte
errString.replace("%FAVICON%", qz_pixmapToByteArray(qIconProvider->standardIcon(QStyle::SP_MessageBoxWarning).pixmap(16, 16)));
errString.replace("%BOX-BORDER%", "qrc:html/box-border.png");
QString heading2 = loadedUrl.host().isEmpty() ? tr("QupZilla can't load page.") : tr("QupZilla can't load page from %1.").arg(loadedUrl.host());
errString.replace("%HEADING%", errorString);
errString.replace("%HEADING2%", tr("QupZilla can't load page from %1.").arg(loadedUrl.host()));
errString.replace("%HEADING2%", heading2);
errString.replace("%LI-1%", tr("Check the address for typing errors such as <b>ww.</b>example.com instead of <b>www.</b>example.com"));
errString.replace("%LI-2%", tr("If you are unable to load any pages, check your computer's network connection."));
errString.replace("%LI-3%", tr("If your computer or network is protected by a firewall or proxy, make sure that QupZilla is permitted to access the Web."));

View File

@ -70,6 +70,10 @@ QIcon WebView::icon() const
return QIcon(":icons/qupzilla.png");
}
if (url().scheme() == "file") {
return qIconProvider->standardIcon(QStyle::SP_DriveHDIcon);
}
if (!QWebView::icon().isNull()) {
return QWebView::icon();
}

View File

@ -309,7 +309,7 @@ void AKN_Handler::showAccessKeys()
if (m_accessKeysVisible) {
m_view.data()->installEventFilter(this);
connect(m_view.data(), SIGNAL(loadStarted()), this, SLOT(hideAccessKeys()));
connect(m_view.data()->page(), SIGNAL(scrollRequested(int,int,QRect)), this, SLOT(hideAccessKeys()));
connect(m_view.data()->page(), SIGNAL(scrollRequested(int, int, QRect)), this, SLOT(hideAccessKeys()));
#if QT_VERSION >= 0x040800
connect(m_view.data()->page(), SIGNAL(viewportChangeRequested()), this, SLOT(hideAccessKeys()));
#endif
@ -331,7 +331,7 @@ void AKN_Handler::hideAccessKeys()
// Uninstall event filter and disconnect loadStarted
m_view.data()->removeEventFilter(this);
disconnect(m_view.data(), SIGNAL(loadStarted()), this, SLOT(hideAccessKeys()));
disconnect(m_view.data()->page(), SIGNAL(scrollRequested(int,int,QRect)), this, SLOT(hideAccessKeys()));
disconnect(m_view.data()->page(), SIGNAL(scrollRequested(int, int, QRect)), this, SLOT(hideAccessKeys()));
#if QT_VERSION >= 0x040800
disconnect(m_view.data()->page(), SIGNAL(viewportChangeRequested()), this, SLOT(hideAccessKeys()));
#endif