#include "custom_widgets.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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); 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); 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(&option); opt.features = v2 ? v2->features : QStyleOptionViewItemV2::ViewItemFeatures(QStyleOptionViewItemV2::None); const QStyleOptionViewItemV3 *v3 = qstyleoption_cast(&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(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(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; iindex(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); }