mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
IGN:Working standalone Cover Flow
This commit is contained in:
parent
2b07022ba2
commit
d669477b23
@ -1,7 +1,7 @@
|
|||||||
*_ui.py
|
*_ui.py
|
||||||
moc_*.cpp
|
moc_*.cpp
|
||||||
src/calibre/plugins
|
src/calibre/plugins
|
||||||
src/calibre/gui2/pictureflow/.build/
|
src/calibre/gui2/pictureflow/*.so*
|
||||||
src/calibre/gui2/pictureflow/PyQt/.build/
|
src/calibre/gui2/pictureflow/PyQt/.build/
|
||||||
src/calibre/gui2/pictureflow/Makefile
|
src/calibre/gui2/pictureflow/Makefile
|
||||||
src/calibre.egg-info/
|
src/calibre.egg-info/
|
||||||
|
4
Makefile
4
Makefile
@ -25,7 +25,7 @@ manual:
|
|||||||
|
|
||||||
pictureflow :
|
pictureflow :
|
||||||
mkdir -p src/calibre/plugins && rm -f src/calibre/plugins/*pictureflow* && \
|
mkdir -p src/calibre/plugins && rm -f src/calibre/plugins/*pictureflow* && \
|
||||||
cd src/calibre/gui2/pictureflow && rm *.o && \
|
cd src/calibre/gui2/pictureflow && rm -f *.o *.so* && \
|
||||||
mkdir -p .build && cd .build && rm -f * && \
|
mkdir -p .build && cd .build && rm -f * && \
|
||||||
qmake ../pictureflow-lib.pro && make && \
|
qmake ../pictureflow-lib.pro && make && \
|
||||||
cd ../PyQt && \
|
cd ../PyQt && \
|
||||||
@ -33,7 +33,7 @@ pictureflow :
|
|||||||
cd .build && rm -f * && \
|
cd .build && rm -f * && \
|
||||||
python ../configure.py && make && \
|
python ../configure.py && make && \
|
||||||
cd ../../../../../.. && \
|
cd ../../../../../.. && \
|
||||||
cp src/calibre/gui2/pictureflow/.build/libpictureflow.so.?.?.? src/calibre/gui2/pictureflow/PyQt/.build/pictureflow.so src/calibre/plugins/ && \
|
cp src/calibre/gui2/pictureflow/libpictureflow.so.?.?.? src/calibre/gui2/pictureflow/PyQt/.build/pictureflow.so src/calibre/plugins/ && \
|
||||||
python -c "import os, glob; lp = glob.glob('src/calibre/plugins/libpictureflow.so.*')[0]; os.rename(lp, lp[:-4])"
|
python -c "import os, glob; lp = glob.glob('src/calibre/plugins/libpictureflow.so.*')[0]; os.rename(lp, lp[:-4])"
|
||||||
|
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ _check_symlinks_prescript()
|
|||||||
print 'Building pictureflow'
|
print 'Building pictureflow'
|
||||||
os.chdir('src/calibre/gui2/pictureflow')
|
os.chdir('src/calibre/gui2/pictureflow')
|
||||||
for f in glob.glob('*.o'): os.unlink(f)
|
for f in glob.glob('*.o'): os.unlink(f)
|
||||||
subprocess.check_call([qmake, 'pictureflow-lib.pro'])
|
subprocess.check_call([qmake, 'pictureflow.pro'])
|
||||||
subprocess.check_call(['make'])
|
subprocess.check_call(['make'])
|
||||||
files.append((os.path.abspath(os.path.realpath('libpictureflow.dylib')), 'libpictureflow.dylib'))
|
files.append((os.path.abspath(os.path.realpath('libpictureflow.dylib')), 'libpictureflow.dylib'))
|
||||||
os.chdir('PyQt/.build')
|
os.chdir('PyQt/.build')
|
||||||
|
131
src/calibre/gui2/cover_flow.py
Normal file
131
src/calibre/gui2/cover_flow.py
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||||
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
|
'''
|
||||||
|
Module to implement the Cover Flow feature
|
||||||
|
'''
|
||||||
|
|
||||||
|
import sys, os
|
||||||
|
from collections import deque
|
||||||
|
|
||||||
|
from PyQt4.QtGui import QImage
|
||||||
|
from PyQt4.QtCore import Qt, QSize, QTimer, SIGNAL
|
||||||
|
|
||||||
|
from calibre import pictureflow
|
||||||
|
|
||||||
|
if pictureflow is not None:
|
||||||
|
class FileSystemImages(pictureflow.FlowImages):
|
||||||
|
|
||||||
|
def __init__(self, dirpath):
|
||||||
|
pictureflow.FlowImages.__init__(self)
|
||||||
|
self.images = []
|
||||||
|
self.captions = []
|
||||||
|
for f in os.listdir(dirpath):
|
||||||
|
f = os.path.join(dirpath, f)
|
||||||
|
img = QImage(f)
|
||||||
|
if not img.isNull():
|
||||||
|
self.images.append(img)
|
||||||
|
self.captions.append(os.path.basename(f))
|
||||||
|
|
||||||
|
def count(self):
|
||||||
|
return len(self.images)
|
||||||
|
|
||||||
|
def image(self, index):
|
||||||
|
return self.images[index]
|
||||||
|
|
||||||
|
def caption(self, index):
|
||||||
|
return self.captions[index]
|
||||||
|
|
||||||
|
def currentChanged(self, index):
|
||||||
|
print 'current changed:', index
|
||||||
|
|
||||||
|
class DatabaseImages(pictureflow.FlowImages):
|
||||||
|
|
||||||
|
def __init__(self, model, buffer=20):
|
||||||
|
pictureflow.FlowImages.__init__(self)
|
||||||
|
self.model = model
|
||||||
|
self.default_image = QImage(':/images/book.svg')
|
||||||
|
self.buffer_size = buffer
|
||||||
|
self.timer = QTimer()
|
||||||
|
self.connect(self.timer, SIGNAL('timeout()'), self.load)
|
||||||
|
self.timer.start(50)
|
||||||
|
self.clear()
|
||||||
|
|
||||||
|
def count(self):
|
||||||
|
return self.model.rowCount(None)
|
||||||
|
|
||||||
|
def caption(self, index):
|
||||||
|
return self.model.title(index)
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
self.buffer = {}
|
||||||
|
self.load_queue = deque()
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
if self.load_queue:
|
||||||
|
index = self.load_queue.popleft()
|
||||||
|
if self.buffer.has_key(index):
|
||||||
|
return
|
||||||
|
img = QImage()
|
||||||
|
img.loadFromData(self.model.cover(index))
|
||||||
|
if img.isNull():
|
||||||
|
img = self.default_image
|
||||||
|
self.buffer[index] = img
|
||||||
|
|
||||||
|
def image(self, index):
|
||||||
|
img = self.buffer.get(index)
|
||||||
|
if img is None:
|
||||||
|
img = QImage()
|
||||||
|
img.loadFromData(self.model.cover(index))
|
||||||
|
if img.isNull():
|
||||||
|
img = self.default_image
|
||||||
|
self.buffer[index] = img
|
||||||
|
return img
|
||||||
|
|
||||||
|
def currentChanged(self, index):
|
||||||
|
for key in self.buffer.keys():
|
||||||
|
if abs(key - index) > self.buffer_size:
|
||||||
|
self.buffer.pop(key)
|
||||||
|
for i in range(max(0, index-self.buffer_size), min(self.count(), index+self.buffer_size)):
|
||||||
|
if not self.buffer.has_key(i):
|
||||||
|
self.load_queue.append(i)
|
||||||
|
|
||||||
|
class CoverFlow(pictureflow.PictureFlow):
|
||||||
|
|
||||||
|
def __init__(self, height=300, parent=None):
|
||||||
|
pictureflow.PictureFlow.__init__(self, parent)
|
||||||
|
self.setSlideSize(QSize(int(2/3. * height), height))
|
||||||
|
self.setMinimumSize(QSize(int(2.35*0.67*height), (5/3.)*height))
|
||||||
|
else:
|
||||||
|
CoverFlow = None
|
||||||
|
|
||||||
|
def main(args=sys.argv):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
from PyQt4.QtGui import QApplication, QMainWindow
|
||||||
|
app = QApplication([])
|
||||||
|
w = QMainWindow()
|
||||||
|
cf = CoverFlow()
|
||||||
|
cf.resize(cf.minimumSize())
|
||||||
|
w.resize(cf.minimumSize()+QSize(30, 20))
|
||||||
|
path = sys.argv[1]
|
||||||
|
if path.endswith('.db'):
|
||||||
|
from calibre.library.database import LibraryDatabase
|
||||||
|
from calibre.gui2.library import BooksModel
|
||||||
|
from calibre.gui2 import images_rc
|
||||||
|
bm = BooksModel()
|
||||||
|
bm.set_database(LibraryDatabase(path))
|
||||||
|
bm.sort(1, Qt.AscendingOrder)
|
||||||
|
model = DatabaseImages(bm)
|
||||||
|
else:
|
||||||
|
model = FileSystemImages(sys.argv[1])
|
||||||
|
cf.setImages(model)
|
||||||
|
cf.connect(cf, SIGNAL('currentChanged(int)'), model.currentChanged)
|
||||||
|
w.setCentralWidget(cf)
|
||||||
|
|
||||||
|
w.show()
|
||||||
|
cf.setFocus(Qt.OtherFocusReason)
|
||||||
|
sys.exit(app.exec_())
|
@ -92,7 +92,7 @@ class BooksModel(QAbstractTableModel):
|
|||||||
num -= d
|
num -= d
|
||||||
return ''.join(result)
|
return ''.join(result)
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent=None):
|
||||||
QAbstractTableModel.__init__(self, parent)
|
QAbstractTableModel.__init__(self, parent)
|
||||||
self.db = None
|
self.db = None
|
||||||
self.cols = ['title', 'authors', 'size', 'date', 'rating', 'publisher', 'tags', 'series']
|
self.cols = ['title', 'authors', 'size', 'date', 'rating', 'publisher', 'tags', 'series']
|
||||||
@ -292,6 +292,12 @@ class BooksModel(QAbstractTableModel):
|
|||||||
def id(self, row):
|
def id(self, row):
|
||||||
return self.db.id(row.row())
|
return self.db.id(row.row())
|
||||||
|
|
||||||
|
def title(self, row_number):
|
||||||
|
return self.db.title(row_number)
|
||||||
|
|
||||||
|
def cover(self, row_number):
|
||||||
|
return self.db.cover(row_number)
|
||||||
|
|
||||||
def data(self, index, role):
|
def data(self, index, role):
|
||||||
if role == Qt.DisplayRole or role == Qt.EditRole:
|
if role == Qt.DisplayRole or role == Qt.EditRole:
|
||||||
row, col = index.row(), index.column()
|
row, col = index.row(), index.column()
|
||||||
|
@ -8,7 +8,8 @@ from PyQt4.QtGui import QPixmap, QColor, QPainter, QMenu, QIcon, QMessageBox, \
|
|||||||
QToolButton, QDialog
|
QToolButton, QDialog
|
||||||
from PyQt4.QtSvg import QSvgRenderer
|
from PyQt4.QtSvg import QSvgRenderer
|
||||||
|
|
||||||
from calibre import __version__, __appname__, islinux, sanitize_file_name, launch, Settings
|
from calibre import __version__, __appname__, islinux, sanitize_file_name, launch, \
|
||||||
|
Settings, pictureflowerror, iswindows, isosx
|
||||||
from calibre.ptempfile import PersistentTemporaryFile
|
from calibre.ptempfile import PersistentTemporaryFile
|
||||||
from calibre.ebooks.metadata.meta import get_metadata, get_filename_pat, set_filename_pat
|
from calibre.ebooks.metadata.meta import get_metadata, get_filename_pat, set_filename_pat
|
||||||
from calibre.devices.errors import FreeSpaceError
|
from calibre.devices.errors import FreeSpaceError
|
||||||
@ -18,7 +19,7 @@ from calibre.gui2 import APP_UID, warning_dialog, choose_files, error_dialog, \
|
|||||||
pixmap_to_data, choose_dir, ORG_NAME, \
|
pixmap_to_data, choose_dir, ORG_NAME, \
|
||||||
qstring_to_unicode, set_sidebar_directories, \
|
qstring_to_unicode, set_sidebar_directories, \
|
||||||
SingleApplication, Application
|
SingleApplication, Application
|
||||||
from calibre import iswindows, isosx
|
from calibre.gui2.cover_flow import CoverFlow
|
||||||
from calibre.library.database import LibraryDatabase
|
from calibre.library.database import LibraryDatabase
|
||||||
from calibre.gui2.update import CheckForUpdates
|
from calibre.gui2.update import CheckForUpdates
|
||||||
from calibre.gui2.main_window import MainWindow
|
from calibre.gui2.main_window import MainWindow
|
||||||
|
@ -30,7 +30,7 @@ makefile = pyqtconfig.QtGuiModuleMakefile (
|
|||||||
# Add the library we are wrapping. The name doesn't include any platform
|
# Add the library we are wrapping. The name doesn't include any platform
|
||||||
# specific prefixes or extensions (e.g. the "lib" prefix on UNIX, or the
|
# specific prefixes or extensions (e.g. the "lib" prefix on UNIX, or the
|
||||||
# ".dll" extension on Windows).
|
# ".dll" extension on Windows).
|
||||||
makefile.extra_lib_dirs = ['../../.build', '..\\..\\release', '../../']
|
makefile.extra_lib_dirs = ['../..', '..\\..\\release']
|
||||||
makefile.extra_libs = ['pictureflow0' if 'win' in sys.platform and 'darwin' not in sys.platform else "pictureflow"]
|
makefile.extra_libs = ['pictureflow0' if 'win' in sys.platform and 'darwin' not in sys.platform else "pictureflow"]
|
||||||
makefile.extra_cflags = ['-arch i386', '-arch ppc'] if 'darwin' in sys.platform else []
|
makefile.extra_cflags = ['-arch i386', '-arch ppc'] if 'darwin' in sys.platform else []
|
||||||
makefile.extra_cxxflags = makefile.extra_cflags
|
makefile.extra_cxxflags = makefile.extra_cflags
|
||||||
|
@ -6,48 +6,18 @@
|
|||||||
%Import QtCore/QtCoremod.sip
|
%Import QtCore/QtCoremod.sip
|
||||||
%Import QtGui/QtGuimod.sip
|
%Import QtGui/QtGuimod.sip
|
||||||
|
|
||||||
class AbstractDelayedImage {
|
class FlowImages : QObject {
|
||||||
|
|
||||||
%TypeHeaderCode
|
%TypeHeaderCode
|
||||||
#include "../../pictureflow.h"
|
#include "../../pictureflow.h"
|
||||||
%End
|
%End
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AbstractDelayedImage();
|
virtual int count();
|
||||||
virtual bool load();
|
virtual QImage image(int index);
|
||||||
virtual void unload();
|
virtual QString caption(int index);
|
||||||
virtual void free();
|
|
||||||
virtual bool isLoaded();
|
|
||||||
virtual QImage* image();
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileDelayedImage : AbstractDelayedImage
|
|
||||||
{
|
|
||||||
|
|
||||||
%TypeHeaderCode
|
|
||||||
#include "../../pictureflow.h"
|
|
||||||
%End
|
|
||||||
|
|
||||||
public:
|
|
||||||
FileDelayedImage(QString path);
|
|
||||||
bool load();
|
|
||||||
};
|
|
||||||
|
|
||||||
class PreLoadedImage : AbstractDelayedImage
|
|
||||||
{
|
|
||||||
|
|
||||||
%TypeHeaderCode
|
|
||||||
#include "../../pictureflow.h"
|
|
||||||
%End
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
PreLoadedImage(const QImage& image);
|
|
||||||
PreLoadedImage(const QPixmap& image);
|
|
||||||
bool load();
|
|
||||||
void free();
|
|
||||||
};
|
|
||||||
|
|
||||||
class PictureFlow : QWidget {
|
class PictureFlow : QWidget {
|
||||||
|
|
||||||
@ -58,102 +28,50 @@ class PictureFlow : QWidget {
|
|||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
PictureFlow(QWidget *parent /TransferThis/ = 0, int loadBuffer = 10);
|
PictureFlow(QWidget *parent /TransferThis/ = 0);
|
||||||
|
|
||||||
/*!
|
void setImages(FlowImages *images);
|
||||||
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;
|
QSize slideSize() const;
|
||||||
|
|
||||||
/*!
|
|
||||||
Sets the dimension of each slide (in pixels).
|
|
||||||
*/
|
|
||||||
void setSlideSize(QSize size);
|
void setSlideSize(QSize size);
|
||||||
|
|
||||||
/*!
|
void setZoomFactor(int zoom);
|
||||||
Returns the total number of slides.
|
|
||||||
*/
|
|
||||||
int slideCount() const;
|
|
||||||
|
|
||||||
/*!
|
int zoomFactor() const;
|
||||||
Returns AbstractDelayedImage of specified slide.
|
|
||||||
*/
|
|
||||||
AbstractDelayedImage slide(int index) const;
|
|
||||||
|
|
||||||
/*!
|
void clearCaches();
|
||||||
Returns the index of slide currently shown in the middle of the viewport.
|
|
||||||
*/
|
|
||||||
int centerIndex() const;
|
|
||||||
|
|
||||||
public slots:
|
virtual QImage slide(int index) const;
|
||||||
|
|
||||||
/*!
|
int currentSlide() const;
|
||||||
Adds a new slide.
|
|
||||||
*/
|
|
||||||
void addSlide(AbstractDelayedImage *image);
|
|
||||||
|
|
||||||
/*!
|
public slots:
|
||||||
Sets an image for specified slide. If the slide already exists,
|
|
||||||
it will be replaced.
|
|
||||||
*/
|
|
||||||
void setSlide(int index, AbstractDelayedImage *image);
|
|
||||||
|
|
||||||
/*!
|
void setCurrentSlide(int index);
|
||||||
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();
|
void render();
|
||||||
|
|
||||||
/*!
|
void showPrevious();
|
||||||
Schedules a rendering update. Unlike render(), this function does not cause
|
|
||||||
immediate rendering.
|
void showNext();
|
||||||
*/
|
|
||||||
void triggerRender();
|
void showSlide(int index);
|
||||||
|
|
||||||
|
void dataChanged();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void centerIndexChanged(int index);
|
void itemActivated(int index);
|
||||||
|
void inputReceived();
|
||||||
|
void currentChanged(int index);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *event);
|
void paintEvent(QPaintEvent *event);
|
||||||
void keyPressEvent(QKeyEvent* event);
|
void keyPressEvent(QKeyEvent* event);
|
||||||
|
void mouseMoveEvent(QMouseEvent* event);
|
||||||
void mousePressEvent(QMouseEvent* event);
|
void mousePressEvent(QMouseEvent* event);
|
||||||
|
void mouseReleaseEvent(QMouseEvent* event);
|
||||||
void resizeEvent(QResizeEvent* event);
|
void resizeEvent(QResizeEvent* event);
|
||||||
|
void timerEvent(QTimerEvent* event);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,185 +0,0 @@
|
|||||||
/*
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <qapplication.h>
|
|
||||||
#include <qdir.h>
|
|
||||||
#include <qevent.h>
|
|
||||||
#include <qfileinfo.h>
|
|
||||||
#include <qimage.h>
|
|
||||||
|
|
||||||
#if QT_VERSION >= 0x040000
|
|
||||||
#include <QTime>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "pictureflow.h"
|
|
||||||
|
|
||||||
QStringList findFiles(const QString& path = QString())
|
|
||||||
{
|
|
||||||
QStringList files;
|
|
||||||
|
|
||||||
QDir dir = QDir::current();
|
|
||||||
if(!path.isEmpty())
|
|
||||||
dir = QDir(path);
|
|
||||||
|
|
||||||
dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
|
|
||||||
#if QT_VERSION >= 0x040000
|
|
||||||
QFileInfoList list = dir.entryInfoList();
|
|
||||||
for (int i = 0; i < list.size(); ++i)
|
|
||||||
{
|
|
||||||
QFileInfo fileInfo = list.at(i);
|
|
||||||
files.append(dir.absoluteFilePath(fileInfo.fileName()));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
const QFileInfoList* list = dir.entryInfoList();
|
|
||||||
if(list)
|
|
||||||
{
|
|
||||||
QFileInfoListIterator it( *list );
|
|
||||||
QFileInfo * fi;
|
|
||||||
while( (fi=it.current()) != 0 )
|
|
||||||
{
|
|
||||||
++it;
|
|
||||||
files.append(dir.absFilePath(fi->fileName()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return files;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if QT_VERSION < 0x040000
|
|
||||||
#define modifiers state
|
|
||||||
#define AltModifier AltButton
|
|
||||||
#define setWindowTitle setCaption
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if QT_VERSION < 0x030000
|
|
||||||
#define flush flushX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class Browser: public PictureFlow
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Browser(): PictureFlow()
|
|
||||||
{
|
|
||||||
setWindowTitle("PictureFlow");
|
|
||||||
}
|
|
||||||
|
|
||||||
void keyPressEvent(QKeyEvent* event)
|
|
||||||
{
|
|
||||||
if(event->key() == Qt::Key_Escape || event->key() == Qt::Key_Enter ||
|
|
||||||
event->key() == Qt::Key_Return)
|
|
||||||
{
|
|
||||||
event->accept();
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// checking the speed of rendering
|
|
||||||
if(event->key() == Qt::Key_F10)
|
|
||||||
if(event->modifiers() == Qt::AltModifier)
|
|
||||||
{
|
|
||||||
qDebug("benchmarking.... please wait");
|
|
||||||
const int blit_count = 10;
|
|
||||||
|
|
||||||
QTime stopwatch;
|
|
||||||
stopwatch.start();
|
|
||||||
for(int i = 0; i < blit_count; i++)
|
|
||||||
{
|
|
||||||
render(); repaint(); QApplication::flush(); QApplication::syncX();
|
|
||||||
render(); repaint(); QApplication::flush(); QApplication::syncX();
|
|
||||||
render(); repaint(); QApplication::flush(); QApplication::syncX();
|
|
||||||
render(); repaint(); QApplication::flush(); QApplication::syncX();
|
|
||||||
render(); repaint(); QApplication::flush(); QApplication::syncX();
|
|
||||||
render(); repaint(); QApplication::flush(); QApplication::syncX();
|
|
||||||
render(); repaint(); QApplication::flush(); QApplication::syncX();
|
|
||||||
render(); repaint(); QApplication::flush(); QApplication::syncX();
|
|
||||||
render(); repaint(); QApplication::flush(); QApplication::syncX();
|
|
||||||
render(); repaint(); QApplication::flush(); QApplication::syncX();
|
|
||||||
}
|
|
||||||
QString msg;
|
|
||||||
int elapsed = stopwatch.elapsed();
|
|
||||||
if( elapsed > 0 )
|
|
||||||
msg = QString("FPS: %1").arg( blit_count*10*1000.0/elapsed );
|
|
||||||
else
|
|
||||||
msg = QString("Too fast. Increase blit_count");
|
|
||||||
setWindowTitle( msg );
|
|
||||||
event->accept();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// for debugging only: Alt+F11 cycles the reflection effect
|
|
||||||
if(event->key() == Qt::Key_F11)
|
|
||||||
if(event->modifiers() == Qt::AltModifier)
|
|
||||||
{
|
|
||||||
qDebug("changing reflection effect...");
|
|
||||||
switch(reflectionEffect())
|
|
||||||
{
|
|
||||||
//case NoReflection: setReflectionEffect(PlainReflection); break;
|
|
||||||
case PlainReflection: setReflectionEffect(BlurredReflection); break;
|
|
||||||
case BlurredReflection: setReflectionEffect(PlainReflection); break;
|
|
||||||
default: setReflectionEffect(PlainReflection); break;
|
|
||||||
}
|
|
||||||
event->accept();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PictureFlow::keyPressEvent(event);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int main( int argc, char ** argv )
|
|
||||||
{
|
|
||||||
QApplication* app = new QApplication( argc, argv );
|
|
||||||
Browser* w = new Browser;
|
|
||||||
|
|
||||||
#if defined(_WS_QWS) || defined(Q_WS_QWS)
|
|
||||||
w->showFullScreen();
|
|
||||||
int ww = w->width();
|
|
||||||
int wh = w->height();
|
|
||||||
int dim = (ww > wh) ? wh : ww;
|
|
||||||
dim = dim * 3 / 4;
|
|
||||||
w->setSlideSize(QSize(3*dim/5, dim));
|
|
||||||
#else
|
|
||||||
w->setSlideSize(QSize(3*80, 5*80));
|
|
||||||
w->resize(750, 470);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QStringList files = (argc > 1) ? findFiles(QString(argv[1])) : findFiles();
|
|
||||||
|
|
||||||
for(int i = 0; i < (int)files.count(); i++)
|
|
||||||
w->addSlide(new FileDelayedImage(files[i]));
|
|
||||||
|
|
||||||
w->setCenterIndex(w->slideCount()/2);
|
|
||||||
w->setBackgroundColor(Qt::white);
|
|
||||||
w->show();
|
|
||||||
|
|
||||||
app->connect( app, SIGNAL(lastWindowClosed()), app, SLOT(quit()) );
|
|
||||||
int result = app->exec();
|
|
||||||
|
|
||||||
delete w;
|
|
||||||
delete app;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
TARGET = pictureflow
|
|
||||||
TEMPLATE = lib
|
|
||||||
HEADERS = pictureflow.h
|
|
||||||
SOURCES = pictureflow.cpp
|
|
||||||
VERSION = 0.2.0
|
|
||||||
CONFIG += x86 ppc
|
|
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,39 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
* (C) Copyright 2007 Trolltech ASA
|
||||||
|
* All rights reserved.
|
||||||
|
**
|
||||||
|
* This is version of the Pictureflow animated image show widget modified by Trolltech ASA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the <organization> nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY TROLLTECH ASA ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
****************************************************************************/
|
||||||
/*
|
/*
|
||||||
|
ORIGINAL COPYRIGHT HEADER
|
||||||
PictureFlow - animated image show widget
|
PictureFlow - animated image show widget
|
||||||
http://pictureflow.googlecode.com
|
http://pictureflow.googlecode.com
|
||||||
|
|
||||||
Copyright (C) 2008 Ariya Hidayat (ariya@kde.org)
|
|
||||||
Copyright (C) 2007 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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
@ -27,87 +58,47 @@
|
|||||||
#ifndef PICTUREFLOW_H
|
#ifndef PICTUREFLOW_H
|
||||||
#define PICTUREFLOW_H
|
#define PICTUREFLOW_H
|
||||||
|
|
||||||
#include <QImage>
|
|
||||||
#include <QPixmap>
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
class AbstractDelayedImage
|
class FlowImages : public QObject
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AbstractDelayedImage() : imageptr(0) {};
|
virtual int count();
|
||||||
virtual ~AbstractDelayedImage() { free(); }
|
virtual QImage image(int index);
|
||||||
|
virtual QString caption(int index);
|
||||||
|
|
||||||
virtual bool load();
|
signals:
|
||||||
virtual void unload();
|
void dataChanged();
|
||||||
virtual void free();
|
|
||||||
virtual bool isLoaded();
|
|
||||||
virtual QImage* image();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
QImage *imageptr;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileDelayedImage : public AbstractDelayedImage
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FileDelayedImage(QString path) : file_path(path) { imageptr = 0; }
|
|
||||||
|
|
||||||
bool load();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString file_path;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PreLoadedImage : public AbstractDelayedImage
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PreLoadedImage(const QImage& image);
|
|
||||||
PreLoadedImage(const QPixmap& image);
|
|
||||||
|
|
||||||
bool load();
|
|
||||||
void free();
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
QImage *memory;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class PictureFlowPrivate;
|
class PictureFlowPrivate;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Class PictureFlow implements an image show widget with animation effect
|
Class PictureFlow implements an image show widget with animation effect
|
||||||
like Apple's CoverFlow (in iTunes and iPod). Images are arranged in form
|
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
|
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
|
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
|
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
|
the right with smooth animation effect; until the new slide is finally
|
||||||
placed at the center.
|
placed at the center.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
class PictureFlow : public QWidget
|
class PictureFlow : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)
|
Q_PROPERTY(int currentSlide READ currentSlide WRITE setCurrentSlide)
|
||||||
Q_PROPERTY(QSize slideSize READ slideSize WRITE setSlideSize)
|
Q_PROPERTY(QSize slideSize READ slideSize WRITE setSlideSize)
|
||||||
Q_PROPERTY(int slideCount READ slideCount)
|
Q_PROPERTY(int zoomFactor READ zoomFactor WRITE setZoomFactor)
|
||||||
Q_PROPERTY(int centerIndex READ centerIndex WRITE setCenterIndex)
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum ReflectionEffect
|
|
||||||
{
|
|
||||||
NoReflection,
|
|
||||||
PlainReflection,
|
|
||||||
BlurredReflection
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Creates a new PictureFlow widget.
|
Creates a new PictureFlow widget.
|
||||||
*/
|
*/
|
||||||
PictureFlow(QWidget* parent = 0, int loadBuffer = 10);
|
PictureFlow(QWidget* parent = 0);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Destroys the widget.
|
Destroys the widget.
|
||||||
@ -115,74 +106,60 @@ public:
|
|||||||
~PictureFlow();
|
~PictureFlow();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the background color.
|
Set the images to be displayed by this widget.
|
||||||
*/
|
*/
|
||||||
QColor backgroundColor() const;
|
void setImages(FlowImages *images);
|
||||||
|
|
||||||
/*!
|
|
||||||
Sets the background color. By default it is black.
|
|
||||||
*/
|
|
||||||
void setBackgroundColor(const QColor& c);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the dimension of each slide (in pixels).
|
Returns the dimension of each slide (in pixels).
|
||||||
*/
|
*/
|
||||||
QSize slideSize() const;
|
QSize slideSize() const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Sets the dimension of each slide (in pixels).
|
Sets the dimension of each slide (in pixels).
|
||||||
*/
|
*/
|
||||||
void setSlideSize(QSize size);
|
void setSlideSize(QSize size);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the total number of slides.
|
Sets the zoom factor (in percent).
|
||||||
*/
|
*/
|
||||||
int slideCount() const;
|
void setZoomFactor(int zoom);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns AbstractDelayedImage of specified slide.
|
Returns the zoom factor (in percent).
|
||||||
*/
|
*/
|
||||||
AbstractDelayedImage slide(int index) const;
|
int zoomFactor() const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Clears any caches held to free up memory
|
||||||
|
*/
|
||||||
|
void clearCaches();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns QImage of specified slide.
|
||||||
|
This function will be called only whenever necessary, e.g. the 100th slide
|
||||||
|
will not be retrived when only the first few slides are visible.
|
||||||
|
*/
|
||||||
|
virtual QImage slide(int index) const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the index of slide currently shown in the middle of the viewport.
|
Returns the index of slide currently shown in the middle of the viewport.
|
||||||
*/
|
*/
|
||||||
int centerIndex() const;
|
int currentSlide() 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:
|
public slots:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Adds a new slide.
|
Sets slide to be shown in the middle of the viewport. No animation
|
||||||
*/
|
|
||||||
void addSlide(AbstractDelayedImage *image);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Sets an image for specified slide. If the slide already exists,
|
|
||||||
it will be replaced.
|
|
||||||
*/
|
|
||||||
void setSlide(int index, AbstractDelayedImage *image);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Sets slide to be shown in the middle of the viewport. No animation
|
|
||||||
effect will be produced, unlike using showSlide.
|
effect will be produced, unlike using showSlide.
|
||||||
*/
|
*/
|
||||||
void setCenterIndex(int index);
|
void setCurrentSlide(int index);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Clears all slides.
|
Rerender the widget. Normally this function will be automatically invoked
|
||||||
|
whenever necessary, e.g. during the transition animation.
|
||||||
*/
|
*/
|
||||||
void clear();
|
void render();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Shows previous slide using animation effect.
|
Shows previous slide using animation effect.
|
||||||
@ -198,41 +175,30 @@ public slots:
|
|||||||
Go to specified slide using animation effect.
|
Go to specified slide using animation effect.
|
||||||
*/
|
*/
|
||||||
void showSlide(int index);
|
void showSlide(int index);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Rerender the widget. Normally this function will be automatically invoked
|
Clear all caches and redraw
|
||||||
whenever necessary, e.g. during the transition animation.
|
|
||||||
*/
|
*/
|
||||||
void render();
|
void dataChanged();
|
||||||
|
|
||||||
/*!
|
void emitcurrentChanged(int index);
|
||||||
Load and images that are in the load buffer. This function is automatically
|
|
||||||
caled peridically.
|
|
||||||
*/
|
|
||||||
void load();
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Schedules a rendering update. Unlike render(), this function does not cause
|
|
||||||
immediate rendering.
|
|
||||||
*/
|
|
||||||
void triggerRender();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void centerIndexChanged(int index);
|
void itemActivated(int index);
|
||||||
|
void inputReceived();
|
||||||
|
void currentChanged(int index);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *event);
|
void paintEvent(QPaintEvent *event);
|
||||||
void keyPressEvent(QKeyEvent* event);
|
void keyPressEvent(QKeyEvent* event);
|
||||||
|
void mouseMoveEvent(QMouseEvent* event);
|
||||||
void mousePressEvent(QMouseEvent* event);
|
void mousePressEvent(QMouseEvent* event);
|
||||||
|
void mouseReleaseEvent(QMouseEvent* event);
|
||||||
void resizeEvent(QResizeEvent* event);
|
void resizeEvent(QResizeEvent* event);
|
||||||
|
void timerEvent(QTimerEvent* event);
|
||||||
private slots:
|
|
||||||
void updateAnimation();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PictureFlowPrivate* d;
|
PictureFlowPrivate* d;
|
||||||
void updateBuffer(int old_center, int new_center);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PICTUREFLOW_H
|
#endif // PICTUREFLOW_H
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
TARGET = pictureflow
|
TARGET = pictureflow
|
||||||
TEMPLATE = app
|
TEMPLATE = lib
|
||||||
HEADERS = pictureflow.h
|
HEADERS = pictureflow.h
|
||||||
SOURCES = pictureflow.cpp main.cpp
|
SOURCES = pictureflow.cpp
|
||||||
VERSION = 0.2.0
|
VERSION = 0.2.0
|
||||||
|
CONFIG += x86 ppc
|
||||||
|
@ -545,7 +545,7 @@ class BuildEXE(build_exe):
|
|||||||
shutil.rmtree('release')
|
shutil.rmtree('release')
|
||||||
if os.path.exists('debug'):
|
if os.path.exists('debug'):
|
||||||
shutil.rmtree('debug')
|
shutil.rmtree('debug')
|
||||||
subprocess.check_call(['qmake', 'pictureflow-lib.pro'])
|
subprocess.check_call(['qmake', 'pictureflow.pro'])
|
||||||
subprocess.check_call(['mingw32-make', '-f', 'Makefile.Release'])
|
subprocess.check_call(['mingw32-make', '-f', 'Makefile.Release'])
|
||||||
os.chdir('PyQt')
|
os.chdir('PyQt')
|
||||||
if not os.path.exists('.build'):
|
if not os.path.exists('.build'):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user