Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 105fba814d | |||
| 555e6c11c8 | |||
| 748f5fac03 | |||
| adc7d07b75 | |||
| ba450ee554 | |||
| cc69b7bc2d | |||
| 42b619641a | |||
| 9af4fa1b99 | |||
| cbc6775756 | |||
| cee6979ece | |||
| 903ec65d52 | |||
| 95e4774507 | |||
| 2410c51d5d | |||
| 17bca74362 | |||
| c70123cf7b | |||
| 12c6385f77 | |||
| 39f3ec7d30 | |||
| 8b968ddcb1 | |||
| da1843e48c | |||
| e0d473c8c8 | |||
| 92f9920f24 | |||
| f68a9c4d7c | |||
| 027a38cb42 | |||
| 47d5a9fc96 | |||
| 061bb3892e |
Vendored
+43
@@ -0,0 +1,43 @@
|
|||||||
|
*******************************************************************************
|
||||||
|
PixInsight Class Library License Version 1.0
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
Copyright (c) 2003-2021, Pleiades Astrophoto S.L. All Rights Reserved.
|
||||||
|
|
||||||
|
Redistribution and use in both source and binary forms, with or without
|
||||||
|
modification, is permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. All redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. All 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.
|
||||||
|
|
||||||
|
3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names of
|
||||||
|
their contributors, may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission. For written
|
||||||
|
permission, please contact info@pixinsight.com.
|
||||||
|
|
||||||
|
4. All products derived from this software, in any form whatsoever, must
|
||||||
|
reproduce the following acknowledgment in the end-user documentation and/or
|
||||||
|
other materials provided with the product:
|
||||||
|
|
||||||
|
"This product is based on software from the PixInsight project, developed by
|
||||||
|
Pleiades Astrophoto and its contributors (https://pixinsight.com/)."
|
||||||
|
|
||||||
|
Alternatively, if that is where third-party acknowledgments normally appear,
|
||||||
|
this acknowledgment must be reproduced in the product itself.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS "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 PLEIADES ASTROPHOTO OR ITS CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS INTERRUPTION; PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE, DATA OR PROFITS) 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.
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
+25
-2
@@ -21,6 +21,7 @@ find_library(FITS_LIB cfitsio REQUIRED)
|
|||||||
find_library(RAW_LIB NAMES raw_r REQUIRED)
|
find_library(RAW_LIB NAMES raw_r REQUIRED)
|
||||||
|
|
||||||
set(TENMON_SRC
|
set(TENMON_SRC
|
||||||
|
about.cpp
|
||||||
database.cpp
|
database.cpp
|
||||||
databaseview.cpp
|
databaseview.cpp
|
||||||
filesystemwidget.cpp
|
filesystemwidget.cpp
|
||||||
@@ -31,6 +32,7 @@ set(TENMON_SRC
|
|||||||
loadrunable.cpp
|
loadrunable.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
mainwindow.cpp
|
mainwindow.cpp
|
||||||
|
markedfiles.cpp
|
||||||
rawimage.cpp
|
rawimage.cpp
|
||||||
starfit.cpp
|
starfit.cpp
|
||||||
stfslider.cpp
|
stfslider.cpp
|
||||||
@@ -48,7 +50,7 @@ endif()
|
|||||||
add_executable(tenmon WIN32 ${TENMON_SRC})
|
add_executable(tenmon WIN32 ${TENMON_SRC})
|
||||||
|
|
||||||
find_path(FITS_INCLUDE fitsio2.h PATH_SUFFIXES cfitsio REQUIRED)
|
find_path(FITS_INCLUDE fitsio2.h PATH_SUFFIXES cfitsio REQUIRED)
|
||||||
target_include_directories(tenmon PRIVATE ${OpenCV_INCLUDE_DIRS} ${FITS_INCLUDE} 3rdparty/include)
|
target_include_directories(tenmon PRIVATE ${OpenCV_INCLUDE_DIRS} ${FITS_INCLUDE} 3rdparty/include ${CMAKE_BINARY_DIR})
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_link_directories(tenmon PRIVATE 3rdparty/lib/Windows)
|
target_link_directories(tenmon PRIVATE 3rdparty/lib/Windows)
|
||||||
@@ -66,5 +68,26 @@ endif()
|
|||||||
|
|
||||||
install(TARGETS tenmon)
|
install(TARGETS tenmon)
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
install(SCRIPT install.cmake)
|
find_program(XDG-DESKTOP-MENU_EXECUTABLE xdg-desktop-menu)
|
||||||
|
if(XDG-DESKTOP-MENU_EXECUTABLE)
|
||||||
|
install(SCRIPT install.cmake)
|
||||||
|
else()
|
||||||
|
if(DEFINED ENV{FLATPAK_DEST})
|
||||||
|
install(FILES org.nou.tenmon.desktop DESTINATION "$ENV{FLATPAK_DEST}/share/applications")
|
||||||
|
install(FILES org.nou.tenmon.png DESTINATION "$ENV{FLATPAK_DEST}/share/icons/hicolor/32x32/apps")
|
||||||
|
else()
|
||||||
|
install(FILES org.nou.tenmon.desktop DESTINATION "/usr/share/applications")
|
||||||
|
install(FILES org.nou.tenmon.png DESTINATION "/usr/share/icons/hicolor/32x32/apps")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
endif(UNIX)
|
endif(UNIX)
|
||||||
|
|
||||||
|
option(RELEASE_BUILD "Release build" OFF)
|
||||||
|
if(RELEASE_BUILD)
|
||||||
|
add_custom_target(tenmon_version COMMAND ${CMAKE_COMMAND} -Dlocal_dir="${CMAKE_CURRENT_SOURCE_DIR}" -Doutput_dir="${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
|
-P "${CMAKE_CURRENT_SOURCE_DIR}/gitversion.cmake")
|
||||||
|
add_dependencies(tenmon tenmon_version)
|
||||||
|
else()
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -Dlocal_dir=${CMAKE_CURRENT_SOURCE_DIR} -Doutput_dir=${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
-P "${CMAKE_CURRENT_SOURCE_DIR}/gitversion.cmake")
|
||||||
|
endif()
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
Simple image viewer with multithreaded image loading
|
FITS/XISF image viewer with multithreaded image loading
|
||||||
|
|
||||||
To get all dependencies install these packages
|
To get all dependencies install these packages
|
||||||
|
|
||||||
sudo apt install qtbase5-dev libraw-dev libexif-dev libcfitsio-dev
|
sudo apt install qtbase5-dev libraw-dev libexif-dev libcfitsio-dev libgsl-dev cmake
|
||||||
|
|
||||||
Then to build run
|
Then to build run standard cmake
|
||||||
|
|
||||||
qmake .
|
cmake -B build -S .
|
||||||
make
|
make
|
||||||
./tenmon
|
./tenmon
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#include "about.h"
|
||||||
|
#include <QTextEdit>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QLocale>
|
||||||
|
#include "gitversion.h"
|
||||||
|
|
||||||
|
About::About(QWidget *parent) : QDialog(parent)
|
||||||
|
{
|
||||||
|
setWindowTitle(tr("About Tenmon"));
|
||||||
|
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||||
|
QLabel *label = new QLabel(this);
|
||||||
|
|
||||||
|
QFile tenmonText(":/about/tenmon");
|
||||||
|
tenmonText.open(QIODevice::ReadOnly);
|
||||||
|
QByteArray text = tenmonText.readAll();
|
||||||
|
text.replace("@GITVERSION@", GITVERSION);
|
||||||
|
label->setText(text);
|
||||||
|
label->setOpenExternalLinks(true);
|
||||||
|
|
||||||
|
QTextEdit *pcl = new QTextEdit(this);
|
||||||
|
QFile pclText(":/about/pcl");
|
||||||
|
pclText.open(QIODevice::ReadOnly);
|
||||||
|
pcl->setText(pclText.readAll());
|
||||||
|
pcl->setReadOnly(true);
|
||||||
|
|
||||||
|
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok);
|
||||||
|
connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||||
|
|
||||||
|
layout->addWidget(label);
|
||||||
|
layout->addWidget(pcl);
|
||||||
|
layout->addWidget(buttonBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
HelpDialog::HelpDialog(QWidget *parent) : QDialog(parent)
|
||||||
|
{
|
||||||
|
setWindowTitle(tr("Help"));
|
||||||
|
resize(800, 600);
|
||||||
|
|
||||||
|
QLocale locale;
|
||||||
|
QString l = QLocale::languageToString(locale.language());
|
||||||
|
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||||
|
QTextEdit *helpText = new QTextEdit(this);
|
||||||
|
helpText->setReadOnly(true);
|
||||||
|
|
||||||
|
QFile tenmonText(":/help");
|
||||||
|
tenmonText.open(QIODevice::ReadOnly);
|
||||||
|
helpText->setHtml(tenmonText.readAll());
|
||||||
|
|
||||||
|
layout->addWidget(helpText);
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef ABOUT_H
|
||||||
|
#define ABOUT_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
class About : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
About(QWidget *parent = nullptr);
|
||||||
|
};
|
||||||
|
|
||||||
|
class HelpDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
HelpDialog(QWidget *parent = nullptr);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ABOUT_H
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 7.4 KiB |
@@ -0,0 +1,93 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<head>
|
||||||
|
<style type="text/css">
|
||||||
|
h1, h2, h3, h4 { padding:0px; margin:10px; }
|
||||||
|
p { padding:0px; margin:5px; }
|
||||||
|
img { margin: 5px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>Tenmon help</h2>
|
||||||
|
|
||||||
|
<p>Tenmon is intended primarily for viewing astro photos and images. It supports the following formats:
|
||||||
|
<ul>
|
||||||
|
<li>FITS 8, 16 bit integer and 32 bit float</li>
|
||||||
|
<li>XISF 8, 16 bit integer and 32 bit float</li>
|
||||||
|
<li>JPEG and PNG images</li>
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Main windows</h3>
|
||||||
|
<p>The main window shows the currently loaded image. On the left is the <i>Image info</i> panel which displays details about the loaded image.
|
||||||
|
The <i>File system</i> panel shows other images in the same directory as the loaded image. At the top is the main menu and below that is the
|
||||||
|
<i>Stretch panel</i> containing various options for auto-stretching linear image data.</p>
|
||||||
|
<p>All panels in the interface can be moved around and/or closed. Any closed or non-visible panel can be
|
||||||
|
re-opened through the <i>Docks</i> menu at the top.</p>
|
||||||
|
|
||||||
|
<h3>Opening and saving images</h3>
|
||||||
|
<p>To load an image select <i>File->Open</i> and choose the file. After a file is loaded, it becomes visible in the main image panel, and the
|
||||||
|
<i>File system</i> panel will show the other images in the same directory.</p>
|
||||||
|
<p>The loaded image can be exported to a different format with <i>File->Save as</i>. Any of the formats JPEG, PNG FITS and XISF can be selected.
|
||||||
|
In the case of saving JPEG or PNG, the stretch function is applied to the saved image. FITS and XISF are saved/converted without applying the stretch.
|
||||||
|
To open an image, you can also drag and drop it to main window.</p>
|
||||||
|
|
||||||
|
<h3>View</h3>
|
||||||
|
<p>The <i>View</i> menu has options to control the size and scale of displayed images:
|
||||||
|
<ul>
|
||||||
|
<li><i>Zoom In</i> and <i>Zoom Out</i> magnify and shrink the image. The mouse wheel can be also used to zoom freely.</li>
|
||||||
|
<li><i>Best fit</i> auto-zooms the image to fit the current size of the window.</li>
|
||||||
|
<li><i>100%</i> will zoom to 1:1 scale.</li>
|
||||||
|
<li><i>Fullscreen</i> enlarges the main window to the whole screen.</li>
|
||||||
|
<li><i>Thumbnails</i> will display small thumbnails for all images in the current directory.</li>
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Stretch toolbar</h3>
|
||||||
|
<p>This panel changes how images are displayed.
|
||||||
|
<br><img src=":/about/stretch-panel.png"></p>
|
||||||
|
<p>Starting on the left, there is slider scale with three adjustable points to manually control the stretch.
|
||||||
|
<ul>
|
||||||
|
<li>black point - all pixels with lower value (darker) than this setting will be clipped black</li>
|
||||||
|
<li>mid point - defines the value to be stretched to 50% intensity</li>
|
||||||
|
<li>white point - all pixels with higher value (brighter) than this will be clipped white</li>
|
||||||
|
</ul>
|
||||||
|
Following the slider are 5 buttons for automatic stretching:
|
||||||
|
<ul>
|
||||||
|
<li><i>Auto Stretch</i> automatically apply black and mid points to render the image with optimal brightness.</li>
|
||||||
|
<li><i>Reset</i> reset three values for black, mid and white point to default.</li>
|
||||||
|
<li><i>Invert</i> invert colors to display the image as negative.</li>
|
||||||
|
<li><i>Super pixel CFA </i> average 2x2 pixels into one (suitable for images from colour camera).</li>
|
||||||
|
<li><i>Apply Auto stretch on load</i> toggle automatically applying Autostretch for each image when loaded.</p>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3>Marking images</h3>
|
||||||
|
<p>Images can be marked in the <i>Select</i> menu. To show a list of only the marked images, use <i>Select->Show marked</i>.
|
||||||
|
This dialog can be useful to clear marks from images. Marked images show a <b>*</b> character in the title bar of the main window.
|
||||||
|
Marked images can be copied or moved to a selected directory with <i>File->Copy/Move marked files</i>.
|
||||||
|
After copying or moving, the list of marked files is cleared. The list of marked files will be remembered after quitting the program.</p>
|
||||||
|
|
||||||
|
<h3>Database of FITS/XISF files</h3>
|
||||||
|
<p>Tenmon can scan a directory of FITS/XISF files and index metadata from FITS headers into it's internal database. This allows searching and sorting images based on that metadata.</p>
|
||||||
|
<p>To populate the database, select a directory of FITS/XISF files with <i>File->Index directory</i>.
|
||||||
|
After the selected directory is searched, metadata parsed from the images will be stored in the database.
|
||||||
|
To refresh the database, run <i>File->Reindex</i>. This will update any changed metadata and remove any record of
|
||||||
|
deleted files. To index new files, simply run <i>Index directory</i> again.</p>
|
||||||
|
<p>The database is viewed through a panel which is not visible in the default layout. To add the database panel to the view,
|
||||||
|
toggle <i>Docks->FITS/XISF database</i>. Once visible, database panel shows the database as a table with a column for each property.
|
||||||
|
Below the table is button to select which columns/properties are displayed.</p>
|
||||||
|
|
||||||
|
<p>Also at the bottom of the database panel are three combo boxes and text inputs used for filtering.
|
||||||
|
Select the property to filter on with the combo box and in the adjacent text box enter a string to search for in that property.
|
||||||
|
<p>Wildcards:
|
||||||
|
<ul>
|
||||||
|
<li><b>%</b> (percent) is a wildcard representing zero or more of any characters.</li>
|
||||||
|
<li><b>_</b> (underscore) is a wildcard for exactly one of any character.</i>
|
||||||
|
<li>Without wildcard characters, the exact string must match.</li>
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
<br><img src=":/about/filter.png"><br>
|
||||||
|
This example filters for files where: "Bias" is in the file name, the OBJECT property is "M_42" (where the underscore can be any single character), and the DATE property begins with "2022".
|
||||||
|
</p>
|
||||||
|
<p><small>PS: Kanji in icon means astronomy in Japanese</small></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<head>
|
||||||
|
<style type="text/css">
|
||||||
|
h1, h2, h3, h4 { padding:0px; margin:10px; }
|
||||||
|
p { padding:0px; margin:5px 5px 10px 5px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>Tenmon pomocník</h2>
|
||||||
|
|
||||||
|
<p>Tenmon slúži primárne na zobrazenie astronomických fotiek a obrázkov. Dokáže otvoriť nasledovné formáty:
|
||||||
|
<ul>
|
||||||
|
<li>FITS 8, 16 bitové celočíselné a 32 bitové s plávajúcou čiarkou</li>
|
||||||
|
<li>XISF 8, 16 bitové celočíselné a 32 bitové s plávajúcou čiarkou</li>
|
||||||
|
<li>JPEG a PNG obrázky</li>
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Hlavné okno</h3>
|
||||||
|
<p>V hlavnom okne sa zobrazujú načítané obrázky. Naľavo sú potom <i>Informácie o obrázku</i> kde sa zobrazujú podrobné
|
||||||
|
informácie o aktuálnom obrázku a <i>Zoznam súborov</i> kde sú všetky obrázky z adresára kde je aktuálne zobrazený obrázok.
|
||||||
|
Hore je hlavné menu a pod ním je <i>Panel úrovní</i>. Všetky panely sa dajú zavrieť a presúvať. Zatvorený panel sa dá znova
|
||||||
|
zobraziť v menu <i>Dokovacie panely</i>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Otváranie a ukladanie obrázkov</h3>
|
||||||
|
<p>Otvoriť obrázok je možné v menu <i>Súbor->Otvoriť</i>. Po vybraní súboru ktorý sa má otvoriť je
|
||||||
|
tento zobrazený v hlavnom okne. Taktiež sú v panely <i>Súborový systém</i> zobrazené ďalšie obrázky v
|
||||||
|
adresári kde sa nachádza zobrazený obrázok.</p>
|
||||||
|
<p>Aktuálne zobrazený obrázok je možné uložiť v inom formáte cez voľbu <i>Súbor->Ulož ako</i>. Dá sa vybrať
|
||||||
|
formát JPEG, PNG, FITS a XISF. V prípade JPEG alebo PNG sa aplikuje funkcia na úpravu úrovní. Pri FITS a XISF
|
||||||
|
sa dáta skonvertujú bez zmeny úrovní.</p>
|
||||||
|
|
||||||
|
<h3>Zobrazenie</h3>
|
||||||
|
<p>Menu <i>Zobrazenie</i> ovplyvňuje veľkosť a škálu zobrazovaných obrázkov.
|
||||||
|
<i>Priblížiť/Oddialiť</i> zväčší a zmenší obrázok. Na toto tiež slúži aj kolečko myši. <i>Najlepšia veľkosť</i> zobrazí
|
||||||
|
obrázok tak aby bol zobrazený na celú plochu. <i>100%</i> zobrazí obrázok v pomere 1:1. <i>Celá obrazovka</i> zobrazí
|
||||||
|
hlavné okno na celú obrazovku. <i>Náhľady</i> zobrazí malé náhľady pre všetky obrázky z aktuálneho adresára.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Panel úrovní</h3>
|
||||||
|
<p>
|
||||||
|
Tento panel umožňuje upraviť spôsob ako sa zobrazujú obrazové dáta. Ako prvá je na tomto panely posuvná škála
|
||||||
|
na ktorej sa dajú nastaviť tri body.
|
||||||
|
<br><br><img src=":/about/stretch-panel.png">
|
||||||
|
<ul>
|
||||||
|
<li>čierny bod - všetky pixeli s hodnotou menšou ako nastavená budú zobrazené ako čierne</li>
|
||||||
|
<li>stredný bod - pixeli s touto hodnotou budú zobrazené ako 50% šedá</li>
|
||||||
|
<li>biely bod - pixeli nad touto hodnotou budú zobrazené ako biele</li>
|
||||||
|
</ul>
|
||||||
|
Nasleduje tlačidlo ktoré nastaví hodnoty čierneho a stredného bodu tak aby bol obrázok zobrazený optimálnym jasom.
|
||||||
|
Druhé tlačidlo resetuje hodnoty pre čierny, stredný a biely bod na východzie hodnoty. Invertovanie farieb zobrazí obrázok ako negatív.
|
||||||
|
Super pixel CFA spriemeruje dva krát dva pixeli do jedného čo je vhodné pri prezeraní surových obrázkov z farebných kamier.
|
||||||
|
Posledné tlačidlo zapína a vypína nastavovanie optimálnych hodnôt úrovní pre každý obrázok zvlášť.</p>
|
||||||
|
|
||||||
|
<h3>Označovanie obrázkov</h3>
|
||||||
|
<p>Obrázky je možné si označiť cez menu <i>Výber</i>. Zoznam takto označených obrázkov sa dá zobraziť cez
|
||||||
|
<i>Výber->Ukázať označené</i>. V tomto dialógu sa dá tiež tento zoznam upraviť. Okrem toho sa pri označených
|
||||||
|
obrázkoch zobrazuje znak * v záhlaví hlavného okna. Takto označené obrázky je potom možné skopírovať alebo
|
||||||
|
presunúť do vybraného adresára pomocou <i>Súbor->Skopírovať/Presunúť označené súbory</i>. Po skopírovaní alebo
|
||||||
|
presunutú sa zoznam označených obrázkov vymaže. Program si tento zoznam pamätá aj po svojom ukončení.</p>
|
||||||
|
|
||||||
|
<h3>Databáza FITS/XISF súborov</h3>
|
||||||
|
<p>Program vie prehľadať adresár a indexovať meta údaje z FIST a XISF obrázkov do internej databázy v ktorej sa dá
|
||||||
|
následne vyhľadávať. Najprv je treba indexovať adresár s FIST/XISF obrázkami <i>Súbor->Indexovať adresár</i>.
|
||||||
|
Vybraný adresár je prehľadaný a meta údaje z FIST a XISF obrázkov sú uložené do databázy. Na kontrolu a obnovu datábazy
|
||||||
|
je možné spustiť re-indexáciu <i>Súbor->Reindex</i>. Toto obnoví zmenené údaje a odstráni záznamy o už neexistujúcich súboroch.
|
||||||
|
Pre indexovanie nových súborov je treba znova pustiť indexáciu.</p>
|
||||||
|
<p>Pre zobrazenie databázy je treba zobraziť jej panel cez <i>Dokovacie panely->Databáza FITS/XISF súborov</i>. Databáza je zobrazená vo forme tabuľky
|
||||||
|
kde sú jednotlivé stĺpcoch zobrazené vybrané vlastnosti. V spodnej časti panelu je tlačidlo ktoré zobrazí dialóg na výber zobrazovaných
|
||||||
|
sĺpcov. Nasledujú tri výberové a textové polia. Tieto slúžia na vyhľadávanie v databáze. Výberové pole určuje stĺpec v ktorom sa
|
||||||
|
má vyhľadávať a do textového poľa sa zadáva hodnota na vyhľadanie.
|
||||||
|
<br><img src=":/about/filter.png"><br>
|
||||||
|
V nasledovnom príklade sa vyhľadajú súbory ktoré majú v mene súboru "Bias", OBJECT je M_42 a DATE začína reťazcom 2022. Znak % sa berie ako
|
||||||
|
zástupný znak za hocijaký reťazec znakov aj žiadny. Znak _ je tiež zástupný znak zastupujúci práve jeden znak.
|
||||||
|
Bez použitia zástupných znakov sa vyhľadá iba presný výskyt.</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
*******************************************************************************
|
||||||
|
PixInsight Class Library License Version 1.0
|
||||||
|
*******************************************************************************
|
||||||
|
|
||||||
|
Copyright (c) 2003-2021, Pleiades Astrophoto S.L. All Rights Reserved.
|
||||||
|
|
||||||
|
Redistribution and use in both source and binary forms, with or without modification, is permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. All redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. All 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.
|
||||||
|
|
||||||
|
3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names of their contributors, may be used to endorse or promote products derived from this software without specific prior written permission. For written permission, please contact info@pixinsight.com.
|
||||||
|
|
||||||
|
4. All products derived from this software, in any form whatsoever, must reproduce the following acknowledgment in the end-user documentation and/or other materials provided with the product:
|
||||||
|
|
||||||
|
"This product is based on software from the PixInsight project, developed by
|
||||||
|
Pleiades Astrophoto and its contributors (https://pixinsight.com/)."
|
||||||
|
|
||||||
|
Alternatively, if that is where third-party acknowledgments normally appear,
|
||||||
|
this acknowledgment must be reproduced in the product itself.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS "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 PLEIADES ASTROPHOTO OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE, DATA OR PROFITS) 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.
|
||||||
|
|
||||||
|
*******************************************************************************
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
@@ -0,0 +1,20 @@
|
|||||||
|
<table><tr>
|
||||||
|
<td style="padding-right:10px"><img src=":/org.nou.tenmon.png"></td>
|
||||||
|
<td><h3>Tenmon</h3>
|
||||||
|
Tenmon is FITS/XISF image viewer and converter. It also index FITS keywords.<br>
|
||||||
|
v@GITVERSION@ Copyright © 2022 Dušan Poizl<br><br>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify<br>
|
||||||
|
it under the terms of the GNU General Public License as published by<br>
|
||||||
|
the Free Software Foundation, either version 3 of the License, or<br>
|
||||||
|
(at your option) any later version.<br><br>
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,<br>
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br>
|
||||||
|
GNU General Public License for more details.<br><br>
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License<br>
|
||||||
|
along with this program. If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.
|
||||||
|
</td>
|
||||||
|
</tr></table>
|
||||||
+85
-53
@@ -98,6 +98,11 @@ QStringList Database::getMarkedFiles()
|
|||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Database::clearMarkedFiles()
|
||||||
|
{
|
||||||
|
QSqlDatabase::database().exec("DELETE FROM files");
|
||||||
|
}
|
||||||
|
|
||||||
bool Database::checkError(QSqlQuery &query)
|
bool Database::checkError(QSqlQuery &query)
|
||||||
{
|
{
|
||||||
QSqlError error = query.lastError();
|
QSqlError error = query.lastError();
|
||||||
@@ -134,6 +139,28 @@ void Database::indexDir(const QDir &dir, QProgressDialog *progress)
|
|||||||
database.rollback();
|
database.rollback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Database::reindex(QProgressDialog *progress)
|
||||||
|
{
|
||||||
|
QVariantList deleteids;
|
||||||
|
QSqlDatabase database = QSqlDatabase::database();
|
||||||
|
QSqlQuery files = database.exec("SELECT id,file,mtime FROM fits_files");
|
||||||
|
progress->setMaximum(files.size());
|
||||||
|
int i = 0;
|
||||||
|
while(files.next())
|
||||||
|
{
|
||||||
|
QString path = files.value(1).toString();
|
||||||
|
QFileInfo file(path);
|
||||||
|
if(file.exists() && file.fileTime(QFileDevice::FileModificationTime).toUTC().toString(Qt::ISODate) != files.value(2).toString())
|
||||||
|
indexFile(file);
|
||||||
|
if(!file.exists())
|
||||||
|
deleteids.append(files.value(0));
|
||||||
|
progress->setValue(i++);
|
||||||
|
}
|
||||||
|
QSqlQuery deleteFiles("DELETE FROM fits_files WHERE id = ?", database);
|
||||||
|
deleteFiles.bindValue(0, deleteids);
|
||||||
|
deleteFiles.execBatch();
|
||||||
|
}
|
||||||
|
|
||||||
QStringList Database::getFitsKeywords()
|
QStringList Database::getFitsKeywords()
|
||||||
{
|
{
|
||||||
m_headerKeywords.exec();
|
m_headerKeywords.exec();
|
||||||
@@ -156,63 +183,68 @@ bool Database::indexDir2(const QDir &dir, QProgressDialog *progress)
|
|||||||
if(!indexDir2(dir.filePath(d), progress))
|
if(!indexDir2(dir.filePath(d), progress))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ImageInfoData info;
|
|
||||||
for(const QFileInfo &file : files)
|
for(const QFileInfo &file : files)
|
||||||
{
|
{
|
||||||
progress->setValue(m_progress++);
|
progress->setValue(m_progress++);
|
||||||
if(progress->wasCanceled())return false;
|
if(progress->wasCanceled())return false;
|
||||||
QString filePath = file.absoluteFilePath();
|
if(!indexFile(file))return false;
|
||||||
QString mtime = file.fileTime(QFileDevice::FileModificationTime).toUTC().toString(Qt::ISODate);
|
|
||||||
m_checkFile.bindValue(0, filePath);
|
|
||||||
m_checkFile.exec();
|
|
||||||
if(m_checkFile.next())
|
|
||||||
{
|
|
||||||
if(m_checkFile.value(1).toString() == mtime)
|
|
||||||
continue;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_deleteFile.bindValue(0, m_checkFile.value(0).toLongLong());
|
|
||||||
m_deleteFile.exec();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ok;
|
|
||||||
if(filePath.endsWith(".xisf", Qt::CaseInsensitive))
|
|
||||||
ok = readXISFHeader(filePath, info);
|
|
||||||
else
|
|
||||||
ok = readFITSHeader(filePath, info);
|
|
||||||
|
|
||||||
qlonglong last_id = -1;
|
|
||||||
if(ok)
|
|
||||||
{
|
|
||||||
m_insertFile.bindValue(0, filePath);
|
|
||||||
m_insertFile.bindValue(1, mtime);
|
|
||||||
if(!m_insertFile.exec())
|
|
||||||
{
|
|
||||||
qDebug() << m_insertFile.lastError();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
last_id = m_insertFile.lastInsertId().toLongLong();
|
|
||||||
QVariantList file_id, keys, values, comments;
|
|
||||||
for(auto &record : info.fitsHeader)
|
|
||||||
{
|
|
||||||
file_id << last_id;
|
|
||||||
keys << QString(record.key);
|
|
||||||
values << record.value.toString();
|
|
||||||
comments << QString(record.comment);
|
|
||||||
}
|
|
||||||
m_insertFitsHeader.bindValue(0, file_id);
|
|
||||||
m_insertFitsHeader.bindValue(1, keys);
|
|
||||||
m_insertFitsHeader.bindValue(2, values);
|
|
||||||
m_insertFitsHeader.bindValue(3, comments);
|
|
||||||
if(!m_insertFitsHeader.execBatch())
|
|
||||||
{
|
|
||||||
qDebug() << m_insertFitsHeader.lastError();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
qDebug() << filePath << last_id;
|
|
||||||
info.fitsHeader.clear();
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Database::indexFile(const QFileInfo &file)
|
||||||
|
{
|
||||||
|
ImageInfoData info;
|
||||||
|
QString filePath = file.absoluteFilePath();
|
||||||
|
QString mtime = file.fileTime(QFileDevice::FileModificationTime).toUTC().toString(Qt::ISODate);
|
||||||
|
m_checkFile.bindValue(0, filePath);
|
||||||
|
m_checkFile.exec();
|
||||||
|
if(m_checkFile.next())
|
||||||
|
{
|
||||||
|
if(m_checkFile.value(1).toString() == mtime)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_deleteFile.bindValue(0, m_checkFile.value(0).toLongLong());
|
||||||
|
m_deleteFile.exec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ok;
|
||||||
|
if(filePath.endsWith(".xisf", Qt::CaseInsensitive))
|
||||||
|
ok = readXISFHeader(filePath, info);
|
||||||
|
else
|
||||||
|
ok = readFITSHeader(filePath, info);
|
||||||
|
|
||||||
|
qlonglong last_id = -1;
|
||||||
|
if(ok)
|
||||||
|
{
|
||||||
|
m_insertFile.bindValue(0, filePath);
|
||||||
|
m_insertFile.bindValue(1, mtime);
|
||||||
|
if(!m_insertFile.exec())
|
||||||
|
{
|
||||||
|
qDebug() << m_insertFile.lastError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
last_id = m_insertFile.lastInsertId().toLongLong();
|
||||||
|
QVariantList file_id, keys, values, comments;
|
||||||
|
for(auto &record : info.fitsHeader)
|
||||||
|
{
|
||||||
|
file_id << last_id;
|
||||||
|
keys << QString(record.key);
|
||||||
|
values << record.value.toString();
|
||||||
|
comments << QString(record.comment);
|
||||||
|
}
|
||||||
|
m_insertFitsHeader.bindValue(0, file_id);
|
||||||
|
m_insertFitsHeader.bindValue(1, keys);
|
||||||
|
m_insertFitsHeader.bindValue(2, values);
|
||||||
|
m_insertFitsHeader.bindValue(3, comments);
|
||||||
|
if(!m_insertFitsHeader.execBatch())
|
||||||
|
{
|
||||||
|
qDebug() << m_insertFitsHeader.lastError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qDebug() << filePath << last_id;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -28,11 +28,14 @@ public:
|
|||||||
bool unmark(const QString &filename);
|
bool unmark(const QString &filename);
|
||||||
bool isMarked(const QString &filename);
|
bool isMarked(const QString &filename);
|
||||||
QStringList getMarkedFiles();
|
QStringList getMarkedFiles();
|
||||||
|
void clearMarkedFiles();
|
||||||
|
|
||||||
void indexDir(const QDir &dir, QProgressDialog *progress);
|
void indexDir(const QDir &dir, QProgressDialog *progress);
|
||||||
|
void reindex(QProgressDialog *progress);
|
||||||
QStringList getFitsKeywords();
|
QStringList getFitsKeywords();
|
||||||
protected:
|
protected:
|
||||||
bool indexDir2(const QDir &dir, QProgressDialog *progress);
|
bool indexDir2(const QDir &dir, QProgressDialog *progress);
|
||||||
|
bool indexFile(const QFileInfo &file);
|
||||||
bool checkError(QSqlQuery &query);
|
bool checkError(QSqlQuery &query);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
set(_build_version "unknown")
|
||||||
|
|
||||||
|
find_package(Git)
|
||||||
|
if(GIT_FOUND)
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${GIT_EXECUTABLE} describe --tags HEAD
|
||||||
|
WORKING_DIRECTORY "${local_dir}"
|
||||||
|
OUTPUT_VARIABLE _build_version
|
||||||
|
ERROR_QUIET
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
message(STATUS "GIT hash: ${_build_version}")
|
||||||
|
else()
|
||||||
|
message(STATUS "GIT not found")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "local:${local_dir} output:${output_dir}")
|
||||||
|
|
||||||
|
configure_file("${local_dir}/gitversion.h.in" "${output_dir}/gitversion.h" @ONLY)
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef GITVERSION_H
|
||||||
|
#define GITVERSION_H
|
||||||
|
|
||||||
|
#define GITVERSION "@_build_version@"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -306,7 +306,9 @@ QVariant ImageRingList::headerData(int section, Qt::Orientation orientation, int
|
|||||||
void ImageRingList::setFiles(const QStringList files, const QString ¤tFile)
|
void ImageRingList::setFiles(const QStringList files, const QString ¤tFile)
|
||||||
{
|
{
|
||||||
QThreadPool::globalInstance()->clear();
|
QThreadPool::globalInstance()->clear();
|
||||||
|
m_thumbPool->clear();
|
||||||
QThreadPool::globalInstance()->waitForDone();
|
QThreadPool::globalInstance()->waitForDone();
|
||||||
|
m_thumbPool->waitForDone();
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
m_images.clear();
|
m_images.clear();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|||||||
+13
-1
@@ -7,6 +7,8 @@
|
|||||||
#include <QOpenGLFramebufferObject>
|
#include <QOpenGLFramebufferObject>
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
struct RawImageType
|
struct RawImageType
|
||||||
{
|
{
|
||||||
@@ -62,6 +64,13 @@ ImageWidget::ImageWidget(QWidget *parent) : QOpenGLWidget(parent)
|
|||||||
m_updateTimer->setSingleShot(true);
|
m_updateTimer->setSingleShot(true);
|
||||||
connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(update()));
|
connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(update()));
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
|
QTimer::singleShot(1000, [this](){
|
||||||
|
if(!isValid())
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, tr("OpenGL error"), tr("Could not initialize OpenGL 3.3 context. Ensure that proper GPU driver is installed."));
|
||||||
|
QCoreApplication::exit(-1);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageWidget::~ImageWidget()
|
ImageWidget::~ImageWidget()
|
||||||
@@ -258,6 +267,9 @@ void ImageWidget::initializeGL()
|
|||||||
f->glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
|
f->glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
|
||||||
f3 = context()->versionFunctions<QOpenGLFunctions_3_3_Core>();
|
f3 = context()->versionFunctions<QOpenGLFunctions_3_3_Core>();
|
||||||
|
|
||||||
|
if(f3 == nullptr)
|
||||||
|
QMessageBox::critical(this, tr("OpenGL error"), tr("Could not initialize OpenGL 3.3 context. Ensure that proper GPU driver is installed."));
|
||||||
|
|
||||||
m_vao = std::unique_ptr<QOpenGLVertexArrayObject>(new QOpenGLVertexArrayObject);
|
m_vao = std::unique_ptr<QOpenGLVertexArrayObject>(new QOpenGLVertexArrayObject);
|
||||||
m_vaoThumb = std::unique_ptr<QOpenGLVertexArrayObject>(new QOpenGLVertexArrayObject);
|
m_vaoThumb = std::unique_ptr<QOpenGLVertexArrayObject>(new QOpenGLVertexArrayObject);
|
||||||
m_vao->create();
|
m_vao->create();
|
||||||
@@ -368,7 +380,7 @@ void ImageWidget::dropEvent(QDropEvent *event)
|
|||||||
{
|
{
|
||||||
if(url.isLocalFile())
|
if(url.isLocalFile())
|
||||||
{
|
{
|
||||||
emit fileDropped(url.path());
|
emit fileDropped(url.toLocalFile());
|
||||||
event->accept();
|
event->accept();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
find_program(XDG-DESKTOP-MENU_EXECUTABLE xdg-desktop-menu)
|
find_program(XDG-DESKTOP-MENU_EXECUTABLE xdg-desktop-menu)
|
||||||
find_program(XDG-ICON-RESOURCE_EXECUTABLE xdg-icon-resource)
|
find_program(XDG-ICON-RESOURCE_EXECUTABLE xdg-icon-resource)
|
||||||
execute_process(COMMAND ${XDG-DESKTOP-MENU_EXECUTABLE} install --novendor org.nou.tenmon.desktop WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
execute_process(COMMAND ${XDG-DESKTOP-MENU_EXECUTABLE} install --novendor org.nou.tenmon.desktop WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||||
execute_process(COMMAND ${XDG-ICON-RESOURCE_EXECUTABLE} install --novendor --size 32 icon.png org.nou.tenmon WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
execute_process(COMMAND ${XDG-ICON-RESOURCE_EXECUTABLE} install --novendor --size 32 org.nou.tenmon.png org.nou.tenmon WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
|||||||
+147
@@ -492,3 +492,150 @@ bool readXISFHeader(const QString &path, ImageInfoData &info)
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConvertRunable::ConvertRunable(const QString &in, const QString &out) :
|
||||||
|
m_infile(in),
|
||||||
|
m_outfile(out)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void writeXISFImage(pcl::XISFWriter &writer, RawImage *rawimg)
|
||||||
|
{
|
||||||
|
const cv::Mat &cvmat = rawimg->mat();
|
||||||
|
T pclimg(rawimg->width(), rawimg->height(), cvmat.channels() == 1 ? pcl::ColorSpace::Gray : pcl::ColorSpace::RGB);
|
||||||
|
if(cvmat.channels() == 1)
|
||||||
|
{
|
||||||
|
memcpy(pclimg.PixelData(0), rawimg->data(), rawimg->size()*sizeof(typename T::sample));
|
||||||
|
}
|
||||||
|
if(cvmat.channels() == 3)
|
||||||
|
{
|
||||||
|
std::vector<cv::Mat> channels;
|
||||||
|
cv::split(cvmat, channels);
|
||||||
|
memcpy(pclimg.PixelData(0), channels[0].data, rawimg->size()*sizeof(typename T::sample));
|
||||||
|
memcpy(pclimg.PixelData(1), channels[1].data, rawimg->size()*sizeof(typename T::sample));
|
||||||
|
memcpy(pclimg.PixelData(2), channels[2].data, rawimg->size()*sizeof(typename T::sample));
|
||||||
|
}
|
||||||
|
writer.WriteImage(pclimg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeFITSImage(fitsfile *fw, RawImage *rawimage, ImageInfoData &imageinfo)
|
||||||
|
{
|
||||||
|
static QStringList skipKeys = {"SIMPLE", "BITPIX", "NAXIS", "NAXIS1", "NAXIS2", "NAXIS3", "BZERO", "BSCALE", "EXTEND"};
|
||||||
|
|
||||||
|
int status = 0;
|
||||||
|
long firstpix[3] = {1,1,1};
|
||||||
|
|
||||||
|
int channels = rawimage->mat().channels();
|
||||||
|
int naxis = channels == 1 ? 2 : 3;
|
||||||
|
long naxes[3] = {(int)rawimage->width(), (int)rawimage->height(), rawimage->mat().channels()};
|
||||||
|
|
||||||
|
std::vector<cv::Mat> mat;
|
||||||
|
if(channels == 1)
|
||||||
|
mat.push_back(rawimage->mat());
|
||||||
|
else
|
||||||
|
cv::split(rawimage->mat(), mat);
|
||||||
|
|
||||||
|
switch(CV_MAT_DEPTH(rawimage->dataType()))
|
||||||
|
{
|
||||||
|
case CV_8U:
|
||||||
|
fits_create_img(fw, BYTE_IMG, naxis, naxes, &status);
|
||||||
|
for(int i=0; i<channels; i++)
|
||||||
|
{
|
||||||
|
firstpix[2] = i+1;
|
||||||
|
fits_write_pix(fw, TBYTE, firstpix, rawimage->size(), mat[i].data, &status);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CV_16U:
|
||||||
|
fits_create_img(fw, USHORT_IMG, naxis, naxes, &status);
|
||||||
|
for(int i=0; i<channels; i++)
|
||||||
|
{
|
||||||
|
firstpix[2] = i+1;
|
||||||
|
fits_write_pix(fw, TUSHORT, firstpix, rawimage->size(), mat[i].data, &status);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CV_32F:
|
||||||
|
fits_create_img(fw, FLOAT_IMG, naxis, naxes, &status);
|
||||||
|
for(int i=0; i<channels; i++)
|
||||||
|
{
|
||||||
|
firstpix[2] = i+1;
|
||||||
|
fits_write_pix(fw, TFLOAT, firstpix, rawimage->size(), mat[i].data, &status);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for(const FITSRecord &record : imageinfo.fitsHeader)
|
||||||
|
{
|
||||||
|
if(skipKeys.contains(record.key))continue;
|
||||||
|
|
||||||
|
bool isdouble;
|
||||||
|
bool isint;
|
||||||
|
bool isbool = record.value.toString() == "T" || record.value.toString() == "F";
|
||||||
|
double vald = record.value.toDouble(&isdouble);
|
||||||
|
int valb = record.value.toString() == "T";
|
||||||
|
long long vall = record.value.toLongLong(&isint);
|
||||||
|
QByteArray str = record.value.toString().toLatin1();
|
||||||
|
if(isdouble)
|
||||||
|
fits_write_key(fw, TDOUBLE, record.key.data(), &vald, record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
|
||||||
|
else if(isint)
|
||||||
|
fits_write_key(fw, TLONGLONG, record.key.data(), &vall, record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
|
||||||
|
else if(isbool)
|
||||||
|
fits_write_key(fw, TLOGICAL, record.key.data(), &valb, record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
|
||||||
|
else if(record.key == "COMMENT")
|
||||||
|
fits_write_comment(fw, record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
|
||||||
|
else if(record.key == "HISTORY")
|
||||||
|
fits_write_history(fw, record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
|
||||||
|
else
|
||||||
|
fits_write_key(fw, TSTRING, record.key.data(), str.isEmpty() ? nullptr : str.data(), record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertRunable::run()
|
||||||
|
{
|
||||||
|
ImageInfoData imageinfo;
|
||||||
|
RawImage *rawimage = nullptr;
|
||||||
|
if(m_infile.endsWith(".FITS", Qt::CaseInsensitive) || m_infile.endsWith(".FIT", Qt::CaseInsensitive))
|
||||||
|
loadFITS(m_infile, imageinfo, &rawimage);
|
||||||
|
if(m_infile.endsWith(".XISF", Qt::CaseInsensitive))
|
||||||
|
loadXISF(m_infile, imageinfo, &rawimage);
|
||||||
|
|
||||||
|
if(rawimage)
|
||||||
|
{
|
||||||
|
if(m_outfile.endsWith(".XISF", Qt::CaseInsensitive))
|
||||||
|
{
|
||||||
|
pcl::XISFOptions options;
|
||||||
|
pcl::FITSKeywordArray fitskeywords;
|
||||||
|
for(auto &record : imageinfo.fitsHeader)
|
||||||
|
{
|
||||||
|
pcl::FITSHeaderKeyword key(pcl::IsoString(record.key.data()), pcl::IsoString(record.value.toString().toLatin1().data()), pcl::IsoString(record.comment.data()));
|
||||||
|
fitskeywords.Append(key);
|
||||||
|
}
|
||||||
|
pcl::XISFWriter xisf;
|
||||||
|
xisf.Create(m_outfile.utf16(), 1);
|
||||||
|
xisf.WriteFITSKeywords(fitskeywords);
|
||||||
|
switch(CV_MAT_DEPTH(rawimage->dataType()))
|
||||||
|
{
|
||||||
|
case CV_8U:
|
||||||
|
writeXISFImage<pcl::UInt8Image>(xisf, rawimage);
|
||||||
|
break;
|
||||||
|
case CV_16U:
|
||||||
|
writeXISFImage<pcl::UInt16Image>(xisf, rawimage);
|
||||||
|
break;
|
||||||
|
case CV_32F:
|
||||||
|
writeXISFImage<pcl::Image>(xisf, rawimage);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_outfile.endsWith(".FITS", Qt::CaseInsensitive) || m_outfile.endsWith(".FIT", Qt::CaseInsensitive))
|
||||||
|
{
|
||||||
|
int status = 0;
|
||||||
|
fitsfile *fw;
|
||||||
|
if(QFileInfo(m_outfile).exists())QFile::remove(m_outfile);
|
||||||
|
fits_create_diskfile(&fw, m_outfile.toLocal8Bit().data(), &status);
|
||||||
|
writeFITSImage(fw, rawimage, imageinfo);
|
||||||
|
fits_close_file(fw, &status);
|
||||||
|
}
|
||||||
|
delete rawimage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,4 +21,13 @@ public:
|
|||||||
void run();
|
void run();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ConvertRunable : public QRunnable
|
||||||
|
{
|
||||||
|
QString m_infile;
|
||||||
|
QString m_outfile;
|
||||||
|
public:
|
||||||
|
ConvertRunable(const QString &in, const QString &out);
|
||||||
|
void run();
|
||||||
|
};
|
||||||
|
|
||||||
#endif // LOADRUNABLE_H
|
#endif // LOADRUNABLE_H
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QSurfaceFormat>
|
#include <QSurfaceFormat>
|
||||||
|
#include <QTranslator>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -14,7 +15,11 @@ int main(int argc, char *argv[])
|
|||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
a.setOrganizationName("nou");
|
a.setOrganizationName("nou");
|
||||||
a.setApplicationName("Tenmon");
|
a.setApplicationName("Tenmon");
|
||||||
a.setWindowIcon(QIcon(":/icon.png"));
|
a.setWindowIcon(QIcon(":/org.nou.tenmon.png"));
|
||||||
|
|
||||||
|
QTranslator translator;
|
||||||
|
if(translator.load(QLocale(), "tenmon", "_", ":/translations"))
|
||||||
|
a.installTranslator(&translator);
|
||||||
|
|
||||||
MainWindow w;
|
MainWindow w;
|
||||||
w.show();
|
w.show();
|
||||||
|
|||||||
+117
-43
@@ -14,6 +14,10 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
#include <QThreadPool>
|
||||||
|
#include "loadrunable.h"
|
||||||
|
#include "markedfiles.h"
|
||||||
|
#include "about.h"
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
@@ -65,7 +69,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
|||||||
filesystemDock->setObjectName("filesystemDock");
|
filesystemDock->setObjectName("filesystemDock");
|
||||||
addDockWidget(Qt::LeftDockWidgetArea, filesystemDock);
|
addDockWidget(Qt::LeftDockWidgetArea, filesystemDock);
|
||||||
|
|
||||||
QDockWidget *databaseViewDock = new QDockWidget(tr("FITS files database"), this);
|
QDockWidget *databaseViewDock = new QDockWidget(tr("FITS/XISF files database"), this);
|
||||||
databaseViewDock->setWidget(m_databaseView);
|
databaseViewDock->setWidget(m_databaseView);
|
||||||
databaseViewDock->setObjectName("databaseViewDock");
|
databaseViewDock->setObjectName("databaseViewDock");
|
||||||
databaseViewDock->hide();
|
databaseViewDock->hide();
|
||||||
@@ -78,16 +82,23 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
|||||||
connect(m_ringList, SIGNAL(infoLoaded(ImageInfoData)), m_info, SLOT(setInfo(const ImageInfoData&)));
|
connect(m_ringList, SIGNAL(infoLoaded(ImageInfoData)), m_info, SLOT(setInfo(const ImageInfoData&)));
|
||||||
connect(m_ringList, SIGNAL(currentImageChanged(int)), m_filesystem, SLOT(selectFile(int)));
|
connect(m_ringList, SIGNAL(currentImageChanged(int)), m_filesystem, SLOT(selectFile(int)));
|
||||||
connect(m_ringList, &ImageRingList::thumbnailLoaded, m_imageGL->imageWidget(), &ImageWidget::thumbnailLoaded);
|
connect(m_ringList, &ImageRingList::thumbnailLoaded, m_imageGL->imageWidget(), &ImageWidget::thumbnailLoaded);
|
||||||
|
connect(m_ringList, &ImageRingList::pixmapLoaded, m_stretchPanel, &StretchToolbar::imageLoaded);
|
||||||
connect(m_imageGL->imageWidget(), &ImageWidget::fileDropped, this, static_cast<void (MainWindow::*)(const QString &)>(&MainWindow::loadFile));
|
connect(m_imageGL->imageWidget(), &ImageWidget::fileDropped, this, static_cast<void (MainWindow::*)(const QString &)>(&MainWindow::loadFile));
|
||||||
|
|
||||||
QMenu *fileMenu = new QMenu(tr("File"), this);
|
QMenu *fileMenu = new QMenu(tr("File"), this);
|
||||||
fileMenu->addAction(tr("Open"), this, SLOT(loadFile()), QKeySequence("Ctrl+O"));
|
fileMenu->addAction(tr("Open"), this, SLOT(loadFile()), QKeySequence::Open);
|
||||||
|
fileMenu->addAction(tr("Save as"), this, SLOT(saveAs()), QKeySequence::Save);
|
||||||
|
fileMenu->addSeparator();
|
||||||
fileMenu->addAction(tr("Copy marked files"), this, SLOT(copyMarked()));
|
fileMenu->addAction(tr("Copy marked files"), this, SLOT(copyMarked()));
|
||||||
fileMenu->addAction(tr("Save as"), this, SLOT(saveAs()), QKeySequence("Ctrl+S"));
|
fileMenu->addAction(tr("Move marked files"), this, SLOT(moveMarked()));
|
||||||
|
fileMenu->addSeparator();
|
||||||
fileMenu->addAction(tr("Index directory"), this, SLOT(indexDir()));
|
fileMenu->addAction(tr("Index directory"), this, SLOT(indexDir()));
|
||||||
|
fileMenu->addAction(tr("Reindex files"), this, SLOT(reindex()));
|
||||||
|
fileMenu->addSeparator();
|
||||||
QAction *liveModeAction = fileMenu->addAction(tr("Live mode"), this, SLOT(liveMode(bool)));
|
QAction *liveModeAction = fileMenu->addAction(tr("Live mode"), this, SLOT(liveMode(bool)));
|
||||||
liveModeAction->setCheckable(true);
|
liveModeAction->setCheckable(true);
|
||||||
fileMenu->addAction(tr("Exit"), this, SLOT(close()));
|
QAction *exitAction = fileMenu->addAction(tr("Exit"), this, SLOT(close()));
|
||||||
|
exitAction->setShortcut(QKeySequence::Quit);
|
||||||
menuBar()->addMenu(fileMenu);
|
menuBar()->addMenu(fileMenu);
|
||||||
|
|
||||||
QMenu *viewMenu = new QMenu(tr("View"), this);
|
QMenu *viewMenu = new QMenu(tr("View"), this);
|
||||||
@@ -112,6 +123,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
|||||||
selectMenu->addSeparator();
|
selectMenu->addSeparator();
|
||||||
selectMenu->addAction(tr("Mark and next"), this, SLOT(markAndNext()), Qt::Key_M);
|
selectMenu->addAction(tr("Mark and next"), this, SLOT(markAndNext()), Qt::Key_M);
|
||||||
selectMenu->addAction(tr("Unmark and next"), this, SLOT(unmarkAndNext()), Qt::Key_X);
|
selectMenu->addAction(tr("Unmark and next"), this, SLOT(unmarkAndNext()), Qt::Key_X);
|
||||||
|
selectMenu->addAction(tr("Show marked"), this, &MainWindow::showMarkFilesDialog);
|
||||||
menuBar()->addMenu(selectMenu);
|
menuBar()->addMenu(selectMenu);
|
||||||
|
|
||||||
QMenu *analyzeMenu = new QMenu(tr("Analyze"), this);
|
QMenu *analyzeMenu = new QMenu(tr("Analyze"), this);
|
||||||
@@ -146,6 +158,11 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
|||||||
dockMenu->addAction(databaseViewDock->toggleViewAction());
|
dockMenu->addAction(databaseViewDock->toggleViewAction());
|
||||||
menuBar()->addMenu(dockMenu);
|
menuBar()->addMenu(dockMenu);
|
||||||
|
|
||||||
|
QMenu *helpMenu = menuBar()->addMenu(tr("Help"));
|
||||||
|
helpMenu->addAction(tr("Help"), [this]{ HelpDialog help(this); help.exec(); }, QKeySequence::HelpContents);
|
||||||
|
helpMenu->addAction(tr("About Tenmon"), [this]{ About about(this); about.exec(); });
|
||||||
|
helpMenu->addAction(tr("About Qt"), [this](){ QMessageBox::aboutQt(this); });
|
||||||
|
|
||||||
setupSigterm();
|
setupSigterm();
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
restoreGeometry(settings.value("mainwindow/geometry").toByteArray());
|
restoreGeometry(settings.value("mainwindow/geometry").toByteArray());
|
||||||
@@ -239,6 +256,57 @@ void MainWindow::closeEvent(QCloseEvent *event)
|
|||||||
QMainWindow::closeEvent(event);
|
QMainWindow::closeEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::copyOrMove(bool copy)
|
||||||
|
{
|
||||||
|
QString dest = QFileDialog::getExistingDirectory(this, tr("Select destination"), _lastDir);
|
||||||
|
QDir dir(dest);
|
||||||
|
if(!dest.isEmpty() && dir.exists())
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
QStringList files = m_database->getMarkedFiles();
|
||||||
|
QProgressDialog progress(copy ? tr("Copying") : tr("Moving"), tr("Cancel"), 0, files.size(), this);
|
||||||
|
progress.setWindowModality(Qt::WindowModal);
|
||||||
|
progress.show();
|
||||||
|
foreach(const QString &file, files)
|
||||||
|
{
|
||||||
|
QFileInfo info(file);
|
||||||
|
QFile srcFile(file);
|
||||||
|
QFile dstFile(dir.absoluteFilePath(info.fileName()));
|
||||||
|
|
||||||
|
if(dstFile.exists())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(progress.wasCanceled())
|
||||||
|
break;
|
||||||
|
#ifdef __linux__
|
||||||
|
if(copy)
|
||||||
|
{
|
||||||
|
srcFile.open(QIODevice::ReadOnly);
|
||||||
|
dstFile.open(QIODevice::WriteOnly);
|
||||||
|
if(ioctl(dstFile.handle(), BTRFS_IOC_CLONE, srcFile.handle()) < 0)
|
||||||
|
{
|
||||||
|
dstFile.remove();
|
||||||
|
dstFile.close();
|
||||||
|
qDebug() << dstFile.fileName();
|
||||||
|
srcFile.copy(dstFile.fileName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
srcFile.rename(dstFile.fileName());
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if(copy)
|
||||||
|
srcFile.copy(dstFile.fileName());
|
||||||
|
else
|
||||||
|
srcFile.rename(dstFile.fileName());
|
||||||
|
#endif
|
||||||
|
progress.setValue(i++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_database->clearMarkedFiles();
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::socketNotify()
|
void MainWindow::socketNotify()
|
||||||
{
|
{
|
||||||
socketNotifier->setEnabled(false);
|
socketNotifier->setEnabled(false);
|
||||||
@@ -296,17 +364,47 @@ void MainWindow::indexDir()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::reindex()
|
||||||
|
{
|
||||||
|
QProgressDialog progressDialog(tr("Indexing FITS files"), tr("Cancel"), 0, 1, this);
|
||||||
|
progressDialog.setModal(true);
|
||||||
|
m_database->reindex(&progressDialog);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::saveAs()
|
void MainWindow::saveAs()
|
||||||
{
|
{
|
||||||
QString file = QFileDialog::getSaveFileName(this, tr("Save as"), _lastDir, tr("Images (*.jpg *.png *.JPG *.PNG)"));
|
QString selectedFilter;
|
||||||
|
QString file = QFileDialog::getSaveFileName(this, tr("Save as"), _lastDir, tr("JPEG (*.jpg *.JPG);; PNG (*.png *.PNG);;FITS (*.fits *.FITS);;XISF (*.xisf *.XISF)"), &selectedFilter);
|
||||||
if(!file.isEmpty())
|
if(!file.isEmpty())
|
||||||
{
|
{
|
||||||
QImage img = m_imageGL->imageWidget()->renderToImage();
|
QFileInfo info(file);
|
||||||
if(!img.isNull())
|
if(info.suffix().isEmpty())
|
||||||
img.save(file);
|
{
|
||||||
|
if(selectedFilter.contains("jpg"))file += ".jpg";
|
||||||
|
if(selectedFilter.contains("png"))file += ".png";
|
||||||
|
if(selectedFilter.contains("fits"))file += ".fits";
|
||||||
|
if(selectedFilter.contains("xisf"))file += ".xisf";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(file.endsWith(".fits") || file.endsWith(".xisf"))
|
||||||
|
{
|
||||||
|
convert(file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QImage img = m_imageGL->imageWidget()->renderToImage();
|
||||||
|
if(!img.isNull())
|
||||||
|
img.save(file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::convert(const QString &outfile)
|
||||||
|
{
|
||||||
|
QString file = m_ringList->currentImage()->name();
|
||||||
|
QThreadPool::globalInstance()->start(new ConvertRunable(file, outfile));
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::markImage()
|
void MainWindow::markImage()
|
||||||
{
|
{
|
||||||
ImagePtr ptr = m_ringList->currentImage();
|
ImagePtr ptr = m_ringList->currentImage();
|
||||||
@@ -349,42 +447,12 @@ void MainWindow::unmarkAndNext()
|
|||||||
|
|
||||||
void MainWindow::copyMarked()
|
void MainWindow::copyMarked()
|
||||||
{
|
{
|
||||||
QString dest = QFileDialog::getExistingDirectory(this, tr("Select destination"));
|
copyOrMove(true);
|
||||||
QDir dir(dest);
|
}
|
||||||
if(!dest.isEmpty() && dir.exists())
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
QStringList files = m_database->getMarkedFiles();
|
|
||||||
QProgressDialog progress(tr("Copying"), tr("Cancel"), 0, files.size(), this);
|
|
||||||
progress.setWindowModality(Qt::WindowModal);
|
|
||||||
progress.show();
|
|
||||||
foreach(const QString &file, files)
|
|
||||||
{
|
|
||||||
QFileInfo info(file);
|
|
||||||
QFile srcFile(file);
|
|
||||||
QFile dstFile(dir.absoluteFilePath(info.fileName()));
|
|
||||||
|
|
||||||
if(dstFile.exists())
|
void MainWindow::moveMarked()
|
||||||
continue;
|
{
|
||||||
|
copyOrMove(false);
|
||||||
if(progress.wasCanceled())
|
|
||||||
break;
|
|
||||||
#ifdef __linux__
|
|
||||||
srcFile.open(QIODevice::ReadOnly);
|
|
||||||
dstFile.open(QIODevice::WriteOnly);
|
|
||||||
if(ioctl(dstFile.handle(), BTRFS_IOC_CLONE, srcFile.handle()) < 0)
|
|
||||||
{
|
|
||||||
dstFile.remove();
|
|
||||||
dstFile.close();
|
|
||||||
qDebug() << dstFile.fileName();
|
|
||||||
srcFile.copy(dstFile.fileName());
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
srcFile.copy(dstFile.fileName());
|
|
||||||
#endif
|
|
||||||
progress.setValue(i++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::toggleFullScreen()
|
void MainWindow::toggleFullScreen()
|
||||||
@@ -421,6 +489,12 @@ void MainWindow::starFinder(bool findStars)
|
|||||||
m_ringList->setFindStars(findStars);
|
m_ringList->setFindStars(findStars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::showMarkFilesDialog()
|
||||||
|
{
|
||||||
|
MarkedFiles markedFiles;
|
||||||
|
markedFiles.exec();
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::updateWindowTitle()
|
void MainWindow::updateWindowTitle()
|
||||||
{
|
{
|
||||||
ImagePtr ptr = m_ringList->currentImage();
|
ImagePtr ptr = m_ringList->currentImage();
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ protected:
|
|||||||
void setupSigterm();
|
void setupSigterm();
|
||||||
static void signalHandler(int);
|
static void signalHandler(int);
|
||||||
void closeEvent(QCloseEvent *event);
|
void closeEvent(QCloseEvent *event);
|
||||||
|
void copyOrMove(bool copy);
|
||||||
protected slots:
|
protected slots:
|
||||||
void socketNotify();
|
void socketNotify();
|
||||||
void updateWindowTitle();
|
void updateWindowTitle();
|
||||||
@@ -44,17 +45,21 @@ protected slots:
|
|||||||
void loadFile(const QString &path);
|
void loadFile(const QString &path);
|
||||||
void loadFile(int row);
|
void loadFile(int row);
|
||||||
void indexDir();
|
void indexDir();
|
||||||
|
void reindex();
|
||||||
void saveAs();
|
void saveAs();
|
||||||
|
void convert(const QString &outfile);
|
||||||
void markImage();
|
void markImage();
|
||||||
void unmarkImage();
|
void unmarkImage();
|
||||||
void markAndNext();
|
void markAndNext();
|
||||||
void unmarkAndNext();
|
void unmarkAndNext();
|
||||||
void copyMarked();
|
void copyMarked();
|
||||||
|
void moveMarked();
|
||||||
void toggleFullScreen();
|
void toggleFullScreen();
|
||||||
void liveMode(bool active);
|
void liveMode(bool active);
|
||||||
void imageStats(bool imageStats);
|
void imageStats(bool imageStats);
|
||||||
void peakFinder(bool findPeaks);
|
void peakFinder(bool findPeaks);
|
||||||
void starFinder(bool findStars);
|
void starFinder(bool findStars);
|
||||||
|
void showMarkFilesDialog();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAINWINDOW_H
|
#endif // MAINWINDOW_H
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
#include "markedfiles.h"
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QTableView>
|
||||||
|
#include <QSqlTableModel>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QSqlQuery>
|
||||||
|
|
||||||
|
MarkedFiles::MarkedFiles(QWidget *parent) : QDialog(parent)
|
||||||
|
{
|
||||||
|
setWindowTitle(tr("Marked files"));
|
||||||
|
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||||
|
m_tableView = new QTableView(this);
|
||||||
|
m_tableView->verticalHeader()->setDefaultSectionSize(1);
|
||||||
|
|
||||||
|
QSqlDatabase db = QSqlDatabase::database();
|
||||||
|
m_model = new QSqlTableModel(this, db);
|
||||||
|
|
||||||
|
m_model->setTable("files");
|
||||||
|
m_model->removeColumn(0);
|
||||||
|
m_model->setHeaderData(0, Qt::Horizontal, tr("Filename"));
|
||||||
|
m_model->select();
|
||||||
|
|
||||||
|
m_tableView->setModel(m_model);
|
||||||
|
m_tableView->resizeColumnsToContents();
|
||||||
|
m_tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
|
|
||||||
|
QHBoxLayout *hlayout = new QHBoxLayout;
|
||||||
|
QPushButton *clearSelectedButton = new QPushButton(tr("Clear selected"), this);
|
||||||
|
QPushButton *clearAllButton = new QPushButton(tr("Clear all"), this);
|
||||||
|
|
||||||
|
connect(clearSelectedButton, &QPushButton::pressed, this, &MarkedFiles::clearSelected);
|
||||||
|
connect(clearAllButton, &QPushButton::pressed, this, &MarkedFiles::clearAll);
|
||||||
|
|
||||||
|
layout->addWidget(m_tableView);
|
||||||
|
layout->addLayout(hlayout);
|
||||||
|
hlayout->addWidget(clearSelectedButton);
|
||||||
|
hlayout->addWidget(clearAllButton);
|
||||||
|
|
||||||
|
resize(800, 600);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarkedFiles::clearSelected()
|
||||||
|
{
|
||||||
|
|
||||||
|
QSqlDatabase db = QSqlDatabase::database();
|
||||||
|
QSqlQuery query("DELETE FROM files where file = ?", db);
|
||||||
|
QModelIndexList rows = m_tableView->selectionModel()->selectedRows();
|
||||||
|
QStringList files;
|
||||||
|
for(const QModelIndex &row : rows)
|
||||||
|
{
|
||||||
|
files.append(row.data().toString());
|
||||||
|
}
|
||||||
|
query.bindValue(0, files);
|
||||||
|
query.execBatch();
|
||||||
|
m_model->select();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarkedFiles::clearAll()
|
||||||
|
{
|
||||||
|
QSqlDatabase db = QSqlDatabase::database();
|
||||||
|
db.exec("DELETE FROM files");
|
||||||
|
m_model->select();
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef MARKEDFILES_H
|
||||||
|
#define MARKEDFILES_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QTableView>
|
||||||
|
#include <QSqlTableModel>
|
||||||
|
|
||||||
|
class MarkedFiles : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
QTableView *m_tableView;
|
||||||
|
QSqlTableModel *m_model;
|
||||||
|
public:
|
||||||
|
MarkedFiles(QWidget *parent = nullptr);
|
||||||
|
protected slots:
|
||||||
|
void clearSelected();
|
||||||
|
void clearAll();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MARKEDFILES_H
|
||||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 454 B |
@@ -5,5 +5,5 @@ Icon=org.nou.tenmon
|
|||||||
Comment=FITS Image viewer
|
Comment=FITS Image viewer
|
||||||
Name=Tenmon
|
Name=Tenmon
|
||||||
Categories=Graphics;2DGraphics;RasterGraphics;Viewer;
|
Categories=Graphics;2DGraphics;RasterGraphics;Viewer;
|
||||||
MimeType=image/fits;
|
MimeType=image/fits;image/x-xisf;
|
||||||
Terminal=false
|
Terminal=false
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
@@ -233,6 +233,11 @@ RawImage::ImgType RawImage::type() const
|
|||||||
return CV2Type(m_img.type());
|
return CV2Type(m_img.type());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int RawImage::dataType() const
|
||||||
|
{
|
||||||
|
return m_img.type();
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t RawImage::norm() const
|
uint32_t RawImage::norm() const
|
||||||
{
|
{
|
||||||
switch(m_img.type())
|
switch(m_img.type())
|
||||||
@@ -288,3 +293,8 @@ float RawImage::thumbAspect() const
|
|||||||
{
|
{
|
||||||
return m_thumbAspect;
|
return m_thumbAspect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cv::Mat& RawImage::mat() const
|
||||||
|
{
|
||||||
|
return m_img;
|
||||||
|
}
|
||||||
|
|||||||
@@ -73,11 +73,13 @@ public:
|
|||||||
uint32_t height() const;
|
uint32_t height() const;
|
||||||
uint32_t size() const;
|
uint32_t size() const;
|
||||||
ImgType type() const;
|
ImgType type() const;
|
||||||
|
int dataType() const;
|
||||||
uint32_t norm() const;
|
uint32_t norm() const;
|
||||||
void* data();
|
void* data();
|
||||||
const void* data() const;
|
const void* data() const;
|
||||||
void convertToThumbnail();
|
void convertToThumbnail();
|
||||||
float thumbAspect() const;
|
float thumbAspect() const;
|
||||||
|
const cv::Mat& mat() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RAWIMAGE_H
|
#endif // RAWIMAGE_H
|
||||||
|
|||||||
+16
-1
@@ -6,9 +6,24 @@
|
|||||||
<file>thumb.vert</file>
|
<file>thumb.vert</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="/">
|
<qresource prefix="/">
|
||||||
<file>icon.png</file>
|
|
||||||
<file>invert.png</file>
|
<file>invert.png</file>
|
||||||
<file>nuke.png</file>
|
<file>nuke.png</file>
|
||||||
<file>bayer.png</file>
|
<file>bayer.png</file>
|
||||||
|
<file>org.nou.tenmon.png</file>
|
||||||
|
<file>nuke_a.png</file>
|
||||||
|
<file>about/tenmon</file>
|
||||||
|
<file>about/pcl</file>
|
||||||
|
<file>translations/tenmon_en.qm</file>
|
||||||
|
<file>translations/tenmon_sk.qm</file>
|
||||||
|
<file>about/filter.png</file>
|
||||||
|
<file>about/stretch-panel.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
|
<qresource lang="en" prefix="/">
|
||||||
|
<file alias="help">about/help_en</file>
|
||||||
|
</qresource>
|
||||||
|
<qresource lang="sk" prefix="/">
|
||||||
|
<file alias="help">about/help_sk</file>
|
||||||
|
</qresource>
|
||||||
|
<qresource prefix="/help"/>
|
||||||
|
<qresource prefix="/helpimg"/>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ StretchToolbar::StretchToolbar(QWidget *parent) : QToolBar(tr("Stretch toolbar")
|
|||||||
QAction *superPixelButton = addAction(QIcon(":/bayer.png"), tr("Superpixel CFA draw 2x2 pixel as one"));
|
QAction *superPixelButton = addAction(QIcon(":/bayer.png"), tr("Superpixel CFA draw 2x2 pixel as one"));
|
||||||
superPixelButton->setCheckable(true);
|
superPixelButton->setCheckable(true);
|
||||||
connect(superPixelButton, SIGNAL(toggled(bool)), this, SIGNAL(superPixel(bool)));
|
connect(superPixelButton, SIGNAL(toggled(bool)), this, SIGNAL(superPixel(bool)));
|
||||||
|
|
||||||
|
m_autoStretchOnLoad = addAction(QIcon(":/nuke_a.png"), tr("Apply auto stretch on load"));
|
||||||
|
m_autoStretchOnLoad->setCheckable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StretchToolbar::stretchImage(Image *img)
|
void StretchToolbar::stretchImage(Image *img)
|
||||||
@@ -63,3 +66,10 @@ void StretchToolbar::resetMTF()
|
|||||||
emit paramChanged(0, 0.5, 1);
|
emit paramChanged(0, 0.5, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StretchToolbar::imageLoaded(Image *img)
|
||||||
|
{
|
||||||
|
if(m_autoStretchOnLoad->isChecked())
|
||||||
|
stretchImage(img);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,11 +10,13 @@ class StretchToolbar : public QToolBar
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
STFSlider *m_stfSlider;
|
STFSlider *m_stfSlider;
|
||||||
|
QAction *m_autoStretchOnLoad;
|
||||||
public:
|
public:
|
||||||
explicit StretchToolbar(QWidget *parent = nullptr);
|
explicit StretchToolbar(QWidget *parent = nullptr);
|
||||||
public slots:
|
public slots:
|
||||||
void stretchImage(Image *img);
|
void stretchImage(Image *img);
|
||||||
void resetMTF();
|
void resetMTF();
|
||||||
|
void imageLoaded(Image *img);
|
||||||
signals:
|
signals:
|
||||||
void paramChanged(float low, float mid, float high);
|
void paramChanged(float low, float mid, float high);
|
||||||
void autoStretch();
|
void autoStretch();
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,384 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="en_US" sourcelanguage="en">
|
||||||
|
<context>
|
||||||
|
<name>About</name>
|
||||||
|
<message>
|
||||||
|
<source>About Tenmon</source>
|
||||||
|
<translation>About Tenmon</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>DataBaseView</name>
|
||||||
|
<message>
|
||||||
|
<source>Select columns</source>
|
||||||
|
<translation>Select columns</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Text to search, you can % as wildcard</source>
|
||||||
|
<translation>Text to search, you can % as wildcard</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filter</source>
|
||||||
|
<translation>Filter</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>FITSFileModel</name>
|
||||||
|
<message>
|
||||||
|
<source>File name</source>
|
||||||
|
<translation>File name</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>HelpDialog</name>
|
||||||
|
<message>
|
||||||
|
<source>Help</source>
|
||||||
|
<translation>Help</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>ImageInfo</name>
|
||||||
|
<message>
|
||||||
|
<source>Property</source>
|
||||||
|
<translation>Property</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Value</source>
|
||||||
|
<translation>Value</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Comment</source>
|
||||||
|
<translation>Comment</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>FITS Header</source>
|
||||||
|
<translation>FITS Header</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Image info</source>
|
||||||
|
<translation>Image info</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>ImageRingList</name>
|
||||||
|
<message>
|
||||||
|
<source>Name</source>
|
||||||
|
<translation>Name</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>ImageWidget</name>
|
||||||
|
<message>
|
||||||
|
<source>OpenGL error</source>
|
||||||
|
<translation>OpenGL error</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Could not initialize OpenGL 3.3 context. Ensure that proper GPU driver is installed.</source>
|
||||||
|
<translation>Could not initialize OpenGL 3.3 context. Ensure that proper GPU driver is installed.</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>MainWindow</name>
|
||||||
|
<message>
|
||||||
|
<source>Image info</source>
|
||||||
|
<translation>Image info</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Can't open DB</source>
|
||||||
|
<translation>Can't open DB</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Can't open SQLITE database</source>
|
||||||
|
<translation>Can't open SQLITE database</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filesystem</source>
|
||||||
|
<translation>File system</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>FITS files database</source>
|
||||||
|
<translation type="vanished">FITS files database</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Tenmon</source>
|
||||||
|
<translation>Tenmon</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>File</source>
|
||||||
|
<translation>File</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Open</source>
|
||||||
|
<translation>Open</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Copy marked files</source>
|
||||||
|
<translation>Copy marked files</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Save as</source>
|
||||||
|
<translation>Save as</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Live mode</source>
|
||||||
|
<translation>Live mode</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Exit</source>
|
||||||
|
<translation>Exit</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>View</source>
|
||||||
|
<translation>View</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Zoom In</source>
|
||||||
|
<translation>Zoom In</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Zoom Out</source>
|
||||||
|
<translation>Zoom Out</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Best Fit</source>
|
||||||
|
<translation>Best Fit</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>100%</source>
|
||||||
|
<translation>100%</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Fullscreen</source>
|
||||||
|
<translation>Fullscreen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Select</source>
|
||||||
|
<translation>Select</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mark</source>
|
||||||
|
<translation>Mark</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmark</source>
|
||||||
|
<translation>Unmark</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mark and next</source>
|
||||||
|
<translation>Mark and next</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmark and next</source>
|
||||||
|
<translation>Unmark and next</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Analyze</source>
|
||||||
|
<translation>Analyze</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Image statistics</source>
|
||||||
|
<translation>Image statistics</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Peak finder</source>
|
||||||
|
<translation>Peak finder</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Docks</source>
|
||||||
|
<translation>Docks</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Open file</source>
|
||||||
|
<translation>Open file</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Select destination</source>
|
||||||
|
<translation>Select destination</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Copying</source>
|
||||||
|
<translation>Copying</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Cancel</source>
|
||||||
|
<translation>Cancel</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Move marked files</source>
|
||||||
|
<translation>Move marked files</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Index directory</source>
|
||||||
|
<translation>Index directory</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Thumbnails</source>
|
||||||
|
<translation>Thumbnails</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Show marked</source>
|
||||||
|
<translation>Show marked</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Help</source>
|
||||||
|
<translation>Help</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>About Tenmon</source>
|
||||||
|
<translation>About Tenmon</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>About Qt</source>
|
||||||
|
<translation>About Qt</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Moving</source>
|
||||||
|
<translation>Moving</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Images (*.jpg *.jpeg *.png *.cr2 *.fit *.fits *.xisf *.JPG *.JPEG *.PNG *.CR2 *.FIT *.FITS *.XISF)</source>
|
||||||
|
<translation>Images (*.jpg *.jpeg *.png *.cr2 *.fit *.fits *.xisf *.JPG *.JPEG *.PNG *.CR2 *.FIT *.FITS *.XISF)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Indexing FITS files</source>
|
||||||
|
<translation>Indexing FITS files</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>JPEG (*.jpg *.JPG);; PNG (*.png *.PNG);;FITS (*.fits *.FITS);;XISF (*.xisf *.XISF)</source>
|
||||||
|
<translation>JPEG (*.jpg *.JPG);; PNG (*.png *.PNG);;FITS (*.fits *.FITS);;XISF (*.xisf *.XISF)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Reindex files</source>
|
||||||
|
<translation>Reindex files</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>FITS/XISF files database</source>
|
||||||
|
<translation>FITS/XISF files database</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>MarkedFiles</name>
|
||||||
|
<message>
|
||||||
|
<source>Marked files</source>
|
||||||
|
<translation>Marked files</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filename</source>
|
||||||
|
<translation>File name</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Clear selected</source>
|
||||||
|
<translation>Clear selected</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Clear all</source>
|
||||||
|
<translation>Clear all</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>QObject</name>
|
||||||
|
<message>
|
||||||
|
<source>ISO</source>
|
||||||
|
<translation>ISO</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Shutter speed</source>
|
||||||
|
<translation>Shutter speed</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Width</source>
|
||||||
|
<translation>Width</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Height</source>
|
||||||
|
<translation>Height</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Error</source>
|
||||||
|
<translation>Error</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filename</source>
|
||||||
|
<translation>File name</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mean</source>
|
||||||
|
<translation>Mean</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Standart deviation</source>
|
||||||
|
<translation>Standart deviation</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Median</source>
|
||||||
|
<translation>Median</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Minimum</source>
|
||||||
|
<translation>Minimum</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Maximum</source>
|
||||||
|
<translation>Maximum</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>MAD</source>
|
||||||
|
<translation>MAD</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Peaks</source>
|
||||||
|
<translation>Peaks</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Peaks draw</source>
|
||||||
|
<translation>Peaks draw</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>FWHM X</source>
|
||||||
|
<translation>FWHM X</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>FWHM Y</source>
|
||||||
|
<translation>FWHM Y</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unsupported sample format</source>
|
||||||
|
<translation>Unsupported sample format</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>SelectColumnsDialog</name>
|
||||||
|
<message>
|
||||||
|
<source>Select columns</source>
|
||||||
|
<translation>Select columns</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>StretchToolbar</name>
|
||||||
|
<message>
|
||||||
|
<source>Stretch toolbar</source>
|
||||||
|
<translation>Stretch toolbar</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Auto Stretch F12</source>
|
||||||
|
<translation>Auto Stretch F12</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Reset Screen Transfer Function F11</source>
|
||||||
|
<translation>Reset Screen Transfer Function F11</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Invert colors</source>
|
||||||
|
<translation>Invert colors</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Superpixel CFA draw 2x2 pixel as one</source>
|
||||||
|
<translation>Superpixel CFA draw 2x2 pixel as one</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Apply auto stretch on load</source>
|
||||||
|
<translation>Apply auto stretch on load</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
||||||
Binary file not shown.
@@ -0,0 +1,397 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="sk_SK" sourcelanguage="en">
|
||||||
|
<context>
|
||||||
|
<name>About</name>
|
||||||
|
<message>
|
||||||
|
<source>About Tenmon</source>
|
||||||
|
<translation>O Tenmon</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>DataBaseView</name>
|
||||||
|
<message>
|
||||||
|
<source>Select columns</source>
|
||||||
|
<translation>Vyber stĺpce</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Text to search, you can % as wildcard</source>
|
||||||
|
<translation>Text na vyhľadanie, môžete použit % ako zástupný znak</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filter</source>
|
||||||
|
<translatorcomment>Meno súboru</translatorcomment>
|
||||||
|
<translation>Filter</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>FITSFileModel</name>
|
||||||
|
<message>
|
||||||
|
<source>File name</source>
|
||||||
|
<translation>Meno súboru</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>HelpDialog</name>
|
||||||
|
<message>
|
||||||
|
<source>Help</source>
|
||||||
|
<translation>Pomoc</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>ImageInfo</name>
|
||||||
|
<message>
|
||||||
|
<source>Property</source>
|
||||||
|
<translation>Vlastnosť</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Value</source>
|
||||||
|
<translation>Hodnota</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Comment</source>
|
||||||
|
<translation>Komentár</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>FITS Header</source>
|
||||||
|
<translation>FITS hlavička</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Image info</source>
|
||||||
|
<translation>Informácie o obrázku</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>ImageRingList</name>
|
||||||
|
<message>
|
||||||
|
<source>Name</source>
|
||||||
|
<translation>Meno</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>ImageWidget</name>
|
||||||
|
<message>
|
||||||
|
<source>OpenGL error</source>
|
||||||
|
<translation>OpenGL chyba</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Could not initialize OpenGL 3.3 context. Ensure that proper GPU driver is installed.</source>
|
||||||
|
<translation>Nepodarilo sa incializovať OpenGL 3.3 context. Ubezpečte sa že sú nainštalované ovládače pre GPU.</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>MainWindow</name>
|
||||||
|
<message>
|
||||||
|
<source>Image info</source>
|
||||||
|
<translation>Informácie o obrázku</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Can't open DB</source>
|
||||||
|
<translation>Nie je možné otvoriť DB</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Can't open SQLITE database</source>
|
||||||
|
<translation>Nie je možné otvoriť SQLITE databázu</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filesystem</source>
|
||||||
|
<translation>Zoznam súborov</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>FITS Editor</source>
|
||||||
|
<translation type="vanished">FITS editor</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>FITS files database</source>
|
||||||
|
<translation type="vanished">Databáza FITS súborov</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Tenmon</source>
|
||||||
|
<translation>Tenmon</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>File</source>
|
||||||
|
<translation>Súbor</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Open</source>
|
||||||
|
<translation>Otvoriť</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Copy marked files</source>
|
||||||
|
<translation>Skopírovať označené súbory</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Save as</source>
|
||||||
|
<translation>Uložiť ako</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Exit</source>
|
||||||
|
<translation>Ukončiť</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>View</source>
|
||||||
|
<translation>Zobrazenie</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Zoom In</source>
|
||||||
|
<translation>Priblížiť</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Zoom Out</source>
|
||||||
|
<translation>Oddialiť</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Best Fit</source>
|
||||||
|
<translation>Najlepšia veľkosť</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>100%</source>
|
||||||
|
<translation>100%</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Fullscreen</source>
|
||||||
|
<translation>Celá obrazovka</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Select</source>
|
||||||
|
<translation>Výber</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mark</source>
|
||||||
|
<translation>Označiť</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmark</source>
|
||||||
|
<translation>Odznačiť</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mark and next</source>
|
||||||
|
<translation>Označiť a ďaľší</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmark and next</source>
|
||||||
|
<translation>Odznačiť a ďaľší</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Analyze</source>
|
||||||
|
<translation>Analýza</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Image statistics</source>
|
||||||
|
<translation>Štatistiky obrázka</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Docks</source>
|
||||||
|
<translation>Dokovacie panely</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Open file</source>
|
||||||
|
<translation>Otvoriť súbor</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Images (*.jpg *.jpeg *.png *.cr2 *.fit *.fits *.JPG *.JPEG *.PNG *.CR2 *.FIT *.FITS)</source>
|
||||||
|
<translation type="vanished">Obrázky (*.jpg *.jpeg *.png *.cr2 *.fit *.fits *.JPG *.JPEG *.PNG *.CR2 *.FIT *.FITS)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Images (*.jpg *.png *.JPG *.PNG)</source>
|
||||||
|
<translation type="vanished">Obrázky (*.jpg *.png *.JPG *.PNG)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Select destination</source>
|
||||||
|
<translation>Vybrať cieľ</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Copying</source>
|
||||||
|
<translation>Kopírovanie</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Cancel</source>
|
||||||
|
<translation>Zrušiť</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Move marked files</source>
|
||||||
|
<translation>Presunúť označené súbory</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Index directory</source>
|
||||||
|
<translation>Indexovať adresár</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Live mode</source>
|
||||||
|
<translation>Živý mód</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Thumbnails</source>
|
||||||
|
<translation>Náhľady</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Show marked</source>
|
||||||
|
<translation>Ukázať označené</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Peak finder</source>
|
||||||
|
<translation>Vyhľadávač vrcholov</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Help</source>
|
||||||
|
<translation>Pomoc</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>About Tenmon</source>
|
||||||
|
<translation>O Tenmon</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>About Qt</source>
|
||||||
|
<translation>O Qt</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Moving</source>
|
||||||
|
<translation>Presúvanie</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Images (*.jpg *.jpeg *.png *.cr2 *.fit *.fits *.xisf *.JPG *.JPEG *.PNG *.CR2 *.FIT *.FITS *.XISF)</source>
|
||||||
|
<translation>Obrázky (*.jpg *.jpeg *.png *.cr2 *.fit *.fits *.xisf *.JPG *.JPEG *.PNG *.CR2 *.FIT *.FITS *.XISF)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Indexing FITS files</source>
|
||||||
|
<translation>Indexovanie FITS/XISF súborov</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>JPEG (*.jpg *.JPG);; PNG (*.png *.PNG);;FITS (*.fits *.FITS);;XISF (*.xisf *.XISF)</source>
|
||||||
|
<translation>JPEG (*.jpg *.JPG);; PNG (*.png *.PNG);;FITS (*.fits *.FITS);;XISF (*.xisf *.XISF)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Reindex files</source>
|
||||||
|
<translation>Reindexuj súbory</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>FITS/XISF files database</source>
|
||||||
|
<translation>Databáza FITS/XISF súborov</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>MarkedFiles</name>
|
||||||
|
<message>
|
||||||
|
<source>Marked files</source>
|
||||||
|
<translation>Označené súbory</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filename</source>
|
||||||
|
<translation>Meno súboru</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Clear selected</source>
|
||||||
|
<translation>Zrušiť vybrané</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Clear all</source>
|
||||||
|
<translation>Zrušiť všetky</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>QObject</name>
|
||||||
|
<message>
|
||||||
|
<source>ISO</source>
|
||||||
|
<translation>ISO</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Shutter speed</source>
|
||||||
|
<translation>Rýchlosť uzávierky</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Error</source>
|
||||||
|
<translation>Chyba</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unsupported sample format</source>
|
||||||
|
<translation>Nepodporovaný formát</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Width</source>
|
||||||
|
<translation>Šírka</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Height</source>
|
||||||
|
<translation>Výška</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filename</source>
|
||||||
|
<translation>Meno súboru</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mean</source>
|
||||||
|
<translation>Priemer</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Standart deviation</source>
|
||||||
|
<translation>Štandardná odchýlka</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Median</source>
|
||||||
|
<translation>Medián</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Minimum</source>
|
||||||
|
<translation>Minimum</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Maximum</source>
|
||||||
|
<translation>Maximum</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>MAD</source>
|
||||||
|
<translation>MAD</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Peaks</source>
|
||||||
|
<translation>Vrcholky</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Peaks draw</source>
|
||||||
|
<translation>Vykreslené vrcholky</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>FWHM X</source>
|
||||||
|
<translation>FWHM X</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>FWHM Y</source>
|
||||||
|
<translation>FWHM Y</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>SelectColumnsDialog</name>
|
||||||
|
<message>
|
||||||
|
<source>Select columns</source>
|
||||||
|
<translation>Výber stĺpcov</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>StretchToolbar</name>
|
||||||
|
<message>
|
||||||
|
<source>Stretch toolbar</source>
|
||||||
|
<translation>Panel úrovní</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Auto Stretch F12</source>
|
||||||
|
<translation>Automatické natiahnutie F12</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Reset Screen Transfer Function F11</source>
|
||||||
|
<translation>Resetuj funkciu prevodu na obrazovku F11</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Invert colors</source>
|
||||||
|
<translation>Invertuj farby</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Superpixel CFA draw 2x2 pixel as one</source>
|
||||||
|
<translation>Super pixel CFA kreslenie 2x2 pixelov ako jeden</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Apply auto stretch on load</source>
|
||||||
|
<translation>Aplikuj automatické natiahnutie pri načítaní</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
||||||
Reference in New Issue
Block a user