...
 
Commits (18)
......@@ -196,6 +196,10 @@ add_subdirectory( ext_vc )
add_subdirectory( ext_gsl )
add_subdirectory( ext_fftw3 )
add_subdirectory( ext_ocio )
add_subdirectory( ext_openjpeg )
if (MSVC)
add_subdirectory( ext_pthreads )
endif (MSVC)
add_subdirectory( ext_fontconfig)
add_subdirectory( ext_freetype)
add_subdirectory( ext_qt )
......
......@@ -153,7 +153,7 @@ Note: on all operating systems the entire procedure is done in a terminal window
cmake --build . --config RelWithDebInfo --target ext_vc
cmake --build . --config RelWithDebInfo --target ext_libraw
cmake --build . --config RelWithDebInfo --target ext_giflib
```
cmake --build . --config RelWithDebInfo --target ext_openjpeg
On Linux (if you want to build your own SIP and PyQt instead of the system one)
```
......
SET(PREFIX_ext_openjpeg "${EXTPREFIX}" )
ExternalProject_Add( ext_openjpeg
DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR}
URL http://files.kde.org/krita/build/dependencies/openjpeg-version.2.1.tar.gz
URL_MD5 3e1c451c087f8462955426da38aa3b3d
INSTALL_DIR ${PREFIX_ext_openjpeg}
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${PREFIX_ext_openjpeg} -DCMAKE_BUILD_TYPE=${GLOBAL_BUILD_TYPE} ${GLOBAL_PROFILE}
UPDATE_COMMAND ""
ALWAYS 0
DEPENDS ext_png ext_tiff ext_lcms2 ext_zlib
)
Enables warnings for overwriting files in case the name comes from the selected filter.
See bug 412651.
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index eb3479b3e..b84441ce2 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -1160,6 +1160,19 @@ Q_AUTOTEST_EXPORT QString qt_tildeExpansion(const QString &path)
}
#endif
+static inline QString selectedNameFilterSuffix(const QFileDialog *dialog)
+{
+ const QString nameFilter = dialog->selectedNameFilter();
+ if (nameFilter.isEmpty())
+ return QString();
+ foreach (const QString &filter, QPlatformFileDialogHelper::cleanFilterList(nameFilter)) {
+
+ if (filter.startsWith(QLatin1String("*.")) && filter.indexOf(QLatin1Char('*'), 2) < 0)
+ return filter.right(filter.size() - 2);
+ }
+ return QString();
+}
+
/**
Returns the text in the line edit which can be one or more file names
*/
@@ -1198,7 +1211,11 @@ QStringList QFileDialogPrivate::typedFiles() const
#endif
}
}
- return addDefaultSuffixToFiles(files);
+
+ QString suffix = q->defaultSuffix();
+ if (suffix.isNull()) // Intended, setting an empty string should suppress the name filter.
+ suffix = selectedNameFilterSuffix(q);
+ return addSuffixToFiles(files, suffix);
}
// Return selected files without defaulting to the root of the file system model
@@ -1209,7 +1226,7 @@ QList<QUrl> QFileDialogPrivate::userSelectedFiles() const
QList<QUrl> files;
if (!usingWidgets())
- return addDefaultSuffixToUrls(selectedFiles_sys());
+ return addSuffixToUrls(selectedFiles_sys(), options->defaultSuffix());
const QModelIndexList selectedRows = qFileDialogUi->listView->selectionModel()->selectedRows();
files.reserve(selectedRows.size());
@@ -1226,16 +1243,16 @@ QList<QUrl> QFileDialogPrivate::userSelectedFiles() const
return files;
}
-QStringList QFileDialogPrivate::addDefaultSuffixToFiles(const QStringList &filesToFix) const
+QStringList QFileDialogPrivate::addSuffixToFiles(const QStringList &filesToFix, const QString &suffix) const
{
QStringList files;
for (int i=0; i<filesToFix.size(); ++i) {
QString name = toInternal(filesToFix.at(i));
QFileInfo info(name);
- // if the filename has no suffix, add the default suffix
- const QString defaultSuffix = options->defaultSuffix();
- if (!defaultSuffix.isEmpty() && !info.isDir() && name.lastIndexOf(QLatin1Char('.')) == -1)
- name += QLatin1Char('.') + defaultSuffix;
+ // if the filename has no suffix, add the desired suffix
+ if (!suffix.isEmpty() && !info.isDir() && name.lastIndexOf(QLatin1Char('.')) == -1) {
+ name += QLatin1Char('.') + suffix;
+ }
if (info.isAbsolute()) {
files.append(name);
} else {
@@ -1252,17 +1269,17 @@ QStringList QFileDialogPrivate::addDefaultSuffixToFiles(const QStringList &files
return files;
}
-QList<QUrl> QFileDialogPrivate::addDefaultSuffixToUrls(const QList<QUrl> &urlsToFix) const
+QList<QUrl> QFileDialogPrivate::addSuffixToUrls(const QList<QUrl> &urlsToFix, const QString suffix) const
{
QList<QUrl> urls;
const int numUrlsToFix = urlsToFix.size();
urls.reserve(numUrlsToFix);
for (int i = 0; i < numUrlsToFix; ++i) {
QUrl url = urlsToFix.at(i);
- // if the filename has no suffix, add the default suffix
- const QString defaultSuffix = options->defaultSuffix();
- if (!defaultSuffix.isEmpty() && !url.path().endsWith(QLatin1Char('/')) && url.path().lastIndexOf(QLatin1Char('.')) == -1)
- url.setPath(url.path() + QLatin1Char('.') + defaultSuffix);
+ // if the filename has no suffix, add the desired suffix
+ if (!suffix.isEmpty() && !url.path().endsWith(QLatin1Char('/')) && url.path().lastIndexOf(QLatin1Char('.')) == -1) {
+ url.setPath(url.path() + QLatin1Char('.') + suffix);
+ }
urls.append(url);
}
return urls;
@@ -1929,6 +1946,12 @@ bool QFileDialog::confirmOverwrite() const
file).
If the first character is a dot ('.'), it is removed.
+
+ If the suffix is not set, the first usable suffix of the selected name
+ filter is appended. This can be suppressed by the property to a non-null,
+ empty string.
+
+ \sa selectedNameFilter(), QString::isNull()
*/
void QFileDialog::setDefaultSuffix(const QString &suffix)
{
diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h
index 2e49696b7..0a029efaa 100644
--- a/src/widgets/dialogs/qfiledialog_p.h
+++ b/src/widgets/dialogs/qfiledialog_p.h
@@ -133,8 +133,8 @@ public:
static QString initialSelection(const QUrl &path);
QStringList typedFiles() const;
QList<QUrl> userSelectedFiles() const;
- QStringList addDefaultSuffixToFiles(const QStringList &filesToFix) const;
- QList<QUrl> addDefaultSuffixToUrls(const QList<QUrl> &urlsToFix) const;
+ QStringList addSuffixToFiles(const QStringList &filesToFix, const QString& suffix) const;
+ QList<QUrl> addSuffixToUrls(const QList<QUrl> &urlsToFix, const QString suffix) const;
bool removeDirectory(const QString &path);
void setLabelTextControl(QFileDialog::DialogLabel label, const QString &text);
inline void updateLookInLabel();
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index 9fccee8c..8c868fce 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -963,11 +963,7 @@ void QFileDialog::setDirectory(const QString &directory)
QDir QFileDialog::directory() const
{
Q_D(const QFileDialog);
- if (d->nativeDialogInUse) {
- QString dir = d->directory_sys().toLocalFile();
- return QDir(dir.isEmpty() ? d->options->initialDirectory().toLocalFile() : dir);
- }
- return d->rootPath();
+ return d->_q_directory();
}
/*!
@@ -1160,13 +1156,38 @@ Q_AUTOTEST_EXPORT QString qt_tildeExpansion(const QString &path)
}
#endif
-static inline QString selectedNameFilterSuffix(const QFileDialog *dialog)
+static inline QString selectedNameFilterSuffix(const QString nameFilter, const QStringList filesList, const QString directory, const QString currentExtension = "")
{
- const QString nameFilter = dialog->selectedNameFilter();
+ QString directoryPath = directory + QDir::separator();
if (nameFilter.isEmpty())
return QString();
- foreach (const QString &filter, QPlatformFileDialogHelper::cleanFilterList(nameFilter)) {
+ // special usecase to avoid jpg/jpeg issues
+ const QString jpeg = "jpeg";
+ const QString jpg = "jpg";
+
+ if (nameFilter.contains(".kra")) {
+ return "kra";
+ }
+
+ if (nameFilter.contains(jpg, Qt::CaseInsensitive) || nameFilter.contains(jpeg, Qt::CaseInsensitive)) {
+
+ foreach (const QString &file, filesList) {
+ if (QFile::exists(directoryPath + file + QString(".") + jpg)) {
+ return QString(jpg);
+ }
+ if (QFile::exists(directoryPath + file + QString(".") + jpeg)) {
+ return QString(jpeg);
+ }
+ }
+
+ if (currentExtension == jpg || currentExtension == jpeg) {
+ return currentExtension;
+ }
+
+ }
+
+ foreach (const QString &filter, QPlatformFileDialogHelper::cleanFilterList(nameFilter)) {
if (filter.startsWith(QLatin1String("*.")) && filter.indexOf(QLatin1Char('*'), 2) < 0)
return filter.right(filter.size() - 2);
}
@@ -1214,7 +1235,7 @@ QStringList QFileDialogPrivate::typedFiles() const
QString suffix = q->defaultSuffix();
if (suffix.isNull()) // Intended, setting an empty string should suppress the name filter.
- suffix = selectedNameFilterSuffix(q);
+ suffix = selectedNameFilterSuffix(q->selectedNameFilter(), files, q->directory().path());
return addSuffixToFiles(files, suffix);
}
@@ -1252,7 +1273,7 @@ QStringList QFileDialogPrivate::addSuffixToFiles(const QStringList &filesToFix,
// if the filename has no suffix, add the desired suffix
if (!suffix.isEmpty() && !info.isDir() && name.lastIndexOf(QLatin1Char('.')) == -1) {
name += QLatin1Char('.') + suffix;
- }
+ }
if (info.isAbsolute()) {
files.append(name);
} else {
@@ -1276,12 +1297,12 @@ QList<QUrl> QFileDialogPrivate::addSuffixToUrls(const QList<QUrl> &urlsToFix, co
urls.reserve(numUrlsToFix);
for (int i = 0; i < numUrlsToFix; ++i) {
QUrl url = urlsToFix.at(i);
- // if the filename has no suffix, add the desired suffix
+ // if the filename has no suffix, add the desired suffix
if (!suffix.isEmpty() && !url.path().endsWith(QLatin1Char('/')) && url.path().lastIndexOf(QLatin1Char('.')) == -1) {
url.setPath(url.path() + QLatin1Char('.') + suffix);
- }
+ }
urls.append(url);
- }
+ }
return urls;
}
@@ -3731,6 +3752,17 @@ void QFileDialogPrivate::_q_goToDirectory(const QString &path)
}
}
+
+QDir QFileDialogPrivate::_q_directory() const
+{
+ if (nativeDialogInUse) {
+ QString dir = directory_sys().toLocalFile();
+ return QDir(dir.isEmpty() ? options->initialDirectory().toLocalFile() : dir);
+ }
+ return rootPath();
+}
+
+
/*!
\internal
@@ -3748,19 +3780,27 @@ void QFileDialogPrivate::_q_useNameFilter(int index)
QString nameFilter = nameFilters.at(index);
QStringList newNameFilters = QPlatformFileDialogHelper::cleanFilterList(nameFilter);
+
if (q_func()->acceptMode() == QFileDialog::AcceptSave) {
QString newNameFilterExtension;
- if (newNameFilters.count() > 0)
- newNameFilterExtension = QFileInfo(newNameFilters.at(0)).suffix();
-
QString fileName = lineEdit()->text();
const QString fileNameExtension = QFileInfo(fileName).suffix();
- if (!fileNameExtension.isEmpty() && !newNameFilterExtension.isEmpty()) {
- const int fileNameExtensionLength = fileNameExtension.count();
- fileName.replace(fileName.count() - fileNameExtensionLength,
- fileNameExtensionLength, newNameFilterExtension);
- qFileDialogUi->listView->clearSelection();
- lineEdit()->setText(fileName);
+
+ if (!fileNameExtension.isEmpty()) {
+
+ QString fileNameWithoutExtension(fileName);
+ int fileNameExtensionLength = fileNameExtension.count();
+ fileNameWithoutExtension.remove(fileName.count() - (fileNameExtensionLength + 1), fileNameExtensionLength + 1); // +1 to count the dot, too
+
+ QStringList filesList = {fileNameWithoutExtension};
+ newNameFilterExtension = selectedNameFilterSuffix(nameFilter, filesList, _q_directory().path(), fileNameExtension);
+
+ if (!newNameFilterExtension.isEmpty()) {
+ fileName.replace(fileName.count() - fileNameExtensionLength,
+ fileNameExtensionLength, newNameFilterExtension);
+ qFileDialogUi->listView->clearSelection();
+ lineEdit()->setText(fileName);
+ }
}
}
diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h
index 0a029efa..3979c6eb 100644
--- a/src/widgets/dialogs/qfiledialog_p.h
+++ b/src/widgets/dialogs/qfiledialog_p.h
@@ -226,6 +226,8 @@ public:
void _q_rowsInserted(const QModelIndex & parent);
void _q_fileRenamed(const QString &path, const QString &oldName, const QString &newName);
+ QDir _q_directory() const;
+
// layout
#if QT_CONFIG(proxymodel)
QAbstractProxyModel *proxyModel;
......@@ -79,6 +79,8 @@ if (WIN32)
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0061-Hack-to-hide-1px-border-with-OpenGL-fullscreen-hack.patch
COMMAND ${PATCH_COMMAND} -p1 -d qttools -i ${CMAKE_CURRENT_SOURCE_DIR}/windeployqt-force-allow-debug-info.patch
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0080-Sync-buffers-of-the-destination-file-after-QFile-cop.patch
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0081-non-native-file-dialog-overwrite-warnings-based-on-filter.patch
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0082-jpeg-extensions-handling-in-non-native-file-dialogs.patch
# COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0031-Compute-logical-DPI-on-a-per-screen-basis.patch
# COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0032-Update-Dpi-and-scale-factor-computation.patch
# COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0033-Move-QT_FONT_DPI-to-cross-platform-code.patch
......@@ -116,6 +118,8 @@ elseif (ANDROID)
PATCH_COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/show-proper-error.patch
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/workaround-null-eglconfig-crash.patch
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/fix-android-menu64bit.patch
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0081-non-native-file-dialog-overwrite-warnings-based-on-filter.patch
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0082-jpeg-extensions-handling-in-non-native-file-dialogs.patch
CONFIGURE_COMMAND <SOURCE_DIR>/configure -prefix ${EXTPREFIX_qt} -opensource -confirm-license -verbose -nomake examples -nomake tests -nomake tools -skip qt3d -skip qtactiveqt -skip qtcanvas3d -skip qtconnectivity -skip qtgraphicaleffects -skip qtlocation -skip qtwayland -skip qtwebchannel -skip qtwebengine -skip qtwebsockets -skip qtwebview -skip qtserialport -skip qtdatavis3d -skip qtvirtualkeyboard -skip qtspeech -skip qtsensors -skip qtgamepad -skip qtscxml -skip qtremoteobjects -skip qtxmlpatterns -skip qtnetworkauth -skip qtcharts -skip qtdatavis3d -skip qtgamepad -skip qtpurchasing -skip qtscxml -skip qtserialbus -skip qtspeech -skip qtvirtualkeyboard -skip qtmultimedia -android-sdk ${ANDROID_SDK_ROOT} -android-ndk ${CMAKE_ANDROID_NDK} -android-arch ${ANDROID_ABI} -xplatform android-clang -android-ndk-platform android-21 -make libs
INSTALL_DIR ${EXTPREFIX_qt}
......@@ -135,6 +139,8 @@ elseif (NOT APPLE)
PATCH_COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0012-Synthesize-Enter-LeaveEvent-for-accepted-QTabletEven.patch
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0013-Poison-Qt-s-headers-with-a-mark-about-presence-of-En.patch
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0070-Fix-QRandomGenerator-initialization-on-AMD-CPUs.patch
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0081-non-native-file-dialog-overwrite-warnings-based-on-filter.patch
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0082-jpeg-extensions-handling-in-non-native-file-dialogs.patch
CMAKE_ARGS -DOPENSSL_LIBS='-L${EXTPREFIX_qt}/lib -lssl -lcrypto'
......@@ -240,6 +246,8 @@ else( APPLE )
set(ext_qt_PATCH_COMMAND ${PATCH_COMMAND}} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0012-Synthesize-Enter-LeaveEvent-for-accepted-QTabletEven.patch
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0013-Poison-Qt-s-headers-with-a-mark-about-presence-of-En.patch
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0070-Fix-QRandomGenerator-initialization-on-AMD-CPUs.patch
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0081-non-native-file-dialog-overwrite-warnings-based-on-filter.patch
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0082-jpeg-extensions-handling-in-non-native-file-dialogs.patch
#COMMAND ${PATCH_COMMAND} -p1 -b -d <SOURCE_DIR>/qtbase/mkspecs/features/mac -i ${CMAKE_CURRENT_SOURCE_DIR}/mac-default.patch
)
......@@ -249,6 +257,8 @@ else( APPLE )
# NOTE: defaults for some untested scenarios like xcrun fails and xcode_version < 8.
# NOTE: that is uncharted territory and (hopefully) a very unlikely scenario...
set(ext_qt_PATCH_COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0012-Synthesize-Enter-LeaveEvent-for-accepted-QTabletEven.patch
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0081-non-native-file-dialog-overwrite-warnings-based-on-filter.patch
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0082-jpeg-extensions-handling-in-non-native-file-dialogs.patch
)
endif()
......
......@@ -645,6 +645,13 @@ set_package_properties(HEIF PROPERTIES
TYPE OPTIONAL
PURPOSE "Required by the Krita HEIF filter")
find_package(OpenJPEG "2.3.0")
set_package_properties(OpenJPEG PROPERTIES
DESCRIPTION "Library for loading and saving jp2000 files."
URL "http://www.openjpeg.org/"
TYPE OPTIONAL
PURPOSE "Required by the Krita JP2000 filter")
set(LIBRAW_MIN_VERSION "0.16")
find_package(LibRaw ${LIBRAW_MIN_VERSION})
set_package_properties(LibRaw PROPERTIES
......
# - Try to find OpenJPEG
# Once done, this will define
#
# OpenJPEG_FOUND - system has OpenJPEG
# OpenJPEG_INCLUDE_DIRS - the OpenJPEG include directories
# OpenJPEG_LIBRARIES - link these to use OpenJPEG
include(LibFindMacros)
# Use pkg-config to get hints about paths
libfind_pkg_check_modules(OpenJPEG_PKGCONF libopenjp2)
# Include dir
find_path(OpenJPEG_INCLUDE_DIR
NAMES openjpeg.h
HINTS ${OpenJPEG_PKGCONF_INCLUDE_DIRS}
)
# Finally the library itself
find_library(OpenJPEG_LIBRARY
NAMES openjp2
HINTS ${OpenJPEG_PKGCONF_LIBRARY_DIRS}
)
# Set the include dir variables and the libraries and let libfind_process do the rest.
# NOTE: Singular variables for this library, plural for libraries this lib depends on.
set(OpenJPEG_PROCESS_INCLUDES OpenJPEG_INCLUDE_DIR)
set(OpenJPEG_PROCESS_LIBS OpenJPEG_LIBRARY)
libfind_process(OpenJPEG)
......@@ -157,9 +157,18 @@ Java_org_krita_android_JNIWrappers_saveState(JNIEnv* /*env*/,
QSettings kritarc(configPath + QStringLiteral("/kritadisplayrc"), QSettings::IniFormat);
kritarc.setValue("canvasState", "OPENGL_SUCCESS");
}
#endif
#ifdef Q_OS_ANDROID
extern "C" JNIEXPORT void JNICALL
Java_org_krita_android_JNIWrappers_exitFullScreen(JNIEnv* /*env*/,
jobject /*obj*/,
jint /*n*/)
{
if (!KisPart::exists()) return;
KisMainWindow *mainWindow = KisPart::instance()->currentMainwindow();
mainWindow->viewFullscreen(false);
}
__attribute__ ((visibility ("default")))
#endif
extern "C" int main(int argc, char **argv)
......
......@@ -375,4 +375,7 @@
<releases>
<release date="2019-05-29" version="4.3.0.0"/>
</releases>
<custom>
<value key="KDE::windows_store">https://www.microsoft.com/store/apps/9n6x57zgrw96</value>
</custom>
</component>
......@@ -286,6 +286,11 @@ void KisMimeDatabase::fillMimeData()
mimeType.description = i18nc("description of a file type", "HEIC/HEIF Image");
mimeType.suffixes = QStringList() << "heic" << "heif";
s_mimeDatabase << mimeType;
mimeType.mimeType = "image/jp2";
mimeType.description = i18nc("description of a file type", "JP2 Image");
mimeType.suffixes = QStringList() << "jp2" << "j2k";
s_mimeDatabase << mimeType;
debugPlugin << "Filled mimedatabase with" << s_mimeDatabase.count() << "special mimetypes";
}
......
......@@ -1990,6 +1990,7 @@ void KisMainWindow::viewFullscreen(bool fullScreen)
} else {
setWindowState(windowState() & ~Qt::WindowFullScreen); // reset
}
d->fullScreenMode->setChecked(isFullScreen());
}
void KisMainWindow::setMaxRecentItems(uint _number)
......
......@@ -316,6 +316,12 @@ public Q_SLOTS:
void slotFileSelected(QString path);
void slotEmptyFilePath();
/**
* Toggle full screen on/off.
*/
void viewFullscreen(bool fullScreen);
private Q_SLOTS:
/**
* Save the list of recent files.
......@@ -383,11 +389,6 @@ private Q_SLOTS:
*/
void slotToolbarToggled(bool toggle);
/**
* Toggle full screen on/off.
*/
void viewFullscreen(bool fullScreen);
/**
* Reload file
*/
......
......@@ -161,7 +161,7 @@ void KoFileDialog::createFileDialog()
d->fileDialog->setOption(QFileDialog::DontUseNativeDialog, group.readEntry("DontUseNativeFileDialog", dontUseNative));
d->fileDialog->setOption(QFileDialog::DontConfirmOverwrite, false);
d->fileDialog->setOption(QFileDialog::HideNameFilterDetails, true);
d->fileDialog->setOption(QFileDialog::HideNameFilterDetails, dontUseNative ? true : false);
#ifdef Q_OS_MACOS
QList<QUrl> urls = d->fileDialog->sidebarUrls();
......
......@@ -21,5 +21,6 @@ package org.krita.android;
class JNIWrappers {
public static native void saveState();
public static native void exitFullScreen();
}
......@@ -19,10 +19,11 @@
package org.krita.android;
import android.os.Bundle;
import android.view.WindowManager;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.WindowManager;
import org.qtproject.qt5.android.bindings.QtActivity;
import org.qtproject.qt5.android.bindings.QtActivity;
public class MainActivity extends QtActivity {
......@@ -49,4 +50,15 @@ public class MainActivity extends QtActivity {
isStartup = false;
}
}
@Override
public boolean onKeyUp(final int keyCode, final KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && getActionBar() != null &&
!getActionBar().isShowing()) {
JNIWrappers.exitFullScreen();
return true;
}
return super.onKeyUp(keyCode, event);
}
}
......@@ -61,6 +61,7 @@ parts:
- libopenexr-dev
- libpng-dev
- libpoppler-qt5-dev
- libopenjpeg-dev
- libtiff5-dev
- libvc-dev
- libopencolorio-dev
......
......@@ -27,6 +27,10 @@ if(Poppler_Qt5_FOUND)
add_subdirectory(pdf)
endif()
if(OpenJPEG_FOUND)
add_subdirectory(jp2)
endif()
if(LIBRAW_FOUND)
add_subdirectory(raw)
endif()
......
add_subdirectory(tests)
include_directories(SYSTEM ${OpenJPEG_INCLUDE_DIR})
set(libkritaconverter_LIB_SRCS
jp2_converter.cc
)
set(kritajp2import_SOURCES
jp2_import.cc
${libkritaconverter_LIB_SRCS}
)
add_library(kritajp2import MODULE ${kritajp2import_SOURCES})
target_link_libraries(kritajp2import kritaui ${OpenJPEG_LIBRARIES} )
install(TARGETS kritajp2import DESTINATION ${KRITA_PLUGIN_INSTALL_DIR})
#set(kritajp2export_SOURCES
# jp2_export.cc
# ${libkritaconverter_LIB_SRCS}
#)
#
#ki18n_wrap_ui(kritajp2export_SOURCES kis_wdg_options_jp2.ui )
#
#add_library(kritajp2export MODULE ${kritajp2export_SOURCES})
#
#target_link_libraries(kritajp2export kritaui ${OPENJPEG_LIBRARIES} )
#install(TARGETS kritajp2export DESTINATION ${KRITA_PLUGIN_INSTALL_DIR})
install( PROGRAMS krita_jp2.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
This diff is collapsed.
/*
* Copyright (c) 2009 Cyrille Berger <cberger@cberger.net>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; version 2.1 of the License.
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef _JP2_CONVERTER_H_
#define _JP2_CONVERTER_H_
#include <stdio.h>
#include <QObject>
#include <QVector>
#include "kis_types.h"
#include "kis_global.h"
#include "kis_annotation.h"
#include <KisImportExportErrorCode.h>
class KisDocument;
struct JP2ConvertOptions {
int rate;
int numberresolution;
};
class JP2Converter: public QObject {
Q_OBJECT
public:
JP2Converter(KisDocument *doc);
virtual ~JP2Converter();
public:
KisImportExportErrorCode buildImage(const QString &filename);
KisImportExportErrorCode buildFile(const QString &filename,
KisPaintLayerSP layer, const JP2ConvertOptions &options);
/**
* Retrieve the constructed image
*/
KisImageWSP image();
void addErrorString(const std::string& str);
void addWarningString(const std::string& str);
void addInfoString(const std::string& str);
private:
KisImportExportErrorCode decode(const QString &filename);
int infile_format(const char *fname);
public Q_SLOTS:
virtual void cancel();
private:
KisImageSP m_image;
KisDocument *m_doc;
bool m_stop;
std::string err;
std::string warn;
};
#endif
/*
* Copyright (c) 2009 Cyrille Berger <cberger@cberger.net>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; version 2.1 of the License.
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "jp2_export.h"
#include <QCheckBox>
#include <QSlider>
#include <QApplication>
#include <KoDialog.h>
#include <kpluginfactory.h>
#include <QFileInfo>
#include <KoColorSpaceConstants.h>
#include <KisFilterChain.h>
#include <KisImportExportManager.h>
#include <kis_properties_configuration.h>
#include <kis_config.h>
#include <KisDocument.h>
#include <kis_image.h>
#include <kis_group_layer.h>
#include <kis_paint_layer.h>
#include <kis_paint_device.h>
#include "jp2_converter.h"
#include "ui_kis_wdg_options_jp2.h"
class KisExternalLayer;
K_PLUGIN_FACTORY_WITH_JSON(ExportFactory, "krita_jp2_export.json", registerPlugin<jp2Export>();)
jp2Export::jp2Export(QObject *parent, const QVariantList &) : KisImportExportFilter(parent)
{
}
jp2Export::~jp2Export()
{
}
KisImportExportFilter::ConversionStatus jp2Export::convert(const QByteArray& from, const QByteArray& to)
{
dbgFile << "JP2 export! From:" << from << ", To:" << to << "";
if (from != "application/x-krita")
return KisImportExportFilter::NotImplemented;
KisDocument *input = inputDocument();
QString filename = outputFile();
if (!input)
return KisImportExportFilter::NoDocumentCreated;
KisImageWSP image = input->image();
Q_CHECK_PTR(image);
if (filename.isEmpty()) return KisImportExportFilter::FileNotFound;
KoDialog* kdb = new KoDialog(0);
kdb->setWindowTitle(i18n("JPEG 2000 Export Options"));
kdb->setButtons(KoDialog::Ok | KoDialog::Cancel);
Ui::WdgOptionsJP2 optionsJP2;
QWidget* wdg = new QWidget(kdb);
optionsJP2.setupUi(wdg);
QString filterConfig = KisConfig().exportConfiguration("JP2");
KisPropertiesConfiguration cfg;
cfg.fromXML(filterConfig);
optionsJP2.numberResolutions->setValue(cfg.getInt("number_resolutions", 6));
optionsJP2.qualityLevel->setValue(cfg.getInt("quality", 100));
kdb->setMainWidget(wdg);
QApplication::restoreOverrideCursor();
if (!getBatchMode()) {
if (kdb->exec() == QDialog::Rejected) {
return KisImportExportFilter::UserCancelled;
}
}
JP2ConvertOptions options;
options.numberresolution = optionsJP2.numberResolutions->value();
cfg.setProperty("number_resolutions", options.numberresolution);
options.rate = optionsJP2.qualityLevel->value();
cfg.setProperty("quality", options.rate);
KisConfig().setExportConfiguration("JP2", cfg);
// the image must be locked at the higher levels
KIS_SAFE_ASSERT_RECOVER_NOOP(input->image()->locked());
jp2Converter kpc(input);
KisPaintDeviceSP pd = new KisPaintDevice(*image->projection());
KisPaintLayerSP l = new KisPaintLayer(image, "projection", OPACITY_OPAQUE_U8, pd);
KisImageBuilder_Result res;
if ((res = kpc.buildFile(filename, l, options)) == KisImageBuilder_RESULT_OK) {
dbgFile << "success !";
return KisImportExportFilter::OK;
}
dbgFile << " Result =" << res;
return KisImportExportFilter::InternalError;
}
#include <jp2_export.moc>
/*
* Copyright (c) 2009 Cyrille Berger <cberger@cberger.net>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; version 2.1 of the License.
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef _JP2_EXPORT_H_
#define _JP2_EXPORT_H_
#include <QVariant>
#include <KisImportExportFilter.h>
class jp2Export : public KisImportExportFilter
{
Q_OBJECT
public:
jp2Export(QObject *parent, const QVariantList &);
virtual ~jp2Export();
public:
virtual KisImportExportFilter::ConversionStatus convert(const QByteArray& from, const QByteArray& to);
};
#endif
/*
* Copyright (c) 2009 Cyrille Berger <cberger@cberger.net>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; version 2.1 of the License.
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "jp2_import.h"
#include <kpluginfactory.h>
#include <QFileInfo>
#include <KisDocument.h>
#include <kis_image.h>
#include "jp2_converter.h"
K_PLUGIN_FACTORY_WITH_JSON(ImportFactory, "krita_jp2_import.json", registerPlugin<jp2Import>();)
jp2Import::jp2Import(QObject *parent, const QVariantList &) : KisImportExportFilter(parent)
{
}
jp2Import::~jp2Import()
{
}
KisImportExportErrorCode jp2Import::convert(KisDocument *document, QIODevice */*io*/, KisPropertiesConfigurationSP /*configuration*/)
{
JP2Converter converter(document);
KisImportExportErrorCode result = converter.buildImage(filename());
if (result.isOk()) {
document->setCurrentImage(converter.image());
}
return result;
}
#include <jp2_import.moc>
/*
* Copyright (c) 2009 Cyrille Berger <cberger@cberger.net>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; version 2.1 of the License.
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef JP2_IMPORT_H_
#define JP2_IMPORT_H_
#include <QVariant>
#include <KisImportExportFilter.h>
class jp2Import : public KisImportExportFilter
{
Q_OBJECT
public:
jp2Import(QObject *parent, const QVariantList &);
virtual ~jp2Import();
public:
KisImportExportErrorCode convert(KisDocument *document, QIODevice *io, KisPropertiesConfigurationSP configuration = 0) override;
};
#endif
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WdgOptionsJP2</class>
<widget class="QWidget" name="WdgOptionsJP2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Compression</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="qualityLevel">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;These settings determine how much information is lost during compression. Low: small files, bad quality. High: big files, good quality.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>10</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="intQuality">
<property name="value">
<number>100</number>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Number of resolutions:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="numberResolutions">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>20</number>
</property>
<property name="value">
<number>6</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>qualityLevel</sender>
<signal>valueChanged(int)</signal>
<receiver>intQuality</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>322</x>
<y>22</y>
</hint>
<hint type="destinationlabel">
<x>367</x>
<y>19</y>
</hint>
</hints>
</connection>
<connection>
<sender>intQuality</sender>
<signal>valueChanged(int)</signal>
<receiver>qualityLevel</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>373</x>
<y>21</y>
</hint>
<hint type="destinationlabel">
<x>328</x>
<y>18</y>
</hint>
</hints>
</connection>
</connections>
</ui>
[Desktop Entry]
Categories=Qt;KDE;Office;Graphics;
GenericName=Application for Drawing and Handling of Images
GenericName[ar]=تطبيق لرسم الصور والتعامل معها
GenericName[bg]=Приложение за рисуване и обработка на изображения
GenericName[bs]=Aplikacija za crtanje i upravljanje slikom
GenericName[ca]=Aplicació per a dibuix i modificació d'imatges
GenericName[ca@valencia]=Aplicació per a dibuix i modificació d'imatges
GenericName[da]=Tegne- og billedbehandlingsprogram
GenericName[de]=Programm zum Zeichnen und Bearbeiten von Bildern
GenericName[el]=Εφαρμογή για επεξεργασία και χειρισμό εικόνων
GenericName[en_GB]=Application for Drawing and Handling of Images
GenericName[eo]=Aplikaĵo por Desegnado kaj Mastrumado de Bildoj
GenericName[es]=Aplicación para dibujo y manipulación de imágenes
GenericName[et]=Joonistamise ja pilditöötluse rakendus
GenericName[eu]=Irudiak marrazteko eta manipulatzeko aplikazioa
GenericName[fa]=کاربرد برای ترسیم و به کار بردن تصاویر
GenericName[fi]=Ohjelma kuvien piirtämiseen ja käsittelyyn
GenericName[fr]=Application pour dessiner et manipuler des images
GenericName[fy]=Aplikaasje om ôfbyldings mei te tekenjen en te bewurkjen
GenericName[ga]=Feidhmchlár le haghaidh Líníochta agus Láimhseála Íomhánna
GenericName[gl]=Aplicación de debuxo e edición de imaxes
GenericName[he]=יישום לצביעה וניהול תמונות
GenericName[hi]=छवियों को ड्रा करने तथा उन्हें प्रबन्धित करने का अनुप्रयोग
GenericName[hne]=फोटू मन ल ड्रा करे अउ ओ मन ल प्रबन्धित करे के अनुपरयोग
GenericName[hu]=Rajzoló és képkezelő
GenericName[is]=Teikni og myndvinnsluforrit
GenericName[it]=Applicazione di disegno e gestione di immagini
GenericName[ja]=描画と画像操作のためのアプリケーション
GenericName[kk]=Кескінді салу және өңдеу бағдарламасы
GenericName[ko]=그림 그리기 및 처리 프로그램
GenericName[lv]=Programma zīmēšanai un attēlu apstrādei
GenericName[nb]=Program for tegning og bildehåndtering
GenericName[nds]=Programm för't Teken un Bildhanteren
GenericName[ne]=रेखाचित्र बनाउन र छविको ह्यान्डल गर्नका लागि अनुप्रयोग
GenericName[nl]=Toepassing om afbeeldingen te tekenen en te bewerken
GenericName[nn]=Program for teikning og handsaming av bilete
GenericName[pl]=Program do rysowania i obróbki obrazów
GenericName[pt]=Aplicação de Desenho e Manipulação de Imagens
GenericName[pt_BR]=Aplicativo de desenho e manipulação de imagens
GenericName[ru]=Приложение для рисования и редактирования изображений
GenericName[sk]=Aplikácia na kresnenie a manilupáciu s obrázkami
GenericName[sl]=Program za risanje in rokovanje s slikami
GenericName[sv]=Program för att rita och hantera bilder
GenericName[ta]=பிம்பங்களை கையாளுதல் மற்றும் வரைதலுக்கான பயன்னாடு
GenericName[tr]=Çizim ve Resim İşleme Uygulaması
GenericName[uk]=Програма для малювання і обробки зображень
GenericName[uz]=Rasm chizish dasturi
GenericName[uz@cyrillic]=Расм чизиш дастури
GenericName[wa]=Programe po dessiner et apougnî des imådjes
GenericName[x-test]=xxApplication for Drawing and Handling of Imagesxx
GenericName[zh_CN]=用于绘制和处理图像的应用程序
GenericName[zh_TW]=繪圖與影像處理的應用程式
Name=Krita
Name[af]=Krita
Name[ar]=كريتا
Name[bg]=Krita
Name[br]=Krita
Name[bs]=Krita
Name[ca]=Krita
Name[ca@valencia]=Krita
Name[cs]=Krita
Name[cy]=Krita
Name[da]=Krita
Name[de]=Krita
Name[el]=Krita
Name[en_GB]=Krita
Name[eo]=Krita
Name[es]=Krita
Name[et]=Krita
Name[eu]=Krita
Name[fi]=Krita
Name[fr]=Krita
Name[fy]=Krita
Name[ga]=Krita
Name[gl]=Krita
Name[he]=Krita
Name[hi]=केरिता
Name[hne]=केरिता
Name[hr]=Krita
Name[hu]=Krita
Name[ia]=Krita
Name[is]=Krita
Name[it]=Krita
Name[ja]=Krita
Name[kk]=Krita
Name[ko]=Krita
Name[lt]=Krita
Name[lv]=Krita
Name[mr]=क्रिटा
Name[ms]=Krita
Name[nb]=Krita
Name[nds]=Krita
Name[ne]=क्रिता
Name[nl]=Krita
Name[nn]=Krita
Name[pl]=Krita
Name[pt]=Krita
Name[pt_BR]=Krita
Name[ro]=Krita
Name[ru]=Krita
Name[se]=Krita
Name[sk]=Krita
Name[sl]=Krita
Name[sv]=Krita
Name[ta]=கிரிட்டா
Name[tg]=Krita
Name[tr]=Krita
Name[ug]=Krita
Name[uk]=Krita
Name[uz]=Krita
Name[uz@cyrillic]=Krita
Name[wa]=Krita
Name[xh]=Krita
Name[x-test]=xxKritaxx
Name[zh_CN]=Krita
Name[zh_TW]=Krita
Exec=krita %u
MimeType=image/jp2;
Type=Application
Icon=krita
StartupNotify=true
NoDisplay=true
{
"Id": "Krita jpeg2000 Export Filter",
"NoDisplay": "true",
"Type": "Service",
"X-KDE-Export": "image/jp2",
"X-KDE-Library": "kritajp2export",
"X-KDE-ServiceTypes": [
"Krita/FileFilter"
],
"X-KDE-Weight": "1",
"X-KDE-Extensions" : "jp2"
}
{
"Id": "Krita jpeg2000 Import Filter",
"NoDisplay": "true",
"Type": "Service",
"X-KDE-Import": "image/jp2,image/j2k",
"X-KDE-Library": "kritajp2import",
"X-KDE-ServiceTypes": [
"Krita/FileFilter"
],
"X-KDE-Weight": "1",
"X-KDE-Extensions" : "jp2,j2k"
}
set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} )
include_directories( ${CMAKE_SOURCE_DIR}/sdk/tests )
include(KritaAddBrokenUnitTest)
macro_add_unittest_definitions()
ecm_add_test(KisJP2Test.cpp
TEST_NAME KisJP2Test
LINK_LIBRARIES kritaui Qt5::Test
NAME_PREFIX "plugins-impex-")
/*
* Copyright (C) 2019 Agata Cacko <cacko.azh@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <KisJP2Test.h>
#include <QTest>
#include <QCoreApplication>
#include "filestest.h"
#ifndef FILES_DATA_DIR
#error "FILES_DATA_DIR not set. A directory with the data used for testing the importing of files in krita"
#endif
const QString JP2Mimetype = "image/jp2";
void KisJP2Test::testImportFromWriteonly()
{
TestUtil::testImportFromWriteonly(QString(FILES_DATA_DIR), JP2Mimetype);
}
void KisJP2Test::testExportToReadonly()
{
TestUtil::testExportToReadonly(QString(FILES_DATA_DIR), JP2Mimetype);
}
void KisJP2Test::testImportIncorrectFormat()
{
TestUtil::testImportIncorrectFormat(QString(FILES_DATA_DIR), JP2Mimetype);
}
KISTEST_MAIN(KisJP2Test)
/*
* Copyright (C) 2019 Agata Cacko <cacko.azh@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _KIS_JP2_TEST_H_
#define _KIS_JP2_TEST_H_
#include <QtTest>
class KisJP2Test : public QObject
{
Q_OBJECT
private Q_SLOTS:
void testImportFromWriteonly();
void testExportToReadonly();
void testImportIncorrectFormat();
};
#endif // _KIS_JP2_TEST_H_
......@@ -4,6 +4,7 @@ set(kritaqimageioexport_SOURCES
kis_qimageio_export.cpp
)
ki18n_wrap_ui(kritaqimageioexport_SOURCES kis_wdg_options_qimageio.ui)
ki18n_wrap_ui(kritaqimageioexport_SOURCES )
add_library(kritaqimageioexport MODULE ${kritaqimageioexport_SOURCES})
......@@ -16,7 +17,6 @@ set(kritaqimageioimport_SOURCES
kis_qimageio_import.cpp
)
ki18n_wrap_ui(kritaqimageioimport_SOURCES kis_wdg_options_qimageio.ui)
add_library(kritaqimageioimport MODULE ${kritaqimageioimport_SOURCES})
......
......@@ -101,6 +101,12 @@ KisBrushOp::KisBrushOp(const KisPaintOpSettingsSP settings, KisPainter *painter,
m_rotationOption.applyFanCornersInfo(this);
m_precisionOption.setHasImprecisePositionOptions(
m_precisionOption.hasImprecisePositionOptions() |
m_scatterOption.isChecked() |
m_rotationOption.isChecked() |
m_airbrushOption.enabled);
KisBrushSP baseBrush = m_brush;
auto resourcesFactory =
[baseBrush, settings, painter] () {
......
......@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>504</width>
<width>545</width>
<height>270</height>
</rect>
</property>
......@@ -89,53 +89,6 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="toolTip">
<string>Use to set the size from which the Automatic Precision Setting should begin. The Precision will remain 5 before this value.</string>
</property>
<property name="text">
<string>Starting Brush Size:</string>
</property>
</widget>
</item>
<item>
<widget class="KisDoubleParseSpinBox" name="sizeToStartFromSpinBox">
<property name="suffix">
<string> px</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>This determines every interval after which the precision should change. For example: if the delta value is set to be 15.00, after every 15 pts change in the size of brush, the precision will change.</string>
</property>
<property name="text">
<string>Delta :</string>
</property>
</widget>
</item>
<item>
<widget class="KisDoubleParseSpinBox" name="deltaValueSpinBox">
<property name="suffix">
<string> px</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblPrecisionValue">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblPrecision">
<property name="sizePolicy">
......@@ -167,11 +120,6 @@
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KisDoubleParseSpinBox</class>
<extends>QDoubleSpinBox</extends>
<header>kis_double_parse_spin_box.h</header>
</customwidget>
<customwidget>
<class>KisSliderSpinBox</class>
<extends>QWidget</extends>
......
......@@ -105,6 +105,10 @@ KisBrushBasedPaintOp::KisBrushBasedPaintOp(const KisPropertiesConfigurationSP se
m_textureProperties.fillProperties(settings);
m_dabCache->setTexturePostprocessing(&m_textureProperties);
m_precisionOption.setHasImprecisePositionOptions(
m_precisionOption.hasImprecisePositionOptions() |
m_mirrorOption.isChecked() | m_textureProperties.m_enabled);
}
KisBrushBasedPaintOp::~KisBrushBasedPaintOp()
......
......@@ -53,17 +53,14 @@ KisBrushSelectionWidget::KisBrushSelectionWidget(QWidget * parent)
m_layout = new QGridLayout(uiWdgBrushChooser.settingsFrame);
m_autoBrushWidget = new KisAutoBrushWidget(this, "autobrush");
connect(m_autoBrushWidget, SIGNAL(sigBrushChanged()), SIGNAL(sigBrushChanged()));
connect(m_autoBrushWidget->inputRadius, SIGNAL(valueChanged(qreal)), SLOT(refreshAutoPrecision(qreal)));
addChooser(i18n("Auto"), m_autoBrushWidget, AUTOBRUSH, KoGroupButton::GroupLeft);
m_predefinedBrushWidget = new KisPredefinedBrushChooser(this);
connect(m_predefinedBrushWidget, SIGNAL(sigBrushChanged()), SIGNAL(sigBrushChanged()));
connect(m_predefinedBrushWidget->brushSizeSpinBox, SIGNAL(valueChanged(qreal)), SLOT(refreshAutoPrecision(qreal)));
addChooser(i18n("Predefined"), m_predefinedBrushWidget, PREDEFINEDBRUSH, KoGroupButton::GroupCenter);
m_textBrushWidget = new KisTextBrushChooser(this, "textbrush", i18n("Text"));
connect(m_textBrushWidget, SIGNAL(sigBrushChanged()), SIGNAL(sigBrushChanged()));
connect(m_textBrushWidget, SIGNAL(fontSizeChanged(qreal)), SLOT(refreshAutoPrecision(qreal)));
addChooser(i18n("Text"), m_textBrushWidget, TEXTBRUSH, KoGroupButton::GroupRight);
connect(m_buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(buttonClicked(int)));
......@@ -79,17 +76,8 @@ KisBrushSelectionWidget::KisBrushSelectionWidget(QWidget * parent)
uiWdgBrushChooser.sliderPrecision->setPageStep(1);
connect(uiWdgBrushChooser.sliderPrecision, SIGNAL(valueChanged(int)), SLOT(precisionChanged(int)));
connect(uiWdgBrushChooser.autoPrecisionCheckBox, SIGNAL(stateChanged(int)), SLOT(setAutoPrecisionEnabled(int)));
connect(uiWdgBrushChooser.deltaValueSpinBox, SIGNAL(valueChanged(double)), SLOT(setDeltaValue(double)));
connect(uiWdgBrushChooser.sizeToStartFromSpinBox, SIGNAL(valueChanged(double)), SLOT(setSizeToStartFrom(double)));
uiWdgBrushChooser.sliderPrecision->setValue(4);
uiWdgBrushChooser.sliderPrecision->setValue(5);
setPrecisionEnabled(false);
uiWdgBrushChooser.label->setVisible(false);
uiWdgBrushChooser.label_2->setVisible(false);
uiWdgBrushChooser.deltaValueSpinBox->setVisible(false);
uiWdgBrushChooser.sizeToStartFromSpinBox->setVisible(false);
uiWdgBrushChooser.lblPrecisionValue->setVisible(false);
uiWdgBrushChooser.label ->setToolTip(i18n("Use to set the size from which the Automatic Precision Setting should begin. \nThe Precision will remain 5 before this value."));
uiWdgBrushChooser.label_2 ->setToolTip(i18n("Use to set the interval at which the Automatic Precision will change. \nThe Precision will decrease as brush size increases."));
m_presetIsValid = true;
}
......@@ -124,24 +112,6 @@ KisBrushSP KisBrushSelectionWidget::brush() const
}
void KisBrushSelectionWidget::updatePrecisionByType(int id)
{
switch (id) {
case AUTOBRUSH:
refreshAutoPrecision(m_autoBrushWidget->inputRadius->value());
break;
case PREDEFINEDBRUSH:
refreshAutoPrecision(m_predefinedBrushWidget->brushSizeSpinBox->value());
break;
case TEXTBRUSH:
refreshAutoPrecision(m_textBrushWidget->fontInfo().pixelSize());
break;
default:
;
}
}
void KisBrushSelectionWidget::setAutoBrush(bool on)
{
m_buttonGroup->button(AUTOBRUSH)->setVisible(on);
......@@ -198,7 +168,6 @@ void KisBrushSelectionWidget::setCurrentBrush(KisBrushSP brush)
void KisBrushSelectionWidget::buttonClicked(int id)
{
setCurrentWidget(m_chooserMap[id]);
updatePrecisionByType(id);
emit sigBrushChanged();
}
......@@ -264,12 +233,11 @@ void KisBrushSelectionWidget::readOptionSetting(const KisPropertiesConfiguration
m_precisionOption.readOptionSetting(setting);
uiWdgBrushChooser.sliderPrecision->setValue(m_precisionOption.precisionLevel());
uiWdgBrushChooser.autoPrecisionCheckBox->setChecked(m_precisionOption.autoPrecisionEnabled());
uiWdgBrushChooser.deltaValueSpinBox ->setValue(m_precisionOption.deltaValue());
uiWdgBrushChooser.sizeToStartFromSpinBox ->setValue(m_precisionOption.sizeToStartFrom());
}
void KisBrushSelectionWidget::setPrecisionEnabled(bool value)
{
uiWdgBrushChooser.autoPrecisionCheckBox->setVisible(value);
uiWdgBrushChooser.sliderPrecision->setVisible(value);
uiWdgBrushChooser.lblPrecision->setVisible(value);
}
......@@ -343,47 +311,15 @@ void KisBrushSelectionWidget::setAutoPrecisionEnabled(int value)
{
m_precisionOption.setAutoPrecisionEnabled(value);
if (m_precisionOption.autoPrecisionEnabled()) {
m_precisionOption.setAutoPrecision(brush()->userEffectiveSize());
setPrecisionEnabled(false);
precisionChanged(m_precisionOption.precisionLevel());
uiWdgBrushChooser.label->setVisible(true);
uiWdgBrushChooser.label_2->setVisible(true);
uiWdgBrushChooser.deltaValueSpinBox->setVisible(true);
uiWdgBrushChooser.sizeToStartFromSpinBox->setVisible(true);