mirror of
https://github.com/YACReader/yacreader
synced 2025-07-22 15:04:40 -04:00
cambiado casting de void * a uint por qint64 (se evita el error ce compilaci?n
al compilar en 64 bit)
This commit is contained in:
112
common/check_new_version.cpp
Normal file
112
common/check_new_version.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
#include "check_new_version.h"
|
||||
#include <QMessageBox>
|
||||
#include <QUrl>
|
||||
#include <QtGlobal>
|
||||
#include <QStringList>
|
||||
|
||||
#define PREVIOUS_VERSION "0.4.5"
|
||||
|
||||
HttpVersionChecker::HttpVersionChecker()
|
||||
:QWidget()
|
||||
{
|
||||
http = new QHttp(this);
|
||||
|
||||
connect(http, SIGNAL(requestFinished(int, bool)),
|
||||
this, SLOT(httpRequestFinished(int, bool)));
|
||||
|
||||
connect(http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)),
|
||||
this, SLOT(readResponseHeader(const QHttpResponseHeader &)));
|
||||
|
||||
connect(http, SIGNAL(readyRead(const QHttpResponseHeader &)),
|
||||
this, SLOT(read(const QHttpResponseHeader &)));
|
||||
}
|
||||
|
||||
void HttpVersionChecker::get()
|
||||
{
|
||||
QUrl url("http://code.google.com/p/yacreader/downloads/list");
|
||||
QHttp::ConnectionMode mode = QHttp::ConnectionModeHttp;
|
||||
http->setHost(url.host(), mode, url.port() == -1 ? 0 : url.port());
|
||||
QByteArray path = QUrl::toPercentEncoding(url.path(), "!$&'()*+,;=:@/");
|
||||
if (path.isEmpty())
|
||||
path = "/";
|
||||
httpGetId = http->get(path, 0);
|
||||
}
|
||||
void HttpVersionChecker::readResponseHeader(const QHttpResponseHeader &responseHeader)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void HttpVersionChecker::read(const QHttpResponseHeader &){
|
||||
content.append(http->readAll());
|
||||
}
|
||||
|
||||
void HttpVersionChecker::httpRequestFinished(int requestId, bool error)
|
||||
{
|
||||
#ifdef QT_DEBUG
|
||||
QString response("YACReader-5.0.0 win32.exe");
|
||||
#else
|
||||
QString response(content);
|
||||
#endif
|
||||
checkNewVersion(response);
|
||||
}
|
||||
|
||||
//TODO escribir prueba unitaria
|
||||
bool HttpVersionChecker::checkNewVersion(QString sourceContent)
|
||||
{
|
||||
#ifdef Q_WS_WIN
|
||||
QRegExp rx(".*YACReader\\-([0-9]+).([0-9]+).([0-9]+)\\.?([0-9]+)?.{0,5}win32.*");
|
||||
#endif
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
QRegExp rx(".*YACReader\\-([0-9]+).([0-9]+).([0-9]+)\\.?([0-9]+)?.{0,5}X11.*");
|
||||
#endif
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
QRegExp rx(".*YACReader\\-([0-9]+).([0-9]+).([0-9]+)\\.?([0-9]+)?.{0,5}Mac.*");
|
||||
#endif
|
||||
|
||||
int index = 0;
|
||||
bool newVersion = false;
|
||||
bool sameVersion = true;
|
||||
//bool currentVersionIsNewer = false;
|
||||
#ifdef QT_DEBUG
|
||||
QString version(PREVIOUS_VERSION);
|
||||
#else
|
||||
QString version(VERSION);
|
||||
#endif
|
||||
QStringList sl = version.split(".");
|
||||
if((index = rx.indexIn(sourceContent))!=-1)
|
||||
{
|
||||
int length = qMin(sl.size(),(rx.cap(4)!="")?4:3);
|
||||
for(int i=0;i<length;i++)
|
||||
{
|
||||
if(rx.cap(i+1).toInt()<sl.at(i).toInt())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(rx.cap(i+1).toInt()>sl.at(i).toInt()){
|
||||
newVersion=true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
sameVersion = sameVersion && rx.cap(i+1).toInt()==sl.at(i).toInt();
|
||||
}
|
||||
if(!newVersion && sameVersion)
|
||||
{
|
||||
if((sl.size()==3)&&(rx.cap(4)!=""))
|
||||
newVersion = true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if(newVersion == true)
|
||||
{
|
||||
emit newVersionDetected();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
32
common/check_new_version.h
Normal file
32
common/check_new_version.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef __CHECKUPDATE_H
|
||||
#define __CHECKUPDATE_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QHttp>
|
||||
#include <QHttpResponseHeader>
|
||||
#include <QByteArray>
|
||||
|
||||
#define VERSION "5.0.0"
|
||||
|
||||
class HttpVersionChecker : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HttpVersionChecker();
|
||||
bool thereIsNewVersion();
|
||||
public slots:
|
||||
void httpRequestFinished(int requestId, bool error);
|
||||
void readResponseHeader(const QHttpResponseHeader &);
|
||||
void read(const QHttpResponseHeader &);
|
||||
void get();
|
||||
private:
|
||||
QHttp *http;
|
||||
int httpGetId;
|
||||
QByteArray content;
|
||||
bool found;
|
||||
bool checkNewVersion(QString sourceContent);
|
||||
signals:
|
||||
void newVersionDetected();
|
||||
};
|
||||
|
||||
#endif
|
461
common/custom_widgets.cpp
Normal file
461
common/custom_widgets.cpp
Normal file
@ -0,0 +1,461 @@
|
||||
#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 "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);
|
||||
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);
|
||||
}
|
189
common/custom_widgets.h
Normal file
189
common/custom_widgets.h
Normal file
@ -0,0 +1,189 @@
|
||||
#ifndef __CUSTOM_WIDGETS_H
|
||||
#define __CUSTOM_WIDGETS_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QHBoxLayout>
|
||||
#include <QTabWidget>
|
||||
#include <QTextBrowser>
|
||||
#include <QDir>
|
||||
#include <QFileIconProvider>
|
||||
#include <QDirModel>
|
||||
#include <QFileInfo>
|
||||
#include <QItemDelegate>
|
||||
#include <QStyleOptionViewItemV2>
|
||||
#include <QStyleOptionViewItemV4>
|
||||
#include <QVariant>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QModelIndex>
|
||||
#include <QRegExp>
|
||||
#include <QHash>
|
||||
#include <QLineEdit>
|
||||
#include <QAction>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QTableView>
|
||||
|
||||
#include "pictureflow.h"
|
||||
|
||||
class QToolBarStretch : public QWidget
|
||||
{
|
||||
public:
|
||||
QToolBarStretch(QWidget * parent=0):QWidget(parent)
|
||||
{
|
||||
QHBoxLayout * l= new QHBoxLayout();
|
||||
l->addStretch();
|
||||
setLayout(l);
|
||||
}
|
||||
};
|
||||
|
||||
class HelpAboutDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HelpAboutDialog(QWidget * parent=0);
|
||||
HelpAboutDialog(const QString & pathAbout,const QString & pathHelp,QWidget * parent =0);
|
||||
public slots:
|
||||
void loadAboutInformation(const QString & path);
|
||||
void loadHelp(const QString & path);
|
||||
|
||||
private:
|
||||
QTabWidget *tabWidget;
|
||||
QTextBrowser *aboutText;
|
||||
QTextBrowser *helpText;
|
||||
QString fileToString(const QString & path);
|
||||
};
|
||||
|
||||
class YACReaderIconProvider : public QFileIconProvider
|
||||
{
|
||||
public:
|
||||
YACReaderIconProvider();
|
||||
virtual QIcon icon ( IconType type ) const;
|
||||
virtual QIcon icon ( const QFileInfo & info ) const;
|
||||
virtual QString type ( const QFileInfo & info ) const;
|
||||
};
|
||||
|
||||
class YACReaderFlow : public PictureFlow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
YACReaderFlow(QWidget * parent,FlowType flowType = CoverFlowLike);
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void mouseDoubleClickEvent(QMouseEvent* event);
|
||||
|
||||
signals:
|
||||
void selected(unsigned int centerIndex);
|
||||
};
|
||||
|
||||
class YACReaderComicDirModel : public QDirModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
YACReaderComicDirModel( const QStringList & nameFilters, QDir::Filters filters, QDir::SortFlags sort, QObject * parent = 0 );
|
||||
QString fileName ( const QModelIndex & index ) const;
|
||||
QFileInfo fileInfo ( const QModelIndex & index ) const;
|
||||
};
|
||||
|
||||
class YACReaderComicViewDelegate : public QItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
YACReaderComicViewDelegate(QObject * parent = 0);
|
||||
virtual void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
|
||||
QRect textLayoutBounds(const QStyleOptionViewItemV2 &option) const;
|
||||
};
|
||||
|
||||
class ModelIndexCache
|
||||
{
|
||||
|
||||
public:
|
||||
struct CacheData{
|
||||
bool visited;
|
||||
bool acepted;
|
||||
};
|
||||
ModelIndexCache();
|
||||
void setModelIndex(const QString & index, const CacheData & cd);
|
||||
CacheData getCacheData(const QString & index) const;
|
||||
void clear();
|
||||
|
||||
|
||||
private:
|
||||
QHash<QString, CacheData> cache;
|
||||
};
|
||||
|
||||
|
||||
class YACReaderTreeSearch : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
YACReaderTreeSearch(QObject * parent = 0);
|
||||
protected:
|
||||
virtual bool filterAcceptsRow ( int sourceRow, const QModelIndex & source_parent ) const;
|
||||
bool itemMatchesExpression(const QModelIndex &index, const QRegExp &exp) const;
|
||||
bool containsFiles(QString path,const QRegExp &exp) const;
|
||||
public slots:
|
||||
void reset();
|
||||
void softReset();
|
||||
private:
|
||||
ModelIndexCache * cache;
|
||||
};
|
||||
|
||||
class YACReaderSortComics : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
YACReaderSortComics(QObject * parent = 0);
|
||||
protected:
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
|
||||
};
|
||||
|
||||
void delTree(QDir dir);
|
||||
|
||||
|
||||
class YACReaderFieldEdit : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
YACReaderFieldEdit(QWidget * parent = 0);
|
||||
void clear();
|
||||
void setDisabled(bool disabled);
|
||||
protected:
|
||||
void focusInEvent(QFocusEvent* e);
|
||||
private:
|
||||
QAction * restore;
|
||||
|
||||
};
|
||||
|
||||
class YACReaderFieldPlainTextEdit : public QPlainTextEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
YACReaderFieldPlainTextEdit(QWidget * parent = 0);
|
||||
void clear();
|
||||
void setDisabled(bool disabled);
|
||||
protected:
|
||||
void focusInEvent(QFocusEvent* e);
|
||||
void focusOutEvent(QFocusEvent* e);
|
||||
private:
|
||||
QAction * restore;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//class YACReaderTableView : public QTableView
|
||||
//{
|
||||
// Q_OBJECT
|
||||
//public:
|
||||
// YACReaderTableView(QWidget *parent = 0)
|
||||
// : QTableView(parent) {}
|
||||
//
|
||||
//protected:
|
||||
// bool viewportEvent ( QEvent * event )
|
||||
// {
|
||||
// resizeColumnsToContents();
|
||||
// return QTableView::viewportEvent(event);
|
||||
// }
|
||||
//};
|
||||
|
||||
#endif
|
||||
|
||||
|
1332
common/pictureflow.cpp
Normal file
1332
common/pictureflow.cpp
Normal file
File diff suppressed because it is too large
Load Diff
224
common/pictureflow.h
Normal file
224
common/pictureflow.h
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
PictureFlow - animated image show widget
|
||||
http://pictureflow.googlecode.com
|
||||
|
||||
Copyright (C) 2008 Ariya Hidayat (ariya@kde.org)
|
||||
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PICTUREFLOW_H
|
||||
#define PICTUREFLOW_H
|
||||
|
||||
#include <qwidget.h>
|
||||
|
||||
class PictureFlowPrivate;
|
||||
|
||||
/*!
|
||||
Class PictureFlow implements an image show widget with animation effect
|
||||
like Apple's CoverFlow (in iTunes and iPod). Images are arranged in form
|
||||
of slides, one main slide is shown at the center with few slides on
|
||||
the left and right sides of the center slide. When the next or previous
|
||||
slide is brought to the front, the whole slides flow to the right or
|
||||
the right with smooth animation effect; until the new slide is finally
|
||||
placed at the center.
|
||||
|
||||
*/
|
||||
class PictureFlow : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)
|
||||
Q_PROPERTY(QSize slideSize READ slideSize WRITE setSlideSize)
|
||||
Q_PROPERTY(int slideCount READ slideCount)
|
||||
Q_PROPERTY(int centerIndex READ centerIndex WRITE setCenterIndex)
|
||||
|
||||
public:
|
||||
|
||||
enum ReflectionEffect
|
||||
{
|
||||
NoReflection,
|
||||
PlainReflection,
|
||||
BlurredReflection
|
||||
};
|
||||
|
||||
enum FlowType
|
||||
{
|
||||
CoverFlowLike,
|
||||
Strip,
|
||||
StripOverlapped
|
||||
};
|
||||
|
||||
/*!
|
||||
Creates a new PictureFlow widget.
|
||||
*/
|
||||
PictureFlow(QWidget* parent = 0, FlowType flowType = CoverFlowLike);
|
||||
|
||||
/*!
|
||||
Destroys the widget.
|
||||
*/
|
||||
~PictureFlow();
|
||||
|
||||
/*!
|
||||
Returns the background color.
|
||||
*/
|
||||
QColor backgroundColor() const;
|
||||
|
||||
/*!
|
||||
Sets the background color. By default it is black.
|
||||
*/
|
||||
void setBackgroundColor(const QColor& c);
|
||||
|
||||
/*!
|
||||
Returns the dimension of each slide (in pixels).
|
||||
*/
|
||||
QSize slideSize() const;
|
||||
|
||||
/*!
|
||||
Sets the dimension of each slide (in pixels).
|
||||
*/
|
||||
void setSlideSize(QSize size);
|
||||
|
||||
/*!
|
||||
Returns the total number of slides.
|
||||
*/
|
||||
int slideCount() const;
|
||||
|
||||
/*!
|
||||
Returns QImage of specified slide.
|
||||
*/
|
||||
QImage slide(int index) const;
|
||||
|
||||
/*!
|
||||
Returns the index of slide currently shown in the middle of the viewport.
|
||||
*/
|
||||
int centerIndex() const;
|
||||
|
||||
/*!
|
||||
Returns the effect applied to the reflection.
|
||||
*/
|
||||
ReflectionEffect reflectionEffect() const;
|
||||
|
||||
/*!
|
||||
Sets the effect applied to the reflection. The default is PlainReflection.
|
||||
*/
|
||||
void setReflectionEffect(ReflectionEffect effect);
|
||||
|
||||
|
||||
public slots:
|
||||
|
||||
/*!
|
||||
Adds a new slide.
|
||||
*/
|
||||
void addSlide(const QImage& image);
|
||||
|
||||
/*!
|
||||
Adds a new slide.
|
||||
*/
|
||||
void addSlide(const QPixmap& pixmap);
|
||||
|
||||
/*!
|
||||
Sets an image for specified slide. If the slide already exists,
|
||||
it will be replaced.
|
||||
*/
|
||||
void setSlide(int index, const QImage& image);
|
||||
|
||||
/*!
|
||||
Sets a pixmap for specified slide. If the slide already exists,
|
||||
it will be replaced.
|
||||
*/
|
||||
void setSlide(int index, const QPixmap& pixmap);
|
||||
|
||||
/*!
|
||||
Sets slide to be shown in the middle of the viewport. No animation
|
||||
effect will be produced, unlike using showSlide.
|
||||
*/
|
||||
void setCenterIndex(int index);
|
||||
|
||||
/*!
|
||||
Clears all slides.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/*!
|
||||
Shows previous slide using animation effect.
|
||||
*/
|
||||
void showPrevious();
|
||||
|
||||
/*!
|
||||
Shows next slide using animation effect.
|
||||
*/
|
||||
void showNext();
|
||||
|
||||
/*!
|
||||
Go to specified slide using animation effect.
|
||||
*/
|
||||
void showSlide(int index);
|
||||
|
||||
/*!
|
||||
Rerender the widget. Normally this function will be automatically invoked
|
||||
whenever necessary, e.g. during the transition animation.
|
||||
*/
|
||||
void render();
|
||||
|
||||
/*!
|
||||
Schedules a rendering update. Unlike render(), this function does not cause
|
||||
immediate rendering.
|
||||
*/
|
||||
void triggerRender();
|
||||
|
||||
void setFlowType(FlowType flowType);
|
||||
|
||||
void setMarkImage(const QImage & mark);
|
||||
|
||||
void markSlide(int index);
|
||||
|
||||
void updateMarks();
|
||||
|
||||
void unmarkSlide(int index);
|
||||
|
||||
void setMarks(const QVector<bool> & marks);
|
||||
|
||||
void setShowMarks(bool enable);
|
||||
|
||||
QVector<bool> getMarks();
|
||||
|
||||
|
||||
signals:
|
||||
void centerIndexChanged(int index);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
void keyPressEvent(QKeyEvent* event);
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void resizeEvent(QResizeEvent* event);
|
||||
|
||||
private slots:
|
||||
void updateAnimation();
|
||||
|
||||
private:
|
||||
PictureFlowPrivate* d;
|
||||
QImage mark;
|
||||
QVector<bool> marks;
|
||||
int framesSkip;
|
||||
};
|
||||
|
||||
#endif // PICTUREFLOW_H
|
||||
|
257
common/qnaturalsorting.cpp
Normal file
257
common/qnaturalsorting.cpp
Normal file
@ -0,0 +1,257 @@
|
||||
/* This file contains parts of the KDE libraries
|
||||
Copyright (C) 1999 Ian Zepp (icszepp@islc.net)
|
||||
Copyright (C) 2006 by Dominic Battre <dominic@battre.de>
|
||||
Copyright (C) 2006 by Martin Pool <mbp@canonical.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "qnaturalsorting.h"
|
||||
|
||||
//from KDE
|
||||
/*
|
||||
int naturalCompare(const QString &_a, const QString &_b, Qt::CaseSensitivity caseSensitivity)
|
||||
{
|
||||
// This method chops the input a and b into pieces of
|
||||
// digits and non-digits (a1.05 becomes a | 1 | . | 05)
|
||||
// and compares these pieces of a and b to each other
|
||||
// (first with first, second with second, ...).
|
||||
//
|
||||
// This is based on the natural sort order code code by Martin Pool
|
||||
// http://sourcefrog.net/projects/natsort/
|
||||
// Martin Pool agreed to license this under LGPL or GPL.
|
||||
|
||||
// FIXME: Using toLower() to implement case insensitive comparison is
|
||||
// sub-optimal, but is needed because we compare strings with
|
||||
// localeAwareCompare(), which does not know about case sensitivity.
|
||||
// A task has been filled for this in Qt Task Tracker with ID 205990.
|
||||
// http://trolltech.com/developer/task-tracker/index_html?method=entry&id=205990
|
||||
QString a;
|
||||
QString b;
|
||||
if (caseSensitivity == Qt::CaseSensitive) {
|
||||
a = _a;
|
||||
b = _b;
|
||||
} else {
|
||||
a = _a.toLower();
|
||||
b = _b.toLower();
|
||||
}
|
||||
|
||||
const QChar* currA = a.unicode(); // iterator over a
|
||||
const QChar* currB = b.unicode(); // iterator over b
|
||||
|
||||
if (currA == currB) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const QChar* begSeqA = currA; // beginning of a new character sequence of a
|
||||
const QChar* begSeqB = currB;
|
||||
|
||||
while (!currA->isNull() && !currB->isNull()) {
|
||||
if (currA->unicode() == QChar::ObjectReplacementCharacter) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (currB->unicode() == QChar::ObjectReplacementCharacter) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (currA->unicode() == QChar::ReplacementCharacter) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (currB->unicode() == QChar::ReplacementCharacter) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// find sequence of characters ending at the first non-character
|
||||
while (!currA->isNull() && !currA->isDigit() && !currA->isPunct() && !currA->isSpace()) {
|
||||
++currA;
|
||||
}
|
||||
|
||||
while (!currB->isNull() && !currB->isDigit() && !currB->isPunct() && !currB->isSpace()) {
|
||||
++currB;
|
||||
}
|
||||
|
||||
// compare these sequences
|
||||
const QStringRef& subA(a.midRef(begSeqA - a.unicode(), currA - begSeqA));
|
||||
const QStringRef& subB(b.midRef(begSeqB - b.unicode(), currB - begSeqB));
|
||||
const int cmp = QStringRef::localeAwareCompare(subA, subB);
|
||||
if (cmp != 0) {
|
||||
return cmp < 0 ? -1 : +1;
|
||||
}
|
||||
|
||||
if (currA->isNull() || currB->isNull()) {
|
||||
break;
|
||||
}
|
||||
|
||||
// find sequence of characters ending at the first non-character
|
||||
while (currA->isPunct() || currA->isSpace() || currB->isPunct() || currB->isSpace()) {
|
||||
if (*currA != *currB) {
|
||||
return (*currA < *currB) ? -1 : +1;
|
||||
}
|
||||
++currA;
|
||||
++currB;
|
||||
}
|
||||
|
||||
// now some digits follow...
|
||||
if ((*currA == '0') || (*currB == '0')) {
|
||||
// one digit-sequence starts with 0 -> assume we are in a fraction part
|
||||
// do left aligned comparison (numbers are considered left aligned)
|
||||
while (1) {
|
||||
if (!currA->isDigit() && !currB->isDigit()) {
|
||||
break;
|
||||
} else if (!currA->isDigit()) {
|
||||
return +1;
|
||||
} else if (!currB->isDigit()) {
|
||||
return -1;
|
||||
} else if (*currA < *currB) {
|
||||
return -1;
|
||||
} else if (*currA > *currB) {
|
||||
return + 1;
|
||||
}
|
||||
++currA;
|
||||
++currB;
|
||||
}
|
||||
} else {
|
||||
// No digit-sequence starts with 0 -> assume we are looking at some integer
|
||||
// do right aligned comparison.
|
||||
//
|
||||
// The longest run of digits wins. That aside, the greatest
|
||||
// value wins, but we can't know that it will until we've scanned
|
||||
// both numbers to know that they have the same magnitude.
|
||||
|
||||
bool isFirstRun = true;
|
||||
int weight = 0;
|
||||
while (1) {
|
||||
if (!currA->isDigit() && !currB->isDigit()) {
|
||||
if (weight != 0) {
|
||||
return weight;
|
||||
}
|
||||
break;
|
||||
} else if (!currA->isDigit()) {
|
||||
if (isFirstRun) {
|
||||
return *currA < *currB ? -1 : +1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else if (!currB->isDigit()) {
|
||||
if (isFirstRun) {
|
||||
return *currA < *currB ? -1 : +1;
|
||||
} else {
|
||||
return +1;
|
||||
}
|
||||
} else if ((*currA < *currB) && (weight == 0)) {
|
||||
weight = -1;
|
||||
} else if ((*currA > *currB) && (weight == 0)) {
|
||||
weight = + 1;
|
||||
}
|
||||
++currA;
|
||||
++currB;
|
||||
isFirstRun = false;
|
||||
}
|
||||
}
|
||||
|
||||
begSeqA = currA;
|
||||
begSeqB = currB;
|
||||
}
|
||||
|
||||
if (currA->isNull() && currB->isNull()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return currA->isNull() ? -1 : + 1;
|
||||
}
|
||||
|
||||
*/
|
||||
static inline QChar getNextChar(const QString &s, int location)
|
||||
{
|
||||
return (location < s.length()) ? s.at(location) : QChar();
|
||||
}
|
||||
|
||||
int naturalCompare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs)
|
||||
{
|
||||
for (int l1 = 0, l2 = 0; l1 <= s1.count() && l2 <= s2.count(); ++l1, ++l2) {
|
||||
// skip spaces, tabs and 0's
|
||||
QChar c1 = getNextChar(s1, l1);
|
||||
while (c1.isSpace())
|
||||
c1 = getNextChar(s1, ++l1);
|
||||
QChar c2 = getNextChar(s2, l2);
|
||||
while (c2.isSpace())
|
||||
c2 = getNextChar(s2, ++l2);
|
||||
|
||||
if (c1.isDigit() && c2.isDigit()) {
|
||||
while (c1.digitValue() == 0)
|
||||
c1 = getNextChar(s1, ++l1);
|
||||
while (c2.digitValue() == 0)
|
||||
c2 = getNextChar(s2, ++l2);
|
||||
|
||||
int lookAheadLocation1 = l1;
|
||||
int lookAheadLocation2 = l2;
|
||||
int currentReturnValue = 0;
|
||||
// find the last digit, setting currentReturnValue as we go if it isn't equal
|
||||
for (
|
||||
QChar lookAhead1 = c1, lookAhead2 = c2;
|
||||
(lookAheadLocation1 <= s1.length() && lookAheadLocation2 <= s2.length());
|
||||
lookAhead1 = getNextChar(s1, ++lookAheadLocation1),
|
||||
lookAhead2 = getNextChar(s2, ++lookAheadLocation2)
|
||||
) {
|
||||
bool is1ADigit = !lookAhead1.isNull() && lookAhead1.isDigit();
|
||||
bool is2ADigit = !lookAhead2.isNull() && lookAhead2.isDigit();
|
||||
if (!is1ADigit && !is2ADigit)
|
||||
break;
|
||||
if (!is1ADigit)
|
||||
return -1;
|
||||
if (!is2ADigit)
|
||||
return 1;
|
||||
if (currentReturnValue == 0) {
|
||||
if (lookAhead1 < lookAhead2) {
|
||||
currentReturnValue = -1;
|
||||
} else if (lookAhead1 > lookAhead2) {
|
||||
currentReturnValue = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (currentReturnValue != 0)
|
||||
return currentReturnValue;
|
||||
}
|
||||
|
||||
if (cs == Qt::CaseInsensitive) {
|
||||
if (!c1.isLower()) c1 = c1.toLower();
|
||||
if (!c2.isLower()) c2 = c2.toLower();
|
||||
}
|
||||
int r = QString::localeAwareCompare(c1, c2);
|
||||
if (r < 0)
|
||||
return -1;
|
||||
if (r > 0)
|
||||
return 1;
|
||||
}
|
||||
// The two strings are the same (02 == 2) so fall back to the normal sort
|
||||
return QString::compare(s1, s2, cs);
|
||||
}
|
||||
bool naturalSortLessThanCS( const QString &left, const QString &right )
|
||||
{
|
||||
return (naturalCompare( left, right, Qt::CaseSensitive ) < 0);
|
||||
}
|
||||
|
||||
bool naturalSortLessThanCI( const QString &left, const QString &right )
|
||||
{
|
||||
return (naturalCompare( left, right, Qt::CaseInsensitive ) < 0);
|
||||
}
|
||||
|
||||
bool naturalSortLessThanCIFileInfo(const QFileInfo & left,const QFileInfo & right)
|
||||
{
|
||||
return naturalSortLessThanCI(left.fileName(),right.fileName());
|
||||
}
|
13
common/qnaturalsorting.h
Normal file
13
common/qnaturalsorting.h
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
#ifndef __QNATURALSORTING_H
|
||||
#define __QNATURALSORTING_H
|
||||
|
||||
#include <QString>
|
||||
#include <QFileInfo>
|
||||
|
||||
bool naturalSortLessThanCS( const QString &left, const QString &right );
|
||||
bool naturalSortLessThanCI( const QString &left, const QString &right );
|
||||
bool naturalSortLessThanCIFileInfo(const QFileInfo & left,const QFileInfo & right);
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user