yacreader/common/custom_widgets.cpp
2012-08-26 20:16:15 +02:00

465 lines
12 KiB
C++

#include "custom_widgets.h"
#include <QMessageBox>
#include <QVBoxLayout>
#include <QFile>
#include <QTextStream>
#include <QScrollBar>
#include <QFont>
#include <QMouseEvent>
#include <QStyleOptionViewItem>
#include <QStyleOptionViewItemV4>
#include <QPainter>
#include <QtGlobal>
#include <QDesktopWidget>
#include <QApplication>
#include <QPushButton>
#include <QFileSystemModel>
#include <QTextCodec>
#include "qnaturalsorting.h"
HelpAboutDialog::HelpAboutDialog(QWidget * parent)
:QDialog(parent)
{
QVBoxLayout * layout = new QVBoxLayout();
tabWidget = new QTabWidget();
tabWidget->addTab(aboutText = new QTextBrowser(), tr("About"));
aboutText->setOpenExternalLinks(true);
aboutText->setFont(QFont("Comic Sans MS", 10)); //purisa
tabWidget->addTab(helpText = new QTextBrowser(), tr("Help"));
helpText->setOpenExternalLinks(true);
helpText->setFont(QFont("Comic Sans MS", 10));
//helpText->setDisabled(true);
//tabWidget->addTab(,"About Qt");
layout->addWidget(tabWidget);
layout->setContentsMargins(1,3,1,1);
setLayout(layout);
resize(500, QApplication::desktop()->availableGeometry().height()*0.83);
}
HelpAboutDialog::HelpAboutDialog(const QString & pathAbout,const QString & pathHelp,QWidget * parent)
:QDialog(parent)
{
loadAboutInformation(pathAbout);
loadHelp(pathHelp);
}
void HelpAboutDialog::loadAboutInformation(const QString & path)
{
aboutText->insertHtml(fileToString(path));
aboutText->moveCursor(QTextCursor::Start);
}
void HelpAboutDialog::loadHelp(const QString & path)
{
helpText->insertHtml(fileToString(path));
helpText->moveCursor(QTextCursor::Start);
}
QString HelpAboutDialog::fileToString(const QString & path)
{
QFile f(path);
f.open(QIODevice::ReadOnly);
QTextStream txtS(&f);
txtS.setCodec(QTextCodec::codecForName("UTF-8"));
QString content = txtS.readAll();
f.close();
return content;
}
void delTree(QDir dir)
{
dir.setFilter(QDir::AllDirs|QDir::Files|QDir::Hidden|QDir::NoDotAndDotDot);
QFileInfoList list = dir.entryInfoList();
for (int i = 0; i < list.size(); ++i)
{
QFileInfo fileInfo = list.at(i);
QString path = fileInfo.filePath();
if(fileInfo.isDir())
{
delTree(QDir(fileInfo.absoluteFilePath()));
dir.rmdir(fileInfo.absoluteFilePath());
}
else
{
dir.remove(fileInfo.absoluteFilePath());
}
}
}
YACReaderIconProvider::YACReaderIconProvider()
:QFileIconProvider()
{
}
QIcon YACReaderIconProvider::icon(IconType type) const
{
switch(type)
{
case Folder:
return QIcon(":/images/folder.png");
break;
case File:
return QIcon(":/images/icon.png");
break;
default:
return QFileIconProvider::icon(type);
}
}
QIcon YACReaderIconProvider::icon(const QFileInfo & info) const
{
if(info.isDir())
return QIcon(":/images/folder.png");
if(info.isFile())
return QIcon(":/images/icon.png");
}
QString YACReaderIconProvider::type(const QFileInfo & info) const
{
return QFileIconProvider::type(info);
}
YACReaderFlow::YACReaderFlow(QWidget * parent,FlowType flowType) : PictureFlow(parent,flowType) {}
void YACReaderFlow::mousePressEvent(QMouseEvent* event)
{
if(event->x() > (width()+slideSize().width())/2)
showNext();
else
if(event->x() < (width()-slideSize().width())/2)
showPrevious();
//else (centered cover space)
}
void YACReaderFlow::mouseDoubleClickEvent(QMouseEvent* event)
{
if((event->x() > (width()-slideSize().width())/2)&&(event->x() < (width()+slideSize().width())/2))
emit selected(centerIndex());
}
YACReaderComicDirModel::YACReaderComicDirModel( const QStringList & nameFilters, QDir::Filters filters, QDir::SortFlags sort, QObject * parent )
:QDirModel(nameFilters,filters,sort,parent)
{
}
//this method isn't used to show fileName on QListView
QString YACReaderComicDirModel::fileName ( const QModelIndex & index ) const
{
QString fileName = QDirModel::fileName(index);
return fileName.remove(fileName.size()-4,4);
}
QFileInfo YACReaderComicDirModel::fileInfo ( const QModelIndex & index ) const
{
QFileInfo fileInfo = QDirModel::fileInfo(index);
QString path = QDir::cleanPath(filePath(index)).remove("/.yacreaderlibrary");
path.remove(path.size()-4,4);
fileInfo.setFile(path);
return fileInfo;
}
YACReaderComicViewDelegate::YACReaderComicViewDelegate(QObject * parent)
:QItemDelegate(parent)
{
}
void YACReaderComicViewDelegate::paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
QStyleOptionViewItemV4 opt = setOptions(index, option);
const QStyleOptionViewItemV2 *v2 = qstyleoption_cast<const QStyleOptionViewItemV2 *>(&option);
opt.features = v2 ? v2->features
: QStyleOptionViewItemV2::ViewItemFeatures(QStyleOptionViewItemV2::None);
const QStyleOptionViewItemV3 *v3 = qstyleoption_cast<const QStyleOptionViewItemV3 *>(&option);
opt.locale = v3 ? v3->locale : QLocale();
opt.widget = v3 ? v3->widget : 0;
// prepare
painter->save();
painter->setClipRect(opt.rect);
// get the data and the rectangles
QVariant value;
QPixmap pixmap;
QRect decorationRect;
QIcon icon;
value = index.data(Qt::DecorationRole);
if (value.isValid()) {
// ### we need the pixmap to call the virtual function
pixmap = decoration(opt, value);
if (value.type() == QVariant::Icon) {
icon = qvariant_cast<QIcon>(value);
const QSize size = icon.actualSize(option.decorationSize);
decorationRect = QRect(QPoint(0, 0), size);
} else {
icon = QIcon();
decorationRect = QRect(QPoint(0, 0), pixmap.size());
}
} else {
icon = QIcon();
decorationRect = QRect();
}
QString text;
QRect displayRect;
value = index.data(Qt::DisplayRole);
if (value.isValid() && !value.isNull()) {
text = value.toString();
text.remove(text.size()-4,4);
displayRect = textRectangle(painter, textLayoutBounds(opt), opt.font, text);
}
QRect checkRect;
Qt::CheckState checkState = Qt::Unchecked;
value = index.data(Qt::CheckStateRole);
if (value.isValid()) {
checkState = static_cast<Qt::CheckState>(value.toInt());
checkRect = check(opt, opt.rect, value);
}
// do the layout
doLayout(opt, &checkRect, &decorationRect, &displayRect, false);
// draw the item
drawBackground(painter, opt, index);
drawCheck(painter, opt, checkRect, checkState);
drawDecoration(painter, opt, decorationRect, pixmap);
drawDisplay(painter, opt, displayRect, text);
drawFocus(painter, opt, displayRect);
// done
painter->restore();
}
QRect YACReaderComicViewDelegate::textLayoutBounds(const QStyleOptionViewItemV2 &option) const
{
QRect rect = option.rect;
const bool wrapText = option.features & QStyleOptionViewItemV2::WrapText;
switch (option.decorationPosition) {
case QStyleOptionViewItem::Left:
case QStyleOptionViewItem::Right:
rect.setWidth(wrapText && rect.isValid() ? rect.width() : (1000));
break;
case QStyleOptionViewItem::Top:
case QStyleOptionViewItem::Bottom:
rect.setWidth(wrapText ? option.decorationSize.width() : (1000));
break;
}
return rect;
}
YACReaderTreeSearch::YACReaderTreeSearch(QObject * parent)
:QSortFilterProxyModel(parent),cache(new ModelIndexCache())
{
this->setFilterCaseSensitivity(Qt::CaseInsensitive);
}
bool YACReaderTreeSearch::containsFiles(QString path,const QRegExp &exp) const
{
QDir dir(path);
QStringList list = dir.entryList(QStringList() << "*"+exp.pattern()+"*",QDir::Files | QDir::NoDotAndDotDot);
return list.size()>0;
}
bool YACReaderTreeSearch::itemMatchesExpression(const QModelIndex &index, const QRegExp &exp) const
{
QString name = ((QFileSystemModel *)sourceModel())->filePath(index);
ModelIndexCache::CacheData cd = cache->getCacheData(name);
bool v = false;
if(!cd.visited || cd.acepted)
{
v = name.contains(exp);// || containsFiles(name,exp); // TODO : complete path?
int numChildren = sourceModel()->rowCount(index);
for(int i=0; i<numChildren;i++)
{
if(v) break;
v = v || itemMatchesExpression(sourceModel()->index(i,0,index), exp);
}
cd.visited = true;
cd.acepted = v;
cache->setModelIndex(name,cd);
}
return cd.acepted;
}
bool YACReaderTreeSearch::filterAcceptsRow ( int sourceRow, const QModelIndex & sourceParent ) const
{
QString name = sourceModel()->data(sourceModel()->index(sourceRow, 0, sourceParent),Qt::DisplayRole ).toString();
QFileSystemModel * dm = (QFileSystemModel *)sourceModel();
if(!dm->isDir(dm->index(sourceRow, 0, sourceParent)))
//if(name.endsWith(".jpg")||name.endsWith(".db")) //TODO: if is not a dir
return false;
if(filterRegExp().isEmpty())
return true;
if(name.contains("yacreader"))
return true;
QString path = dm->filePath(dm->index(sourceRow, 0, sourceParent));
if(path.contains("yacreaderlibrary"))
return itemMatchesExpression(sourceModel()->index(sourceRow, 0, sourceParent), filterRegExp());
else
return true;
}
void YACReaderTreeSearch::reset()
{
//invalidateFilter();
cache->clear();
}
void YACReaderTreeSearch::softReset()
{
//invalidateFilter();
}
ModelIndexCache::ModelIndexCache()
:cache()
{
}
void ModelIndexCache::setModelIndex(const QString & index, const CacheData & cd)
{
cache.insert(index,cd);
}
ModelIndexCache::CacheData ModelIndexCache::getCacheData(const QString & index) const
{
if(cache.contains(index))
return cache.value(index);
else
{
CacheData cd;
cd.visited = false;
cd.acepted = true;
return cd;
}
}
void ModelIndexCache::clear()
{
cache.clear();
}
YACReaderSortComics::YACReaderSortComics(QObject * parent)
:QSortFilterProxyModel(parent)
{
}
bool YACReaderSortComics::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
QVariant leftData = sourceModel()->data(left);
QVariant rightData = sourceModel()->data(right);
QString leftString = leftData.toString();
QString rightString = rightData.toString();
return naturalSortLessThanCI(leftString,rightString);
}
//--------------------------------------------
YACReaderFieldEdit::YACReaderFieldEdit(QWidget * parent)
:QLineEdit(parent)
{
setPlaceholderText(tr("Click to overwrite"));
setModified(false);
restore = new QAction(tr("Restore to default"),this);
this->addAction(restore);
//this->setContextMenuPolicy(Qt::ActionsContextMenu);
}
void YACReaderFieldEdit::focusInEvent(QFocusEvent* e)
{
if (e->reason() == Qt::MouseFocusReason)
{
setModified(true);
setPlaceholderText("");
}
QLineEdit::focusInEvent(e);
}
void YACReaderFieldEdit::clear()
{
setPlaceholderText(tr("Click to overwrite"));
QLineEdit::clear();
QLineEdit::setModified(false);
}
void YACReaderFieldEdit::setDisabled(bool disabled)
{
if(disabled)
setPlaceholderText("");
QLineEdit::setDisabled(disabled);
}
//--------------------------------------------
YACReaderFieldPlainTextEdit::YACReaderFieldPlainTextEdit(QWidget * parent)
:QPlainTextEdit(parent)
{
document()->setModified(false);
setPlainText(tr("Click to overwrite"));
restore = new QAction(tr("Restore to default"),this);
this->addAction(restore);
//this->setContextMenuPolicy(Qt::ActionsContextMenu);
}
void YACReaderFieldPlainTextEdit::focusInEvent(QFocusEvent* e)
{
if (e->reason() == Qt::MouseFocusReason || e->reason() == Qt::TabFocusReason)
{
document()->setModified(true);
if(toPlainText()==tr("Click to overwrite"))
setPlainText("");
}
QPlainTextEdit::focusInEvent(e);
}
void YACReaderFieldPlainTextEdit::focusOutEvent(QFocusEvent* e)
{
/*if (e->reason() == Qt::MouseFocusReason || e->reason() == Qt::TabFocusReason)
{
if(toPlainText().isEmpty())
{
setPlainText(tr("Click to overwrite"));
document()->setModified(false);
}
}
*/
QPlainTextEdit::focusOutEvent(e);
}
void YACReaderFieldPlainTextEdit::clear()
{
QPlainTextEdit::clear();
document()->setModified(false);
setPlainText(tr("Click to overwrite"));
}
void YACReaderFieldPlainTextEdit::setDisabled(bool disabled)
{
if(disabled)
setPlainText(tr("Click to overwrite"));
QPlainTextEdit::setDisabled(disabled);
}