Add delete and copy url ops to the webcache editor
This commit is contained in:
parent
241586a3a7
commit
759d8eca9f
@ -29,6 +29,11 @@
|
||||
#endif
|
||||
|
||||
#include <QDebug>
|
||||
#include <QSettings>
|
||||
#include <QCloseEvent>
|
||||
#include <QShortcut>
|
||||
#include <QMenu>
|
||||
#include <QClipboard>
|
||||
|
||||
#include "recoll.h"
|
||||
#include "webcache.h"
|
||||
@ -58,10 +63,17 @@ public:
|
||||
WebcacheModel::WebcacheModel(QObject *parent)
|
||||
: QAbstractTableModel(parent), m(new WebcacheModelInternal())
|
||||
{
|
||||
qDebug() << "WebcacheModel::WebcacheModel()";
|
||||
//qDebug() << "WebcacheModel::WebcacheModel()";
|
||||
reload();
|
||||
}
|
||||
|
||||
void WebcacheModel::reload()
|
||||
{
|
||||
m->cache =
|
||||
STD_SHARED_PTR<BeagleQueueCache>(new BeagleQueueCache(theconfig));
|
||||
|
||||
m->all.clear();
|
||||
m->disp.clear();
|
||||
|
||||
if (m->cache) {
|
||||
bool eof;
|
||||
m->cache->cc()->rewind(eof);
|
||||
@ -80,6 +92,21 @@ WebcacheModel::WebcacheModel(QObject *parent)
|
||||
break;
|
||||
}
|
||||
}
|
||||
emit dataChanged(createIndex(0,0,0), createIndex(1, m->all.size(),0));
|
||||
}
|
||||
|
||||
bool WebcacheModel::deleteIdx(unsigned int idx)
|
||||
{
|
||||
if (idx > m->disp.size() || !m->cache)
|
||||
return false;
|
||||
return m->cache->cc()->erase(m->disp[idx].udi, true);
|
||||
}
|
||||
|
||||
string WebcacheModel::getURL(unsigned int idx)
|
||||
{
|
||||
if (idx > m->disp.size() || !m->cache)
|
||||
return string();
|
||||
return m->disp[idx].url;
|
||||
}
|
||||
|
||||
int WebcacheModel::rowCount(const QModelIndex&) const
|
||||
@ -181,15 +208,120 @@ void WebcacheModel::setSearchFilter(const QString& _txt)
|
||||
emit dataChanged(createIndex(0,0,0), createIndex(1, m->all.size(),0));
|
||||
}
|
||||
|
||||
static const int ROWHEIGHTPAD = 2;
|
||||
static const char *cwnm = "/Recoll/prefs/webcachecolw";
|
||||
static const char *wwnm = "/Recoll/prefs/webcachew";
|
||||
static const char *whnm = "/Recoll/prefs/webcacheh";
|
||||
static const QKeySequence closeKS(Qt::ControlModifier+Qt::Key_W);
|
||||
|
||||
WebcacheEdit::WebcacheEdit(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
qDebug() << "WebcacheEdit::WebcacheEdit()";
|
||||
//qDebug() << "WebcacheEdit::WebcacheEdit()";
|
||||
setupUi(this);
|
||||
m_model = new WebcacheModel(this);
|
||||
webcacheTV->setModel(m_model);
|
||||
tableview->setModel(m_model);
|
||||
tableview->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
tableview->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
tableview->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
tableview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
||||
QSettings settings;
|
||||
QStringList wl;
|
||||
wl = settings.value(cwnm).toStringList();
|
||||
QHeaderView *header = tableview->horizontalHeader();
|
||||
if (header) {
|
||||
if (int(wl.size()) == header->count()) {
|
||||
for (int i = 0; i < header->count(); i++) {
|
||||
header->resizeSection(i, wl[i].toInt());
|
||||
}
|
||||
}
|
||||
}
|
||||
connect(header, SIGNAL(sectionResized(int,int,int)),
|
||||
this, SLOT(saveColState()));
|
||||
|
||||
header = tableview->verticalHeader();
|
||||
if (header) {
|
||||
header->setDefaultSectionSize(QApplication::fontMetrics().height() +
|
||||
ROWHEIGHTPAD);
|
||||
}
|
||||
|
||||
int width = settings.value(wwnm, 0).toInt();
|
||||
int height = settings.value(whnm, 0).toInt();
|
||||
if (width && height) {
|
||||
resize(QSize(width, height));
|
||||
}
|
||||
|
||||
connect(searchLE, SIGNAL(textEdited(const QString&)),
|
||||
m_model, SLOT(setSearchFilter(const QString&)));
|
||||
connect(new QShortcut(closeKS, this), SIGNAL (activated()),
|
||||
this, SLOT (close()));
|
||||
connect(tableview, SIGNAL(customContextMenuRequested(const QPoint&)),
|
||||
this, SLOT(createPopupMenu(const QPoint&)));
|
||||
|
||||
}
|
||||
|
||||
void WebcacheEdit::createPopupMenu(const QPoint& pos)
|
||||
{
|
||||
int selsz = tableview->selectionModel()->selectedRows().size();
|
||||
if (selsz <= 0) {
|
||||
return;
|
||||
}
|
||||
QMenu *popup = new QMenu(this);
|
||||
if (selsz == 1) {
|
||||
popup->addAction(tr("Copy URL"), this, SLOT(copyURL()));
|
||||
}
|
||||
popup->addAction(tr("Delete selection"), this, SLOT(deleteSelected()));
|
||||
|
||||
popup->popup(tableview->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void WebcacheEdit::deleteSelected()
|
||||
{
|
||||
QModelIndexList selection = tableview->selectionModel()->selectedRows();
|
||||
for (int i = 0; i < selection.size(); i++) {
|
||||
m_model->deleteIdx(selection[i].row());
|
||||
}
|
||||
m_model->reload();
|
||||
m_model->setSearchFilter(searchLE->text());
|
||||
tableview->clearSelection();
|
||||
}
|
||||
|
||||
void WebcacheEdit::copyURL()
|
||||
{
|
||||
QModelIndexList selection = tableview->selectionModel()->selectedRows();
|
||||
if (selection.size() != 1)
|
||||
return;
|
||||
string url = m_model->getURL(selection[0].row());
|
||||
if (!url.empty()) {
|
||||
url = url_encode(url, 7);
|
||||
QApplication::clipboard()->setText(url.c_str(),
|
||||
QClipboard::Selection);
|
||||
QApplication::clipboard()->setText(url.c_str(),
|
||||
QClipboard::Clipboard);
|
||||
}
|
||||
}
|
||||
|
||||
void WebcacheEdit::saveColState()
|
||||
{
|
||||
//qDebug() << "void WebcacheEdit::saveColState()";
|
||||
QHeaderView *header = tableview->horizontalHeader();
|
||||
QStringList newwidths;
|
||||
for (int vi = 0; vi < header->count(); vi++) {
|
||||
int li = header->logicalIndex(vi);
|
||||
newwidths.push_back(lltodecstr(header->sectionSize(li)).c_str());
|
||||
}
|
||||
|
||||
QSettings settings;
|
||||
settings.setValue(cwnm, newwidths);
|
||||
}
|
||||
|
||||
void WebcacheEdit::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
if (!isFullScreen()) {
|
||||
QSettings settings;
|
||||
settings.setValue(wwnm, width());
|
||||
settings.setValue(whnm, height());
|
||||
}
|
||||
event->accept();
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include <QAbstractTableModel>
|
||||
|
||||
class WebcacheModelInternal;
|
||||
class QCloseEvent;
|
||||
|
||||
class WebcacheModel : public QAbstractTableModel {
|
||||
Q_OBJECT;
|
||||
@ -41,9 +42,13 @@ public:
|
||||
int role = Qt::DisplayRole) const;
|
||||
virtual QVariant data(const QModelIndex& index,
|
||||
int role = Qt::DisplayRole ) const;
|
||||
bool deleteIdx(unsigned int idx);
|
||||
std::string getURL(unsigned int idx);
|
||||
void reload();
|
||||
|
||||
public slots:
|
||||
void setSearchFilter(const QString&);
|
||||
|
||||
|
||||
private:
|
||||
WebcacheModelInternal *m;
|
||||
};
|
||||
@ -53,6 +58,13 @@ class WebcacheEdit : public QDialog, public Ui::Webcache {
|
||||
|
||||
public:
|
||||
WebcacheEdit(QWidget *parent);
|
||||
public slots:
|
||||
void saveColState();
|
||||
void createPopupMenu(const QPoint&);
|
||||
void deleteSelected();
|
||||
void copyURL();
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *);
|
||||
private:
|
||||
WebcacheModel *m_model;
|
||||
};
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableView" name="webcacheTV">
|
||||
<widget class="QTableView" name="tableview">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
|
||||
@ -441,7 +441,8 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool writeEntryHeader(off_t offset, const EntryHeaderData& d) {
|
||||
bool writeEntryHeader(off_t offset, const EntryHeaderData& d,
|
||||
bool eraseData = false) {
|
||||
if (m_fd < 0) {
|
||||
m_reason << "writeEntryHeader: not open ";
|
||||
return false;
|
||||
@ -459,6 +460,17 @@ public:
|
||||
m_reason << "CirCache::weh: write failed. errno " << errno;
|
||||
return false;
|
||||
}
|
||||
if (eraseData == true) {
|
||||
if (d.dicsize || d.datasize) {
|
||||
m_reason << "CirCache::weh: erase requested but not empty";
|
||||
return false;
|
||||
}
|
||||
string buf(d.padsize, ' ');
|
||||
if (write(m_fd, buf.c_str(), d.padsize) != d.padsize) {
|
||||
m_reason << "CirCache::weh: write failed. errno " << errno;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -928,7 +940,7 @@ bool CirCache::get(const string& udi, string& dic, string *data, int instance)
|
||||
return bret;
|
||||
}
|
||||
|
||||
bool CirCache::erase(const string& udi)
|
||||
bool CirCache::erase(const string& udi, bool reallyclear)
|
||||
{
|
||||
if (m_d == 0) {
|
||||
LOGERR(("CirCache::erase: null data\n"));
|
||||
@ -960,21 +972,21 @@ bool CirCache::erase(const string& udi)
|
||||
}
|
||||
|
||||
for (vector<off_t>::iterator it = ofss.begin(); it != ofss.end(); it++) {
|
||||
LOGDEB(("CirCache::erase: reading at %lu\n", (unsigned long)*it));
|
||||
LOGDEB2(("CirCache::erase: reading at %lu\n", (unsigned long)*it));
|
||||
EntryHeaderData d;
|
||||
string fudi;
|
||||
if (!m_d->readHUdi(*it, d, fudi)) {
|
||||
return false;
|
||||
}
|
||||
LOGDEB(("CirCache::erase: found fudi [%s]\n", fudi.c_str()));
|
||||
LOGDEB2(("CirCache::erase: found fudi [%s]\n", fudi.c_str()));
|
||||
if (!fudi.compare(udi)) {
|
||||
EntryHeaderData nd;
|
||||
nd.padsize = d.dicsize + d.datasize + d.padsize;
|
||||
LOGDEB(("CirCache::erase: rewriting at %lu\n", (unsigned long)*it));
|
||||
LOGDEB2(("CirCache::erase: rewrite at %lu\n", (unsigned long)*it));
|
||||
if (*it == m_d->m_nheadoffs) {
|
||||
m_d->m_npadsize = nd.padsize;
|
||||
}
|
||||
if (!m_d->writeEntryHeader(*it, nd)) {
|
||||
if (!m_d->writeEntryHeader(*it, nd, reallyclear)) {
|
||||
LOGERR(("CirCache::erase: write header failed\n"));
|
||||
return false;
|
||||
}
|
||||
@ -1050,8 +1062,8 @@ bool CirCache::put(const string& udi, const ConfSimple *iconf,
|
||||
uLong len = compressBound(static_cast<uLong>(data.size()));
|
||||
char *bf = compbuf.setsize(len);
|
||||
if (bf != 0 &&
|
||||
compress((Bytef*)bf, &len, (Bytef*)data.c_str(), static_cast<uLong>(data.size()))
|
||||
== Z_OK) {
|
||||
compress((Bytef*)bf, &len, (Bytef*)data.c_str(),
|
||||
static_cast<uLong>(data.size())) == Z_OK) {
|
||||
if (float(len) < 0.9 * float(data.size())) {
|
||||
// bf is local but it's our static buffer address
|
||||
datap = bf;
|
||||
|
||||
@ -73,7 +73,7 @@ public:
|
||||
virtual bool put(const std::string& udi, const ConfSimple *dicp,
|
||||
const std::string& data, unsigned int flags = 0);
|
||||
|
||||
virtual bool erase(const std::string& udi);
|
||||
virtual bool erase(const std::string& udi, bool reallyclear = false);
|
||||
|
||||
/** Walk the archive.
|
||||
*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user