Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Network
KIO Extras
Commits
7e3fd25b
Commit
7e3fd25b
authored
Jun 05, 2021
by
Méven Car
Browse files
Thumbnails: Refactor, add ThumbCreatorWithMetadata
parent
52861ac4
Changes
2
Hide whitespace changes
Inline
Side-by-side
thumbnail/thumbnail.cpp
View file @
7e3fd25b
...
...
@@ -231,25 +231,27 @@ void ThumbnailProtocol::get(const QUrl &url)
return
;
}
ThumbCreator
*
creator
=
getThumbCreator
(
plugin
);
if
(
!
creator
)
{
error
(
KIO
::
ERR_INTERNAL
,
i18n
(
"Cannot load ThumbCreator %1"
,
plugin
));
ThumbCreatorWithMetadata
*
creator
=
getThumbCreator
(
plugin
);
if
(
!
creator
)
{
return
;
}
ThumbSequenceCreator
*
sequenceCreator
=
dynamic_cast
<
ThumbSequenceCreator
*>
(
creator
);
if
(
sequenceCreator
)
{
sequenceCreator
->
setSequenceIndex
(
sequenceIndex
());
if
(
creator
->
handleSequences
)
{
ThumbSequenceCreator
*
sequenceCreator
=
dynamic_cast
<
ThumbSequenceCreator
*>
(
creator
->
creator
);
if
(
sequenceCreator
)
{
sequenceCreator
->
setSequenceIndex
(
sequenceIndex
());
setMetaData
(
"handlesSequences"
,
QStringLiteral
(
"1"
));
setMetaData
(
"handlesSequences"
,
QStringLiteral
(
"1"
));
}
}
if
(
!
creat
or
->
creat
e
(
info
.
canonicalFilePath
(),
m_width
,
m_height
,
img
))
{
if
(
!
creat
eThumbnail
(
creat
or
,
info
.
canonicalFilePath
(),
m_width
,
m_height
,
img
))
{
error
(
KIO
::
ERR_INTERNAL
,
i18n
(
"Cannot create thumbnail for %1"
,
info
.
canonicalFilePath
()));
return
;
}
if
(
sequenceCreator
)
{
if
(
creator
->
handleSequences
)
{
ThumbSequenceCreator
*
sequenceCreator
=
dynamic_cast
<
ThumbSequenceCreator
*>
(
creator
->
creator
);
// We MUST do this after calling create(), because the create() call itself might change it.
const
float
wp
=
sequenceCreator
->
sequenceIndexWraparoundPoint
();
setMetaData
(
"sequenceIndexWraparoundPoint"
,
QString
().
setNum
(
wp
));
...
...
@@ -620,16 +622,16 @@ QImage ThumbnailProtocol::thumbForDirectory(const QString& directory)
return
img
;
}
ThumbCreator
*
ThumbnailProtocol
::
getThumbCreator
(
const
QString
&
plugin
)
ThumbCreator
WithMetadata
*
ThumbnailProtocol
::
getThumbCreator
(
const
QString
&
plugin
)
{
auto
it
=
m_creators
.
constFind
(
plugin
);
if
(
it
!=
m_creators
.
constEnd
())
{
return
*
it
;
}
ThumbCreator
*
creator
=
nullptr
;
// Don't use KPluginFactory here, this is not a QObject and
// neither is ThumbCreator
ThumbCreator
*
creator
=
nullptr
;
QLibrary
library
(
KPluginLoader
::
findPlugin
((
plugin
)));
if
(
library
.
load
())
{
auto
createFn
=
(
newCreator
)
library
.
resolve
(
"new_creator"
);
...
...
@@ -637,13 +639,31 @@ ThumbCreator* ThumbnailProtocol::getThumbCreator(const QString& plugin)
creator
=
createFn
();
}
}
if
(
!
creator
)
{
ThumbCreatorWithMetadata
*
thumbCreator
=
nullptr
;
if
(
creator
)
{
const
KService
::
List
plugins
=
KServiceTypeTrader
::
self
()
->
query
(
QStringLiteral
(
"ThumbCreator"
),
QStringLiteral
(
"Library == '%1'"
).
arg
(
plugin
));
if
(
plugins
.
size
()
==
0
)
{
qCWarning
(
KIO_THUMBNAIL_LOG
)
<<
"Plugin not found:"
<<
plugin
;
}
else
{
auto
service
=
plugins
.
first
();
QVariant
cacheThumbnails
=
service
->
property
(
"CacheThumbnail"
);
QVariant
handleSequences
=
service
->
property
(
"HandleSequences"
);
thumbCreator
=
new
ThumbCreatorWithMetadata
{
creator
,
cacheThumbnails
.
isValid
()
?
cacheThumbnails
.
toBool
()
:
true
,
handleSequences
.
isValid
()
?
handleSequences
.
toBool
()
:
false
};
}
}
else
{
qCWarning
(
KIO_THUMBNAIL_LOG
)
<<
"Failed to load"
<<
plugin
<<
library
.
errorString
();
}
m_creators
.
insert
(
plugin
,
c
reator
);
m_creators
.
insert
(
plugin
,
thumbC
reator
);
return
c
reator
;
return
thumbC
reator
;
}
void
ThumbnailProtocol
::
ensureDirsCreated
()
...
...
@@ -661,7 +681,7 @@ void ThumbnailProtocol::ensureDirsCreated()
bool
ThumbnailProtocol
::
createSubThumbnail
(
QImage
&
thumbnail
,
const
QString
&
filePath
,
int
segmentWidth
,
int
segmentHeight
)
{
auto
getSubCreator
=
[
&
filePath
,
this
]()
->
ThumbCreator
*
{
auto
getSubCreator
=
[
&
filePath
,
this
]()
->
ThumbCreator
WithMetadata
*
{
const
QMimeDatabase
db
;
const
QString
subPlugin
=
pluginForMimeType
(
db
.
mimeTypeForFile
(
filePath
).
name
());
if
(
subPlugin
.
isEmpty
()
||
!
m_enabledPlugins
.
contains
(
subPlugin
))
{
...
...
@@ -706,53 +726,73 @@ bool ThumbnailProtocol::createSubThumbnail(QImage &thumbnail, const QString &fil
}
// no cached version is available, a new thumbnail must be created
ThumbCreator
*
subCreator
=
getSubCreator
();
if
(
subCreator
&&
subCreator
->
create
(
filePath
,
cacheSize
,
cacheSize
,
thumbnail
))
{
scaleDownImage
(
thumbnail
,
cacheSize
,
cacheSize
);
if
(
thumbnail
.
isNull
())
{
ThumbCreatorWithMetadata
*
subCreator
=
getSubCreator
();
if
(
subCreator
&&
createThumbnail
(
subCreator
,
filePath
,
cacheSize
,
cacheSize
,
thumbnail
))
{
scaleDownImage
(
thumbnail
,
cacheSize
,
cacheSize
);
// The thumbnail has been created successfully. Check if we can store
// the thumbnail to the cache for future access.
// The thumbnail has been created successfully. Check if we can store
// the thumbnail to the cache for future access.
#if KIO_VERSION >= QT_VERSION_CHECK(5, 83, 0)
if
(
metaData
(
"cache"
).
toInt
())
{
if
(
subCreator
->
cacheThumbnail
&&
metaData
(
"cache"
).
toInt
()
&&
!
thumbnail
.
isNull
()
)
{
#else
{
if
(
subCreator
->
cacheThumbnail
&&
!
thumbnail
.
isNull
())
{
#endif
QString
thumbPath
;
const
int
wants
=
std
::
max
(
thumbnail
.
width
(),
thumbnail
.
height
());
for
(
const
auto
&
pool
:
pools
)
{
if
(
pool
.
minSize
<
wants
)
{
continue
;
}
else
if
(
thumbPath
.
isEmpty
())
{
// that's the appropriate path for this thumbnail
thumbPath
=
m_thumbBasePath
+
pool
.
path
;
QString
thumbPath
;
const
int
wants
=
std
::
max
(
thumbnail
.
width
(),
thumbnail
.
height
());
for
(
const
auto
&
pool
:
pools
)
{
if
(
pool
.
minSize
<
wants
)
{
continue
;
}
else
if
(
thumbPath
.
isEmpty
())
{
// that's the appropriate path for this thumbnail
thumbPath
=
m_thumbBasePath
+
pool
.
path
;
}
}
}
// The thumbnail has been created successfully. Store the thumbnail
// to the cache for future access.
QSaveFile
thumbnailfile
(
QDir
(
thumbPath
).
absoluteFilePath
(
thumbNam
e
))
;
if
(
thumbnailfile
.
open
(
QIODevice
::
WriteOnly
|
QIODevice
::
Truncate
))
{
QFileInfo
fi
(
file
Path
);
thumbnail
.
setText
(
QStringLiteral
(
"Thumb::
URI
"
),
QString
::
fromUtf8
(
fileUrl
));
thumbnail
.
setText
(
QStringLiteral
(
"Thumb::
MTim
e"
),
QString
::
number
(
fi
.
lastModified
().
toSecsSinceEpoch
()));
thumbnail
.
setText
(
QStringLiteral
(
"Thumb::Size"
),
QString
::
number
(
fi
.
size
()));
if
(
thumbnail
.
save
(
&
thumbnailfile
,
"png"
))
{
thumbnailfile
.
commit
();
// The thumbnail has been created successfully. Store the thumbnail
// to the cache for future access.
QSaveFile
thumbnailfile
(
QDir
(
thumbPath
).
absoluteFilePath
(
thumbName
));
if
(
thumbnailfile
.
open
(
QIODevice
::
WriteOnly
|
QIODevice
::
Truncat
e
))
{
QFileInfo
fi
(
filePath
);
thumbnail
.
setText
(
QStringLiteral
(
"Thumb::URI"
),
QString
::
fromUtf8
(
file
Url
)
);
thumbnail
.
setText
(
QStringLiteral
(
"Thumb::
MTime
"
),
QString
::
number
(
fi
.
lastModified
().
toSecsSinceEpoch
()
));
thumbnail
.
setText
(
QStringLiteral
(
"Thumb::
Siz
e"
),
QString
::
number
(
fi
.
size
()));
if
(
thumbnail
.
save
(
&
thumbnailfile
,
"png"
))
{
thumbnailfile
.
commit
();
}
}
}
}
}
}
else
{
if
(
thumbnail
.
isNull
())
{
return
false
;
}
}
else
{
ThumbCreator
*
subCreator
=
getSubCreator
();
return
subCreator
&&
subCreator
->
create
(
filePath
,
segmentWidth
,
segmentHeight
,
thumbnail
);
// image requested is too big to be stored in the cache
// create an image on demand
ThumbCreatorWithMetadata
*
subCreator
=
getSubCreator
();
if
(
!
subCreator
||
!
createThumbnail
(
subCreator
,
filePath
,
segmentWidth
,
segmentHeight
,
thumbnail
))
{
return
false
;
}
}
return
true
;
}
bool
ThumbnailProtocol
::
createThumbnail
(
ThumbCreatorWithMetadata
*
thumbCreator
,
const
QString
&
filePath
,
int
width
,
int
height
,
QImage
&
thumbnail
)
{
if
(
thumbCreator
->
creator
->
create
(
filePath
,
width
,
height
,
thumbnail
))
{
// make sure the image is not bigger than the expected size
scaleDownImage
(
thumbnail
,
width
,
height
);
return
true
;
}
return
false
;
}
void
ThumbnailProtocol
::
drawSubThumbnail
(
QPainter
&
p
,
QImage
subThumbnail
,
int
width
,
int
height
,
int
xPos
,
int
yPos
,
int
frameWidth
)
{
scaleDownImage
(
subThumbnail
,
width
,
height
);
...
...
thumbnail/thumbnail.h
View file @
7e3fd25b
...
...
@@ -17,6 +17,15 @@
class
ThumbCreator
;
class
QImage
;
namespace
{
struct
ThumbCreatorWithMetadata
{
ThumbCreator
*
creator
=
nullptr
;
bool
cacheThumbnail
=
true
;
bool
handleSequences
=
false
;
};
};
class
ThumbnailProtocol
:
public
KIO
::
SlaveBase
{
public:
...
...
@@ -26,7 +35,7 @@ public:
void
get
(
const
QUrl
&
url
)
override
;
protected:
ThumbCreator
*
getThumbCreator
(
const
QString
&
plugin
);
ThumbCreator
WithMetadata
*
getThumbCreator
(
const
QString
&
plugin
);
bool
isOpaque
(
const
QImage
&
image
)
const
;
void
drawPictureFrame
(
QPainter
*
painter
,
const
QPoint
&
pos
,
const
QImage
&
image
,
int
frameWidth
,
QSize
imageTargetSize
,
int
rotationAngle
)
const
;
...
...
@@ -52,12 +61,13 @@ private:
int
xPos
,
int
yPos
,
int
frameWidth
);
private:
void
ensureDirsCreated
();
bool
createThumbnail
(
ThumbCreatorWithMetadata
*
subCreator
,
const
QString
&
filePath
,
int
width
,
int
height
,
QImage
&
thumbnail
);
QString
m_mimeType
;
int
m_width
;
int
m_height
;
// Thumbnail creators
QHash
<
QString
,
ThumbCreator
*>
m_creators
;
QHash
<
QString
,
ThumbCreator
WithMetadata
*>
m_creators
;
QStringList
m_enabledPlugins
;
QSet
<
QString
>
m_propagationDirectories
;
QString
m_thumbBasePath
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment