Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f5cec01c0 | ||
|
|
518371e5c1 | ||
|
|
81cf250862 | ||
|
|
4f64fdc7d5 | ||
|
|
b1f4f2d15f | ||
|
|
0e517799c8 | ||
|
|
2b9290e4d8 | ||
|
|
24f58fa13d | ||
|
|
c10aac922d | ||
|
|
0f286efe4c | ||
|
|
7d3c61c91d | ||
|
|
059b16f08a | ||
|
|
4b23b1f3de | ||
|
|
3350f86ddf | ||
|
|
a2045aa1f6 |
@@ -13,9 +13,13 @@ include_directories(${CMAKE_CURRENT_LIST_DIR}
|
|||||||
Resources/InsaneWidget
|
Resources/InsaneWidget
|
||||||
Resources/Utilities
|
Resources/Utilities
|
||||||
Resources/InsaneWidget/UI
|
Resources/InsaneWidget/UI
|
||||||
|
Resources/StampWidget
|
||||||
|
Resources/StampWidget/UI
|
||||||
|
|
||||||
Resources/UI/S7)
|
Resources/UI/S7)
|
||||||
|
|
||||||
add_subdirectory(Resources/Utilities)
|
add_subdirectory(Resources/Utilities)
|
||||||
|
add_subdirectory(Resources/StampWidget)
|
||||||
add_subdirectory(Resources/InsaneWidget)
|
add_subdirectory(Resources/InsaneWidget)
|
||||||
|
|
||||||
add_executable(s7
|
add_executable(s7
|
||||||
@@ -25,6 +29,6 @@ add_executable(s7
|
|||||||
|
|
||||||
install(TARGETS s7 RUNTIME DESTINATION bin)
|
install(TARGETS s7 RUNTIME DESTINATION bin)
|
||||||
|
|
||||||
target_link_libraries(s7 minutils insanewidget
|
target_link_libraries(s7 insanewidget
|
||||||
${wxWidgets_LIBRARIES}
|
${wxWidgets_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -5,9 +5,10 @@ This is a simple scanning application with these goals:
|
|||||||
- full page scan
|
- full page scan
|
||||||
- known number of pages to scan
|
- known number of pages to scan
|
||||||
- double-sided handling
|
- double-sided handling
|
||||||
- multiple output file format: PNG, JPEG, TIFF, PNM and PDF.
|
- multiple output file format: PNG, JPEG, TIFF, PNM and PDF
|
||||||
|
- apply an optional stamp on each page.
|
||||||
|
|
||||||
It is based on [libinsane](https://gitlab.gnome.org/World/OpenPaperwork/libinsane) and written with [wxWidgets](https://wxwidgets.org).
|
It is based on [libinsane](https://gitlab.gnome.org/World/OpenPaperwork/libinsane) and [wxWidgets](https://wxwidgets.org).
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -22,6 +23,7 @@ Inputs:
|
|||||||
- the scanner and its minimal parameters (source, mode, resolution)
|
- the scanner and its minimal parameters (source, mode, resolution)
|
||||||
- page size
|
- page size
|
||||||
- output file format.
|
- output file format.
|
||||||
|
- an optional stamp text
|
||||||
|
|
||||||
Right click on the 'New' label to specify the number of faces and whether double-sided scanning is needed.
|
Right click on the 'New' label to specify the number of faces and whether double-sided scanning is needed.
|
||||||
|
|
||||||
@@ -29,6 +31,14 @@ Right click on the 'New' label to specify the number of faces and whether double
|
|||||||
|
|
||||||
Right click on the 'Scan' button to set the device properties.
|
Right click on the 'Scan' button to set the device properties.
|
||||||
|
|
||||||
|
'Ctrl - right click' on the 'Scan' button to define stamps.
|
||||||
|
|
||||||
|
Press 'Esc' to cancel and reset a scan project.
|
||||||
|
|
||||||
|
Press 'Ctrl + N' to open a new window.
|
||||||
|
|
||||||
|
Press 'Ctrl + Q' to close a window.
|
||||||
|
|
||||||
Outputs:
|
Outputs:
|
||||||
|
|
||||||
- a single PDF file with the number of requested pages
|
- a single PDF file with the number of requested pages
|
||||||
|
|||||||
@@ -9,25 +9,25 @@ find_package(LibInsane REQUIRED)
|
|||||||
find_package(PoDoFo REQUIRED)
|
find_package(PoDoFo REQUIRED)
|
||||||
find_package(Paper REQUIRED)
|
find_package(Paper REQUIRED)
|
||||||
|
|
||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_LIST_DIR}
|
include_directories(${CMAKE_CURRENT_LIST_DIR}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/UI
|
${CMAKE_CURRENT_LIST_DIR}/UI
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/../StampWidget
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/../StampWidget/UI
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../Utilities)
|
${CMAKE_CURRENT_LIST_DIR}/../Utilities)
|
||||||
|
|
||||||
add_library(insanewidget STATIC
|
add_library(insanewidget STATIC
|
||||||
UI/InsaneWidget.cpp
|
UI/InsaneWidget.cpp
|
||||||
UI/ScannerWidget.cpp
|
UI/ScannerWidget.cpp
|
||||||
|
|
||||||
Common.h
|
DefsInsaneWidget.h
|
||||||
XInsaneWidget.cpp
|
XInsaneWidget.cpp
|
||||||
XScannerWidget.cpp
|
XScannerWidget.cpp
|
||||||
InsaneWorker.cpp
|
InsaneWorker.cpp
|
||||||
PixelToImageWriter.cpp
|
PixelToImageWriter.cpp
|
||||||
PixelToPdfWriter.cpp)
|
PixelToPdfWriter.cpp)
|
||||||
|
|
||||||
target_link_libraries(insanewidget minutils
|
target_link_libraries(insanewidget minutils stampwidget
|
||||||
${wxWidgets_LIBRARIES}
|
${wxWidgets_LIBRARIES}
|
||||||
${LIBINSANE_LIBRARIES}
|
${LIBINSANE_LIBRARIES}
|
||||||
${PODOFO_LIBRARIES}
|
${PODOFO_LIBRARIES}
|
||||||
${NETPBM_LIBRARIES}
|
|
||||||
${PAPER_LIBRARIES})
|
${PAPER_LIBRARIES})
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
// /*
|
// /*
|
||||||
// * File: Common.h
|
// * File: DefsInsaneWidget.h
|
||||||
// * Author: Saleem Edah-Tally - nmset@yandex.com
|
// * Author: Saleem Edah-Tally - nmset@yandex.com
|
||||||
// * License : CeCILL-C
|
// * License : CeCILL-C
|
||||||
// * Copyright Saleem Edah-Tally - © 2025
|
// * Copyright Saleem Edah-Tally - © 2025
|
||||||
// *
|
// *
|
||||||
// * Created on 27 06 2025, 20:34
|
// * Created on 08 07 2025, 20:44
|
||||||
// */
|
// */
|
||||||
|
|
||||||
#ifndef COMMON_H
|
#ifndef DEFSINSANEWIDGET_H
|
||||||
#define COMMON_H
|
#define DEFSINSANEWIDGET_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
@@ -27,4 +27,4 @@ static void UpdateExtensionsMap()
|
|||||||
Extensions[PNM] = "pnm";
|
Extensions[PNM] = "pnm";
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // COMMON_H
|
#endif // DEFSINSANEWIDGET_H
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <paper.h>
|
#include <paper.h>
|
||||||
#include <libinsane/log.h>
|
|
||||||
#include <libinsane/safebet.h>
|
#include <libinsane/safebet.h>
|
||||||
#include <libinsane/error.h>
|
#include <libinsane/error.h>
|
||||||
#include <libinsane/util.h>
|
#include <libinsane/util.h>
|
||||||
@@ -22,8 +21,7 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#define IERR(e) ("[" + to_string(e) + "] " + lis_strerror(e))
|
#define IERR(e) ("[InsaneWorker] - [" + to_string(e) + "] " + lis_strerror(e))
|
||||||
static bool gs_cancelRequested = false;
|
|
||||||
|
|
||||||
InsaneWorker::InsaneWorker ( InsaneWorkerEvent * evh )
|
InsaneWorker::InsaneWorker ( InsaneWorkerEvent * evh )
|
||||||
{
|
{
|
||||||
@@ -273,7 +271,8 @@ bool InsaneWorker::ConfigureDevice(const std::string& deviceId,
|
|||||||
* Sounds weird but needed.
|
* Sounds weird but needed.
|
||||||
*/
|
*/
|
||||||
lis_set_option(m_sourceItem, OPT_NAME_SOURCE, source.c_str());
|
lis_set_option(m_sourceItem, OPT_NAME_SOURCE, source.c_str());
|
||||||
lis_set_option(m_sourceItem, OPT_NAME_RESOLUTION, to_string(resolution).c_str());
|
if (resolution > 0) // No resolution with v4l devices.
|
||||||
|
lis_set_option(m_sourceItem, OPT_NAME_RESOLUTION, to_string(resolution).c_str());
|
||||||
pair<double, double> br;
|
pair<double, double> br;
|
||||||
if (GetBottomRight(br))
|
if (GetBottomRight(br))
|
||||||
{
|
{
|
||||||
@@ -306,6 +305,8 @@ bool InsaneWorker::Scan(const std::string& dir, const std::string& basename,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (m_cancelRequested)
|
||||||
|
return false;
|
||||||
auto makeFileName = [&] (int index)
|
auto makeFileName = [&] (int index)
|
||||||
{
|
{
|
||||||
// std:format is not friendly with a variable padwidth; requires a literal format.
|
// std:format is not friendly with a variable padwidth; requires a literal format.
|
||||||
@@ -375,12 +376,13 @@ bool InsaneWorker::Scan(const std::string& dir, const std::string& basename,
|
|||||||
m_evh->OnPageStartScan(filePath, pageIndex, imageAttributes);
|
m_evh->OnPageStartScan(filePath, pageIndex, imageAttributes);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (gs_cancelRequested)
|
if (m_cancelRequested)
|
||||||
{
|
{
|
||||||
session->cancel(session);
|
session->cancel(session);
|
||||||
|
m_rootSourceItem->close(m_rootSourceItem);
|
||||||
if (m_evh)
|
if (m_evh)
|
||||||
m_evh->OnSessionCancelled(filePath);
|
m_evh->OnSessionCancelled(filePath);
|
||||||
gs_cancelRequested = false;
|
m_cancelRequested = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
@@ -410,7 +412,7 @@ bool InsaneWorker::Scan(const std::string& dir, const std::string& basename,
|
|||||||
catch (std::bad_alloc& e)
|
catch (std::bad_alloc& e)
|
||||||
{
|
{
|
||||||
m_rootSourceItem->close(m_rootSourceItem);
|
m_rootSourceItem->close(m_rootSourceItem);
|
||||||
cout << "ABORT: " << e.what() << " - could not allocate " << bytesPerRow << " bytes." << endl;
|
cerr << "[InsaneWorker] - ABORT: " << e.what() << " - could not allocate " << bytesPerRow << " bytes." << endl;
|
||||||
if (m_evh)
|
if (m_evh)
|
||||||
m_evh->OnError("Insufficient system RAM.");
|
m_evh->OnError("Insufficient system RAM.");
|
||||||
return false;
|
return false;
|
||||||
@@ -451,7 +453,7 @@ bool InsaneWorker::GetBottomRight(std::pair<double, double>& br)
|
|||||||
if (res != PAPER_OK)
|
if (res != PAPER_OK)
|
||||||
{
|
{
|
||||||
const string msg = "Could not initialise the paper library.";
|
const string msg = "Could not initialise the paper library.";
|
||||||
cerr << msg << endl;
|
cerr << "[InsaneWorker] - " << msg << endl;
|
||||||
if (m_evh)
|
if (m_evh)
|
||||||
m_evh->OnError(msg);
|
m_evh->OnError(msg);
|
||||||
return false;
|
return false;
|
||||||
@@ -461,14 +463,14 @@ bool InsaneWorker::GetBottomRight(std::pair<double, double>& br)
|
|||||||
if (!p)
|
if (!p)
|
||||||
{
|
{
|
||||||
string msg = "Failed to find the requested paper; attempt to use a default paper size.";
|
string msg = "Failed to find the requested paper; attempt to use a default paper size.";
|
||||||
cerr << msg << endl;
|
cerr << "[InsaneWorker] - " << msg << endl;
|
||||||
if (m_evh)
|
if (m_evh)
|
||||||
m_evh->OnError(msg);
|
m_evh->OnError(msg);
|
||||||
p = defaultpaper();
|
p = defaultpaper();
|
||||||
if (!p)
|
if (!p)
|
||||||
{
|
{
|
||||||
msg = "Failed to find a default paper size; using the default scanner sizes.";
|
msg = "Failed to find a default paper size; using the default scanner sizes.";
|
||||||
cerr << msg << endl;
|
cerr << "[InsaneWorker] - " << msg << endl;
|
||||||
if (m_evh)
|
if (m_evh)
|
||||||
m_evh->OnError(msg);
|
m_evh->OnError(msg);
|
||||||
return false;
|
return false;
|
||||||
@@ -484,7 +486,7 @@ bool InsaneWorker::GetBottomRight(std::pair<double, double>& br)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
const string msg = "The measurement unit of the paper size is not handled; using the default scanner sizes.";
|
const string msg = "The measurement unit of the paper size is not handled; using the default scanner sizes.";
|
||||||
cerr << msg << endl;
|
cerr << "[InsaneWorker] - " << msg << endl;
|
||||||
if (m_evh)
|
if (m_evh)
|
||||||
m_evh->OnError(msg);
|
m_evh->OnError(msg);
|
||||||
return false;
|
return false;
|
||||||
@@ -497,7 +499,7 @@ bool InsaneWorker::GetBottomRight(std::pair<double, double>& br)
|
|||||||
if (res != PAPER_OK)
|
if (res != PAPER_OK)
|
||||||
{
|
{
|
||||||
const string msg = "Could not cleanly end the paper library.";
|
const string msg = "Could not cleanly end the paper library.";
|
||||||
cerr << msg << endl;
|
cerr << "[InsaneWorker] - " << msg << endl;
|
||||||
if (m_evh)
|
if (m_evh)
|
||||||
m_evh->OnError(msg);
|
m_evh->OnError(msg);
|
||||||
}
|
}
|
||||||
@@ -516,7 +518,7 @@ std::string InsaneWorker::ToLower(const std::string& input)
|
|||||||
|
|
||||||
void InsaneWorker::Cancel()
|
void InsaneWorker::Cancel()
|
||||||
{
|
{
|
||||||
gs_cancelRequested = true;
|
m_cancelRequested = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<int, int> InsaneWorker::UpdateStartAndIncrement(const int startPageIndex, const int increment,
|
std::pair<int, int> InsaneWorker::UpdateStartAndIncrement(const int startPageIndex, const int increment,
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ private:
|
|||||||
lis_item * m_sourceItem = nullptr;
|
lis_item * m_sourceItem = nullptr;
|
||||||
InsaneWorkerEvent * m_evh = nullptr;
|
InsaneWorkerEvent * m_evh = nullptr;
|
||||||
|
|
||||||
|
bool m_cancelRequested = false;
|
||||||
std::vector<DeviceDescriptor> m_devices;
|
std::vector<DeviceDescriptor> m_devices;
|
||||||
std::string m_deviceId;
|
std::string m_deviceId;
|
||||||
std::string m_source = "FlatBed";
|
std::string m_source = "FlatBed";
|
||||||
|
|||||||
@@ -8,14 +8,17 @@
|
|||||||
// */
|
// */
|
||||||
|
|
||||||
#include "PixelToImageWriter.h"
|
#include "PixelToImageWriter.h"
|
||||||
#include <Common.h>
|
#include <StampWorker.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <DefsInsaneWidget.h>
|
||||||
|
#include <DefsStampWidget.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
bool PixelToImageWriter::Convert(const std::string& pixelFilePath,
|
bool PixelToImageWriter::Convert(const std::string& pixelFilePath,
|
||||||
int imageWidth, int imageHeight,
|
int imageWidth, int imageHeight,
|
||||||
int outputFormat, wxImage * image)
|
std::vector<StampDescriptor*> * descriptors,
|
||||||
|
int outputFormat, wxImage * image)
|
||||||
{
|
{
|
||||||
UpdateExtensionsMap();
|
UpdateExtensionsMap();
|
||||||
wxImage * outImage = image;
|
wxImage * outImage = image;
|
||||||
@@ -35,6 +38,16 @@ bool PixelToImageWriter::Convert(const std::string& pixelFilePath,
|
|||||||
raw.assign(istreambuf_iterator<char>(ifs), istreambuf_iterator<char>());
|
raw.assign(istreambuf_iterator<char>(ifs), istreambuf_iterator<char>());
|
||||||
|
|
||||||
outImage->SetData((unsigned char*) raw.data(), imageWidth, imageHeight, true); // true +++
|
outImage->SetData((unsigned char*) raw.data(), imageWidth, imageHeight, true); // true +++
|
||||||
|
if (descriptors)
|
||||||
|
{
|
||||||
|
for (StampDescriptor * descriptor : *descriptors)
|
||||||
|
{
|
||||||
|
if (descriptor)
|
||||||
|
{
|
||||||
|
StampWorker::StampBackground(*outImage, descriptor->image, descriptor->location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (outputFormat)
|
switch (outputFormat)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,19 +10,26 @@
|
|||||||
#ifndef PIXELTOIMAGEWRITER_H
|
#ifndef PIXELTOIMAGEWRITER_H
|
||||||
#define PIXELTOIMAGEWRITER_H
|
#define PIXELTOIMAGEWRITER_H
|
||||||
|
|
||||||
#include "Common.h"
|
#include "DefsInsaneWidget.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include <wx/wx.h>
|
#include <wx/wx.h>
|
||||||
|
|
||||||
|
struct StampDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an image file from a raw scanned file.\n
|
* Create an image file from a raw scanned file.\n
|
||||||
|
* Optionally,\n
|
||||||
|
* - use an wxImage object from the application\n
|
||||||
|
* - blend a stamp image on the converted image.\n
|
||||||
*/
|
*/
|
||||||
class PixelToImageWriter
|
class PixelToImageWriter
|
||||||
{
|
{
|
||||||
|
DECLARE_DYNAMIC_CLASS( PixelToImageWriter )
|
||||||
public:
|
public:
|
||||||
static bool Convert(const std::string& pixelFilePath,
|
static bool Convert(const std::string& pixelFilePath,
|
||||||
int imageWidth, int imageHeight, int outputFormat = PNG,
|
int imageWidth, int imageHeight, std::vector<StampDescriptor*> * descriptors,
|
||||||
wxImage * image = nullptr);
|
int outputFormat = PNG, wxImage * image = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PIXELTOIMAGEWRITER_H
|
#endif // PIXELTOIMAGEWRITER_H
|
||||||
|
|||||||
@@ -9,7 +9,11 @@
|
|||||||
|
|
||||||
#include "PixelToPdfWriter.h"
|
#include "PixelToPdfWriter.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <StampWorker.h>
|
||||||
|
#include <DefsInsaneWidget.h>
|
||||||
|
#include <DefsStampWidget.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace PoDoFo;
|
using namespace PoDoFo;
|
||||||
@@ -29,8 +33,9 @@ PixelToPdfWriter::PixelToPdfWriter()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PixelToPdfWriter::AddPageAt(const std::string& pixelFile, uint width, uint height, uint index,
|
bool PixelToPdfWriter::AddPageAt(const std::string& pixelFile, uint width, uint height, uint index,
|
||||||
PoDoFo::PdfPageSize pageSize, PoDoFo::PdfColorSpace)
|
std::vector<StampDescriptor*> * descriptors,
|
||||||
|
PoDoFo::PdfPageSize pageSize, PoDoFo::PdfColorSpace)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -46,6 +51,23 @@ bool PixelToPdfWriter::AddPageAt(const std::string& pixelFile, uint width, uint
|
|||||||
ifstream ifs(pixelFile, ios::binary);
|
ifstream ifs(pixelFile, ios::binary);
|
||||||
string content;
|
string content;
|
||||||
content.assign(istreambuf_iterator<char>(ifs), istreambuf_iterator<char>());
|
content.assign(istreambuf_iterator<char>(ifs), istreambuf_iterator<char>());
|
||||||
|
if (descriptors)
|
||||||
|
{
|
||||||
|
for (StampDescriptor * descriptor : *descriptors)
|
||||||
|
{
|
||||||
|
if (!descriptor)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
wxImage background;
|
||||||
|
background.SetData(reinterpret_cast<unsigned char*> (content.data()), width, height, true);
|
||||||
|
StampWorker::StampBackground(background, descriptor->image, descriptor->location);
|
||||||
|
stringstream ssStamped;
|
||||||
|
ssStamped.write((const char*) (background.GetData()), width * height * 3);
|
||||||
|
ssStamped.flush();
|
||||||
|
content.clear();
|
||||||
|
content = ssStamped.str();
|
||||||
|
}
|
||||||
|
}
|
||||||
bufferview bv(content);
|
bufferview bv(content);
|
||||||
|
|
||||||
const uint pageNumber = m_doc.GetPages().GetCount();
|
const uint pageNumber = m_doc.GetPages().GetCount();
|
||||||
|
|||||||
@@ -12,13 +12,18 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
#include <podofo/podofo.h>
|
#include <podofo/podofo.h>
|
||||||
|
#include <wx/wx.h>
|
||||||
|
|
||||||
|
struct StampDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a PDF document, append or insert pages from raw scanned files.\n
|
* Create a PDF document, append or insert pages from raw scanned files.\n
|
||||||
* Each image is a full page scan; it is scaled in the PDF document to the full
|
* Each image is a full page scan; it is scaled in the PDF document to the full
|
||||||
* page dimensions.\n
|
* page dimensions.\n
|
||||||
* Account for page size.
|
* Account for page size.\n
|
||||||
|
* Optionally, a stamp image may be blended on the page.
|
||||||
*/
|
*/
|
||||||
class PixelToPdfWriter
|
class PixelToPdfWriter
|
||||||
{
|
{
|
||||||
@@ -27,6 +32,7 @@ public:
|
|||||||
|
|
||||||
PixelToPdfWriter();
|
PixelToPdfWriter();
|
||||||
bool AddPageAt(const std::string& pixelFile, uint width, uint height, uint index,
|
bool AddPageAt(const std::string& pixelFile, uint width, uint height, uint index,
|
||||||
|
std::vector<StampDescriptor*> * descriptors,
|
||||||
PoDoFo::PdfPageSize pageSize = PoDoFo::PdfPageSize::A4,
|
PoDoFo::PdfPageSize pageSize = PoDoFo::PdfPageSize::A4,
|
||||||
PoDoFo::PdfColorSpace = PoDoFo::PdfColorSpace::DeviceRGB /*Unused*/);
|
PoDoFo::PdfColorSpace = PoDoFo::PdfColorSpace::DeviceRGB /*Unused*/);
|
||||||
void Save(const std::string& pdfFile);
|
void Save(const std::string& pdfFile);
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ InsaneWidget::~InsaneWidget()
|
|||||||
void InsaneWidget::Init()
|
void InsaneWidget::Init()
|
||||||
{
|
{
|
||||||
////@begin InsaneWidget member initialisation
|
////@begin InsaneWidget member initialisation
|
||||||
|
szInsaneWidgetMain = NULL;
|
||||||
lblNewDoc = NULL;
|
lblNewDoc = NULL;
|
||||||
txtNewDoc = NULL;
|
txtNewDoc = NULL;
|
||||||
btnScan = NULL;
|
btnScan = NULL;
|
||||||
@@ -119,11 +120,11 @@ void InsaneWidget::CreateControls()
|
|||||||
////@begin InsaneWidget content construction
|
////@begin InsaneWidget content construction
|
||||||
InsaneWidget* itemPanel1 = this;
|
InsaneWidget* itemPanel1 = this;
|
||||||
|
|
||||||
wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
|
szInsaneWidgetMain = new wxBoxSizer(wxVERTICAL);
|
||||||
itemPanel1->SetSizer(itemBoxSizer2);
|
itemPanel1->SetSizer(szInsaneWidgetMain);
|
||||||
|
|
||||||
wxBoxSizer* itemBoxSizer1 = new wxBoxSizer(wxHORIZONTAL);
|
wxBoxSizer* itemBoxSizer1 = new wxBoxSizer(wxHORIZONTAL);
|
||||||
itemBoxSizer2->Add(itemBoxSizer1, 0, wxGROW|wxALL, 5);
|
szInsaneWidgetMain->Add(itemBoxSizer1, 0, wxGROW|wxALL, 5);
|
||||||
|
|
||||||
lblNewDoc = new wxStaticText( itemPanel1, ID_NewDoc_LBL, _("New"), wxDefaultPosition, wxDefaultSize, 0 );
|
lblNewDoc = new wxStaticText( itemPanel1, ID_NewDoc_LBL, _("New"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
if (InsaneWidget::ShowToolTips())
|
if (InsaneWidget::ShowToolTips())
|
||||||
@@ -137,7 +138,7 @@ void InsaneWidget::CreateControls()
|
|||||||
|
|
||||||
btnScan = new wxButton( itemPanel1, ID_Scan_BTN, _("Scan"), wxDefaultPosition, wxDefaultSize, 0 );
|
btnScan = new wxButton( itemPanel1, ID_Scan_BTN, _("Scan"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
if (InsaneWidget::ShowToolTips())
|
if (InsaneWidget::ShowToolTips())
|
||||||
btnScan->SetToolTip(_("'Left click' to start the scan project.\n'Right click' to show the scanner widget."));
|
btnScan->SetToolTip(_("'Left click' to start the scan project.\n'Right click' to show the scanner widget.\n'Ctrl + Right click' to show the Stamp dialog."));
|
||||||
itemBoxSizer1->Add(btnScan, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
itemBoxSizer1->Add(btnScan, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||||
|
|
||||||
////@end InsaneWidget content construction
|
////@end InsaneWidget content construction
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
////@begin forward declarations
|
////@begin forward declarations
|
||||||
|
class wxBoxSizer;
|
||||||
////@end forward declarations
|
////@end forward declarations
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -39,7 +40,7 @@
|
|||||||
#define SYMBOL_INSANEWIDGET_STYLE wxTAB_TRAVERSAL
|
#define SYMBOL_INSANEWIDGET_STYLE wxTAB_TRAVERSAL
|
||||||
#define SYMBOL_INSANEWIDGET_TITLE _("InsaneWidget")
|
#define SYMBOL_INSANEWIDGET_TITLE _("InsaneWidget")
|
||||||
#define SYMBOL_INSANEWIDGET_IDNAME ID_INSANEWIDGET
|
#define SYMBOL_INSANEWIDGET_IDNAME ID_INSANEWIDGET
|
||||||
#define SYMBOL_INSANEWIDGET_SIZE wxSize(400, 300)
|
#define SYMBOL_INSANEWIDGET_SIZE wxDefaultSize
|
||||||
#define SYMBOL_INSANEWIDGET_POSITION wxDefaultPosition
|
#define SYMBOL_INSANEWIDGET_POSITION wxDefaultPosition
|
||||||
////@end control identifiers
|
////@end control identifiers
|
||||||
|
|
||||||
@@ -87,6 +88,7 @@ public:
|
|||||||
static bool ShowToolTips();
|
static bool ShowToolTips();
|
||||||
|
|
||||||
////@begin InsaneWidget member variables
|
////@begin InsaneWidget member variables
|
||||||
|
wxBoxSizer* szInsaneWidgetMain;
|
||||||
wxStaticText* lblNewDoc;
|
wxStaticText* lblNewDoc;
|
||||||
wxTextCtrl* txtNewDoc;
|
wxTextCtrl* txtNewDoc;
|
||||||
wxButton* btnScan;
|
wxButton* btnScan;
|
||||||
|
|||||||
@@ -245,7 +245,7 @@
|
|||||||
<string name="proxy-Font">""</string>
|
<string name="proxy-Font">""</string>
|
||||||
<string name="proxy-Foreground colour">""</string>
|
<string name="proxy-Foreground colour">""</string>
|
||||||
<string name="proxy-Header filename">"InsaneWidget.h"</string>
|
<string name="proxy-Header filename">"InsaneWidget.h"</string>
|
||||||
<long name="proxy-Height">300</long>
|
<long name="proxy-Height">-1</long>
|
||||||
<string name="proxy-Help text">""</string>
|
<string name="proxy-Help text">""</string>
|
||||||
<bool name="proxy-Hidden">0</bool>
|
<bool name="proxy-Hidden">0</bool>
|
||||||
<string name="proxy-Icon">""</string>
|
<string name="proxy-Icon">""</string>
|
||||||
@@ -257,7 +257,7 @@
|
|||||||
<string name="proxy-Texture style">"Tiled"</string>
|
<string name="proxy-Texture style">"Tiled"</string>
|
||||||
<string name="proxy-Title">"InsaneWidget"</string>
|
<string name="proxy-Title">"InsaneWidget"</string>
|
||||||
<string name="proxy-Tooltip text">""</string>
|
<string name="proxy-Tooltip text">""</string>
|
||||||
<long name="proxy-Width">400</long>
|
<long name="proxy-Width">-1</long>
|
||||||
<string name="proxy-Window kind">"wxPanel"</string>
|
<string name="proxy-Window kind">"wxPanel"</string>
|
||||||
<bool name="proxy-wxBORDER_THEME">0</bool>
|
<bool name="proxy-wxBORDER_THEME">0</bool>
|
||||||
<bool name="proxy-wxCAPTION">0</bool>
|
<bool name="proxy-wxCAPTION">0</bool>
|
||||||
@@ -303,13 +303,21 @@
|
|||||||
<long name="is-transient">0</long>
|
<long name="is-transient">0</long>
|
||||||
<long name="locked">0</long>
|
<long name="locked">0</long>
|
||||||
<long name="owns-file">1</long>
|
<long name="owns-file">1</long>
|
||||||
<string name="proxy-Member variable name">""</string>
|
<string name="proxy-AlignH">"Centre"</string>
|
||||||
|
<string name="proxy-AlignV">"Centre"</string>
|
||||||
|
<long name="proxy-Border">5</long>
|
||||||
|
<string name="proxy-Member variable name">"szInsaneWidgetMain"</string>
|
||||||
<string name="proxy-Orientation">"Vertical"</string>
|
<string name="proxy-Orientation">"Vertical"</string>
|
||||||
<string name="proxy-Platform">"<Any platform>"</string>
|
<string name="proxy-Platform">"<Any platform>"</string>
|
||||||
|
<long name="proxy-Stretch factor">0</long>
|
||||||
<bool name="proxy-wxADJUST_MINSIZE">0</bool>
|
<bool name="proxy-wxADJUST_MINSIZE">0</bool>
|
||||||
|
<bool name="proxy-wxBOTTOM">1</bool>
|
||||||
<bool name="proxy-wxFIXED_MINSIZE">0</bool>
|
<bool name="proxy-wxFIXED_MINSIZE">0</bool>
|
||||||
|
<bool name="proxy-wxLEFT">1</bool>
|
||||||
<bool name="proxy-wxRESERVE_SPACE_EVEN_IF_HIDDEN">0</bool>
|
<bool name="proxy-wxRESERVE_SPACE_EVEN_IF_HIDDEN">0</bool>
|
||||||
|
<bool name="proxy-wxRIGHT">1</bool>
|
||||||
<bool name="proxy-wxSHAPED">0</bool>
|
<bool name="proxy-wxSHAPED">0</bool>
|
||||||
|
<bool name="proxy-wxTOP">1</bool>
|
||||||
<string name="title">"wxBoxSizer V"</string>
|
<string name="title">"wxBoxSizer V"</string>
|
||||||
<long name="title-mode">0</long>
|
<long name="title-mode">0</long>
|
||||||
<string name="type">"dialog-control-document"</string>
|
<string name="type">"dialog-control-document"</string>
|
||||||
@@ -538,7 +546,8 @@
|
|||||||
<bool name="proxy-Separate files">0</bool>
|
<bool name="proxy-Separate files">0</bool>
|
||||||
<long name="proxy-Stretch factor">0</long>
|
<long name="proxy-Stretch factor">0</long>
|
||||||
<string name="proxy-Tooltip text">"'Left click' to start the scan project.
|
<string name="proxy-Tooltip text">"'Left click' to start the scan project.
|
||||||
'Right click' to show the scanner widget."</string>
|
'Right click' to show the scanner widget.
|
||||||
|
'Ctrl + Right click' to show the Stamp dialog."</string>
|
||||||
<long name="proxy-Width">-1</long>
|
<long name="proxy-Width">-1</long>
|
||||||
<bool name="proxy-wxADJUST_MINSIZE">0</bool>
|
<bool name="proxy-wxADJUST_MINSIZE">0</bool>
|
||||||
<bool name="proxy-wxBOTTOM">1</bool>
|
<bool name="proxy-wxBOTTOM">1</bool>
|
||||||
@@ -654,13 +663,21 @@
|
|||||||
<long name="is-transient">0</long>
|
<long name="is-transient">0</long>
|
||||||
<long name="locked">0</long>
|
<long name="locked">0</long>
|
||||||
<long name="owns-file">1</long>
|
<long name="owns-file">1</long>
|
||||||
|
<string name="proxy-AlignH">"Centre"</string>
|
||||||
|
<string name="proxy-AlignV">"Centre"</string>
|
||||||
|
<long name="proxy-Border">5</long>
|
||||||
<string name="proxy-Member variable name">""</string>
|
<string name="proxy-Member variable name">""</string>
|
||||||
<string name="proxy-Orientation">"Vertical"</string>
|
<string name="proxy-Orientation">"Vertical"</string>
|
||||||
<string name="proxy-Platform">"<Any platform>"</string>
|
<string name="proxy-Platform">"<Any platform>"</string>
|
||||||
|
<long name="proxy-Stretch factor">0</long>
|
||||||
<bool name="proxy-wxADJUST_MINSIZE">0</bool>
|
<bool name="proxy-wxADJUST_MINSIZE">0</bool>
|
||||||
|
<bool name="proxy-wxBOTTOM">1</bool>
|
||||||
<bool name="proxy-wxFIXED_MINSIZE">0</bool>
|
<bool name="proxy-wxFIXED_MINSIZE">0</bool>
|
||||||
|
<bool name="proxy-wxLEFT">1</bool>
|
||||||
<bool name="proxy-wxRESERVE_SPACE_EVEN_IF_HIDDEN">0</bool>
|
<bool name="proxy-wxRESERVE_SPACE_EVEN_IF_HIDDEN">0</bool>
|
||||||
|
<bool name="proxy-wxRIGHT">1</bool>
|
||||||
<bool name="proxy-wxSHAPED">0</bool>
|
<bool name="proxy-wxSHAPED">0</bool>
|
||||||
|
<bool name="proxy-wxTOP">1</bool>
|
||||||
<string name="title">"wxBoxSizer V"</string>
|
<string name="title">"wxBoxSizer V"</string>
|
||||||
<long name="title-mode">0</long>
|
<long name="title-mode">0</long>
|
||||||
<string name="type">"dialog-control-document"</string>
|
<string name="type">"dialog-control-document"</string>
|
||||||
|
|||||||
@@ -12,7 +12,10 @@
|
|||||||
#include <MiscTools.h>
|
#include <MiscTools.h>
|
||||||
#include "PixelToImageWriter.h"
|
#include "PixelToImageWriter.h"
|
||||||
#include "PixelToPdfWriter.h"
|
#include "PixelToPdfWriter.h"
|
||||||
#include <Common.h>
|
#include <DefsInsaneWidget.h>
|
||||||
|
#include <DefsStampWidget.h>
|
||||||
|
#include <XStampWidget.h>
|
||||||
|
#include <StampWorker.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -37,6 +40,45 @@ private:
|
|||||||
wxWeakRef<XInsaneWidget> m_owner = nullptr;
|
wxWeakRef<XInsaneWidget> m_owner = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
class BackgroundScan : public wxThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BackgroundScan(XInsaneWidget * insaneWidget, InsaneWorker * insaneWorker,
|
||||||
|
const wxString& dir, const wxString& basename,
|
||||||
|
int start = 0, int padWidth = 2, int increment = 1)
|
||||||
|
{
|
||||||
|
m_insaneWidget = insaneWidget;
|
||||||
|
m_insaneWorker = insaneWorker;
|
||||||
|
m_dir = dir;
|
||||||
|
m_basename = basename;
|
||||||
|
m_start = start;
|
||||||
|
m_padWidth = padWidth;
|
||||||
|
m_increment = increment;
|
||||||
|
}
|
||||||
|
ExitCode Entry() override
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We refrain from using a mutex/critical section.
|
||||||
|
* If 2 instances of XInsaneWidget in a single application scan on the same
|
||||||
|
* device simultaneously, the first one that starts scanning prevails and
|
||||||
|
* the second one triggers a "Device busy" error.
|
||||||
|
* If 2 instances of XInsaneWidget in a single application scan on different
|
||||||
|
* devices simultaneously, both jobs succeed.
|
||||||
|
* Since there cannot be concurrency leading to a crash ('Device busy'), we
|
||||||
|
* do not block the next line. It may limit an application that needs to
|
||||||
|
* scan from multiple devices.
|
||||||
|
*/
|
||||||
|
m_insaneWorker->Scan(m_dir.ToStdString(), m_basename.ToStdString(), m_start, m_padWidth, m_increment);
|
||||||
|
return (ExitCode) 0;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
wxWeakRef<XInsaneWidget> m_insaneWidget = nullptr;
|
||||||
|
InsaneWorker * m_insaneWorker = nullptr;
|
||||||
|
wxString m_dir, m_basename;
|
||||||
|
int m_start = 0, m_padWidth = 2, m_increment = 1;
|
||||||
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
class ScanProjectHandler : public InsaneWorkerEvent
|
class ScanProjectHandler : public InsaneWorkerEvent
|
||||||
{
|
{
|
||||||
@@ -46,13 +88,16 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* mode, outputType, adf, doubleSided, total, PaperSize:
|
* mode, resolution, outputType, adf, doubleSided, total, PaperSize:
|
||||||
* These are not updated here if there are pending jobs.
|
* These are not updated here if there are pending jobs.
|
||||||
* However,
|
* However,
|
||||||
* deviceId, source, sourceIndex, mode, resolution, paperSize
|
* deviceId, source, sourceIndex, mode, resolution, paperSize
|
||||||
* can be changed if there are pending jobs in ConfigureDevice() since it is
|
* can be changed if there are pending jobs in ConfigureDevice() since it is
|
||||||
* called before these setters. They won't change on their own but by user
|
* called before these setters. They won't change on their own but by user
|
||||||
* interaction.
|
* interaction.
|
||||||
|
* The 'resolution' variable is used downstream to distinguish between v4l
|
||||||
|
* and real scanners. v4l devices do not have a source and a resolution
|
||||||
|
* tunables.
|
||||||
*/
|
*/
|
||||||
void SetMode(const string& mode)
|
void SetMode(const string& mode)
|
||||||
{
|
{
|
||||||
@@ -60,6 +105,12 @@ public:
|
|||||||
return;
|
return;
|
||||||
m_mode = mode;
|
m_mode = mode;
|
||||||
}
|
}
|
||||||
|
void SetResolution(int resolution)
|
||||||
|
{
|
||||||
|
if (m_pixelFiles.size())
|
||||||
|
return;
|
||||||
|
m_resolution = resolution;
|
||||||
|
}
|
||||||
void SetOutputType(int outputType)
|
void SetOutputType(int outputType)
|
||||||
{
|
{
|
||||||
if (m_pixelFiles.size())
|
if (m_pixelFiles.size())
|
||||||
@@ -101,6 +152,45 @@ public:
|
|||||||
return;
|
return;
|
||||||
m_paperSize = paperSize;
|
m_paperSize = paperSize;
|
||||||
}
|
}
|
||||||
|
void SetStampDescriptors(vector<StampDescriptor*> * descriptors)
|
||||||
|
{
|
||||||
|
m_stampDescriptors = descriptors;
|
||||||
|
}
|
||||||
|
// WIP means InsaneWorker is busy, not the position in a scan project.
|
||||||
|
void SetWip(bool wip)
|
||||||
|
{
|
||||||
|
m_wip = wip;
|
||||||
|
}
|
||||||
|
bool GetWip() const
|
||||||
|
{
|
||||||
|
return m_wip;
|
||||||
|
}
|
||||||
|
/* Enable/disable the label and destination file controls per scanning and
|
||||||
|
* idle mode.
|
||||||
|
* Do not include in Reset() because the status of the scan button is
|
||||||
|
* independent of the rest.
|
||||||
|
*/
|
||||||
|
void UpdateControlsStatus(bool enable)
|
||||||
|
{
|
||||||
|
wxTheApp->CallAfter([this, enable] ()
|
||||||
|
{
|
||||||
|
m_owner->lblNewDoc->Enable(enable);
|
||||||
|
m_owner->txtNewDoc->Enable(enable);
|
||||||
|
if (enable)
|
||||||
|
{
|
||||||
|
m_owner->btnScan->Enable(enable);
|
||||||
|
m_owner->btnScan->SetLabelText(_("Scan"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*Only XInsaneWidget::Setup() and XInsaneWidget::CancelScanning()
|
||||||
|
* disable the scan button.
|
||||||
|
*/
|
||||||
|
m_owner->btnScan->SetLabelText(_("Cancel"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
std::pair<int, int> GetStartAndIncrement(InsaneWorker * insaneWorker)
|
std::pair<int, int> GetStartAndIncrement(InsaneWorker * insaneWorker)
|
||||||
{
|
{
|
||||||
wxASSERT_MSG(insaneWorker != nullptr, "insaneWorker is NULL.");
|
wxASSERT_MSG(insaneWorker != nullptr, "insaneWorker is NULL.");
|
||||||
@@ -114,26 +204,35 @@ public:
|
|||||||
{
|
{
|
||||||
cerr << message << endl;
|
cerr << message << endl;
|
||||||
Reset();
|
Reset();
|
||||||
MiscTools::MessageBox(_("A scan library error occurred."), true);
|
UpdateControlsStatus(true);
|
||||||
|
const wxString msg = _("A scan library error occurred.");
|
||||||
|
MiscTools::AsyncMessageBox(msg, true);
|
||||||
}
|
}
|
||||||
void OnError ( const std::string& message ) override
|
void OnError ( const std::string& message ) override
|
||||||
{
|
{
|
||||||
cerr << message << endl;
|
cerr << message << endl;
|
||||||
Reset();
|
Reset();
|
||||||
MiscTools::MessageBox(_("A general error occurred."), true);
|
UpdateControlsStatus(true);
|
||||||
|
const wxString msg = _("A general error occurred.");
|
||||||
|
MiscTools::AsyncMessageBox(msg, true);
|
||||||
}
|
}
|
||||||
void OnSessionReadError(const std::string & filePath) override
|
void OnSessionReadError(const std::string & filePath) override
|
||||||
{
|
{
|
||||||
const wxString msg = _("A session read error occurred.");
|
const wxString msg = _("A session read error occurred.");
|
||||||
cerr << msg << endl;
|
cerr << msg << endl;
|
||||||
Reset();
|
Reset();
|
||||||
MiscTools::MessageBox(msg, true);
|
UpdateControlsStatus(true);
|
||||||
|
MiscTools::AsyncMessageBox(msg, true);
|
||||||
}
|
}
|
||||||
void OnSessionCancelled(const std::string & filePath) override
|
void OnSessionCancelled(const std::string & filePath) override
|
||||||
{
|
{
|
||||||
const wxString msg = _("Session cancelled.");
|
if (wxFileExists(filePath))
|
||||||
|
wxRemoveFile(filePath);
|
||||||
Reset();
|
Reset();
|
||||||
MiscTools::MessageBox(msg, true);
|
UpdateControlsStatus(true);
|
||||||
|
const wxString msg = _("Session cancelled.");
|
||||||
|
MiscTools::AsyncMessageBox(msg, true);
|
||||||
|
m_sb->CallAfter(&TimeredStatusBar::SetTransientText, msg, 3000);
|
||||||
}
|
}
|
||||||
// Every time a page is fully scanned.
|
// Every time a page is fully scanned.
|
||||||
void OnPageEndScan(const std::string & filePath, uint pageIndex,
|
void OnPageEndScan(const std::string & filePath, uint pageIndex,
|
||||||
@@ -142,7 +241,7 @@ public:
|
|||||||
m_startPageIndex = pageIndex;
|
m_startPageIndex = pageIndex;
|
||||||
m_pixelFiles[pageIndex] = {filePath, imageAttributes};
|
m_pixelFiles[pageIndex] = {filePath, imageAttributes};
|
||||||
|
|
||||||
auto informProgress = [&] ()
|
auto informProgress = [this] ()
|
||||||
{
|
{
|
||||||
if (!m_sb || (m_total == 1))
|
if (!m_sb || (m_total == 1))
|
||||||
return;
|
return;
|
||||||
@@ -159,19 +258,19 @@ public:
|
|||||||
wxString upperBoundMessage = _(". Turn the whole stack of pages.");
|
wxString upperBoundMessage = _(". Turn the whole stack of pages.");
|
||||||
msg += upperBoundMessage;
|
msg += upperBoundMessage;
|
||||||
}
|
}
|
||||||
|
m_sb->CallAfter(&wxStatusBar::SetStatusText, msg, 0);
|
||||||
m_sb->SetStatusText(msg);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (m_outputType != PDF)
|
if (m_outputType != PDF)
|
||||||
{
|
{
|
||||||
// Convert pixel file to PNG using netpbm.
|
// Convert pixel file to PNG using wxImage.
|
||||||
if (!PixelToImageWriter::Convert(filePath, imageAttributes.width, imageAttributes.height, m_outputType))
|
if (!PixelToImageWriter::Convert(filePath, imageAttributes.width, imageAttributes.height,
|
||||||
|
m_stampDescriptors, m_outputType))
|
||||||
{
|
{
|
||||||
const wxString msg = _("Failed to create output image.");
|
const wxString msg = _("Failed to create output image.");
|
||||||
cerr << msg << endl;
|
cerr << msg << endl;
|
||||||
if (m_sb)
|
if (m_sb)
|
||||||
m_sb->SetTransientText(msg);
|
m_sb->CallAfter(&TimeredStatusBar::SetTransientText, msg, 3000);
|
||||||
}
|
}
|
||||||
wxRemoveFile(filePath);
|
wxRemoveFile(filePath);
|
||||||
informProgress();
|
informProgress();
|
||||||
@@ -191,12 +290,13 @@ public:
|
|||||||
cerr << msg << endl;
|
cerr << msg << endl;
|
||||||
pageSize = PoDoFo::PdfPageSize::A4;
|
pageSize = PoDoFo::PdfPageSize::A4;
|
||||||
}
|
}
|
||||||
if (!m_pixelToPdfWriter->AddPageAt(filePath, imageAttributes.width, imageAttributes.height, index, pageSize))
|
if (!m_pixelToPdfWriter->AddPageAt(filePath, imageAttributes.width, imageAttributes.height, index,
|
||||||
|
m_stampDescriptors, pageSize))
|
||||||
{
|
{
|
||||||
const wxString msg = _("Failed to add page to PDF document.");
|
const wxString msg = _("Failed to add page to PDF document.");
|
||||||
cerr << msg << endl;
|
cerr << msg << endl;
|
||||||
if (m_sb)
|
if (m_sb)
|
||||||
m_sb->SetTransientText(msg);
|
m_sb->CallAfter(&TimeredStatusBar::SetTransientText, msg, 3000);
|
||||||
}
|
}
|
||||||
wxRemoveFile(filePath);
|
wxRemoveFile(filePath);
|
||||||
informProgress();
|
informProgress();
|
||||||
@@ -233,13 +333,27 @@ public:
|
|||||||
m_pixelToPdfWriter.reset((new PixelToPdfWriter())); // For next scan project.
|
m_pixelToPdfWriter.reset((new PixelToPdfWriter())); // For next scan project.
|
||||||
}
|
}
|
||||||
Reset();
|
Reset();
|
||||||
m_owner->txtNewDoc->Clear();
|
m_owner->txtNewDoc->CallAfter(&wxTextCtrl::SetValue, wxString());
|
||||||
if (m_sb)
|
if (m_sb)
|
||||||
{
|
{
|
||||||
const wxString msg = _("Finished.");
|
const wxString msg = _("Finished.");
|
||||||
m_sb->SetTransientText(msg);
|
m_sb->CallAfter(&TimeredStatusBar::SetTransientText, msg, 3000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
UpdateControlsStatus(true);
|
||||||
|
m_wip = false;
|
||||||
|
}
|
||||||
|
void OnStartScanSession(uint pageIndex, const ImageAttributes& imageAttributes) override
|
||||||
|
{
|
||||||
|
// Dealing with stamps only.
|
||||||
|
if (!m_stampDescriptors)
|
||||||
|
return;
|
||||||
|
for (StampDescriptor * descriptor : *m_stampDescriptors)
|
||||||
|
{
|
||||||
|
if (descriptor->text.IsEmpty())
|
||||||
|
continue;
|
||||||
|
descriptor->image = StampWorker::CreateStamp(descriptor, m_resolution);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void Reset()
|
void Reset()
|
||||||
{
|
{
|
||||||
@@ -248,6 +362,7 @@ public:
|
|||||||
m_increment = 1;
|
m_increment = 1;
|
||||||
m_totalEven = 0;
|
m_totalEven = 0;
|
||||||
m_pixelFiles.clear();
|
m_pixelFiles.clear();
|
||||||
|
m_wip = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -255,7 +370,9 @@ private:
|
|||||||
wxWeakRef<TimeredStatusBar> m_sb = nullptr;
|
wxWeakRef<TimeredStatusBar> m_sb = nullptr;
|
||||||
std::unique_ptr<PixelToPdfWriter> m_pixelToPdfWriter;
|
std::unique_ptr<PixelToPdfWriter> m_pixelToPdfWriter;
|
||||||
PixelFilesMap m_pixelFiles;
|
PixelFilesMap m_pixelFiles;
|
||||||
|
vector<StampDescriptor*> * m_stampDescriptors = nullptr;
|
||||||
string m_mode = "Color";
|
string m_mode = "Color";
|
||||||
|
int m_resolution = -1;
|
||||||
uint m_outputType = PDF;
|
uint m_outputType = PDF;
|
||||||
wxString m_paperSize = _T("A4");
|
wxString m_paperSize = _T("A4");
|
||||||
bool m_adf = false;
|
bool m_adf = false;
|
||||||
@@ -264,55 +381,76 @@ private:
|
|||||||
int m_totalEven = 0;
|
int m_totalEven = 0;
|
||||||
int m_startPageIndex = 0;
|
int m_startPageIndex = 0;
|
||||||
int m_increment = 1;
|
int m_increment = 1;
|
||||||
|
bool m_wip = false; // Is InsaneWorker busy?
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
XInsaneWidget::XInsaneWidget(wxWindow* parent, TimeredStatusBar * sb, wxConfig * config, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
|
IMPLEMENT_CLASS( XInsaneWidget, InsaneWidget )
|
||||||
|
|
||||||
|
XInsaneWidget::XInsaneWidget(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
|
||||||
: InsaneWidget(parent, id, pos, size, style)
|
: InsaneWidget(parent, id, pos, size, style)
|
||||||
|
{}
|
||||||
|
|
||||||
|
XInsaneWidget::~XInsaneWidget() = default; // Important for mixing unique_ptr and PIMPL.
|
||||||
|
|
||||||
|
void XInsaneWidget::Setup(wxConfig * config, TimeredStatusBar * sb)
|
||||||
{
|
{
|
||||||
UpdateExtensionsMap();
|
UpdateExtensionsMap();
|
||||||
m_config = config;
|
m_config = config;
|
||||||
m_sb = sb;
|
m_sb = sb;
|
||||||
|
|
||||||
|
// Restore known last values.
|
||||||
|
m_doubleSided = m_config->ReadBool("/Scanner/DoubleSided", false);
|
||||||
|
m_total = m_config->ReadLong("/Scanner/Total", 1);
|
||||||
|
|
||||||
lblNewDoc->Bind ( wxEVT_RIGHT_UP, &XInsaneWidget::OnLblNewDocRightClick, this );
|
lblNewDoc->Bind ( wxEVT_RIGHT_UP, &XInsaneWidget::OnLblNewDocRightClick, this );
|
||||||
txtNewDoc->Bind ( wxEVT_KEY_UP, &XInsaneWidget::OnTxtNewDocKeyPressed, this );
|
txtNewDoc->Bind ( wxEVT_KEY_UP, &XInsaneWidget::OnTxtNewDocKeyPressed, this );
|
||||||
|
|
||||||
m_ptwScannerWidget = std::unique_ptr<wxPopupTransientWindow> (new wxPopupTransientWindow ( wxApp::GetGUIInstance()->GetTopWindow() ));
|
/*
|
||||||
|
* Don't use GetTopWindow() as parent. If it goes away in an application with
|
||||||
|
* multiples instances of XInsaneWidget, any call to the scanner widget leads
|
||||||
|
* to a crash.
|
||||||
|
*/
|
||||||
|
m_ptwScannerWidget = std::make_unique<wxPopupTransientWindow> (GetParent());
|
||||||
m_ptwScannerWidget->Show ( false );
|
m_ptwScannerWidget->Show ( false );
|
||||||
m_scanProject = std::make_unique<ScanProjectHandler>(this, m_sb);
|
m_scanProject = std::make_unique<ScanProjectHandler>(this, m_sb);
|
||||||
m_insaneWorker = std::make_unique<InsaneWorker>(m_scanProject.get());
|
m_insaneWorker = std::make_unique<InsaneWorker>(m_scanProject.get());
|
||||||
m_scannerWidget = std::make_unique<XScannerWidget> ( m_ptwScannerWidget.get(), m_sb, m_insaneWorker.get() );
|
m_scannerWidget = std::make_unique<XScannerWidget> (m_ptwScannerWidget.get());
|
||||||
m_scannerWidget->SetConfig ( m_config );
|
m_scannerWidget->Setup ( m_config, m_insaneWorker.get(), m_sb );
|
||||||
|
|
||||||
btnScan->Enable(false);
|
btnScan->Enable(false);
|
||||||
btnScan->Bind ( wxEVT_RIGHT_UP, &XInsaneWidget::OnBtnScanRightClick, this );
|
btnScan->Bind ( wxEVT_RIGHT_UP, &XInsaneWidget::OnBtnScanRightClick, this );
|
||||||
btnScan->Bind ( wxEVT_LEFT_UP, &XInsaneWidget::OnBtnScanClick, this );
|
btnScan->Bind ( wxEVT_LEFT_UP, &XInsaneWidget::OnBtnScanClick, this );
|
||||||
m_backgroundScannerDiscoveryEvh = std::make_unique<BackgroundScannerDiscoveryEVH>(this);
|
m_backgroundDiscovery = new BackgroundScannerDiscovery ( m_scannerWidget.get(),
|
||||||
BackgroundScannerDiscovery * backgroundDiscovery = new BackgroundScannerDiscovery ( m_scannerWidget.get(),
|
new BackgroundScannerDiscoveryEVH(this)); // Takes ownership.
|
||||||
m_backgroundScannerDiscoveryEvh.get());
|
m_backgroundDiscovery->Run();
|
||||||
backgroundDiscovery->Run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XInsaneWidget::~XInsaneWidget() = default; // Important for mixing unique_ptr and PIMPL.
|
|
||||||
|
|
||||||
// Show a popup to specifiy the number of pages to scan and back-sided scanning.
|
// Show a popup to specifiy the number of pages to scan and back-sided scanning.
|
||||||
void XInsaneWidget::OnLblNewDocRightClick ( wxMouseEvent& evt )
|
void XInsaneWidget::OnLblNewDocRightClick ( wxMouseEvent& evt )
|
||||||
{
|
{
|
||||||
|
if (!lblNewDoc->IsEnabled())
|
||||||
|
{
|
||||||
|
evt.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* The previous ConfigEditorPopup is deleted here, which commits the
|
* The previous ConfigEditorPopup is deleted here, which commits the
|
||||||
* parameters to the config file. At any time, the current parameter values
|
* parameters to the config file. At any time, the current parameter values
|
||||||
* can be lost if a crash occurs.
|
* can be lost if a crash occurs.
|
||||||
*/
|
*/
|
||||||
m_pageStack.reset(new ConfigEditorPopup(wxApp::GetGUIInstance()->GetTopWindow(), m_config));
|
m_pageStack.reset(new ConfigEditorPopup(GetParent(), m_config));
|
||||||
PopupTransientWindow * ptw = m_pageStack->CreatePopup();
|
PopupTransientWindow * ptw = m_pageStack->CreatePopup();
|
||||||
if ( !ptw )
|
if ( !ptw )
|
||||||
{
|
{
|
||||||
evt.Skip();
|
evt.Skip();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wxCheckBox * cb = m_pageStack->AddCheckBox (_("Double sided:"),_T("/Scanner/DoubleSided") );
|
wxCheckBox * cb = m_pageStack->AddCheckBox (_("Double sided:"),_T("/Scanner/DoubleSided"), &m_doubleSided );
|
||||||
cb->SetToolTip (_("Scan all front faces first, then all back faces in reverse order.") );
|
cb->SetToolTip (_("Scan all front faces first, then all back faces in reverse order.") );
|
||||||
wxSpinCtrl * spn = m_pageStack->AddSpinCtrl (_("Total:"),_T("/Scanner/Total") );
|
wxSpinCtrl * spn = m_pageStack->AddSpinCtrl (_("Total:"),_T("/Scanner/Total"), &m_total );
|
||||||
spn->SetRange ( 1, 50 );
|
spn->SetRange ( 1, 50 );
|
||||||
spn->SetToolTip (_("Total number of sides to scan (not total number of sheets).") );
|
spn->SetToolTip (_("Total number of sides to scan (not total number of sheets).") );
|
||||||
m_pageStack->ShowPopup();
|
m_pageStack->ShowPopup();
|
||||||
@@ -328,21 +466,49 @@ void XInsaneWidget::OnTxtNewDocKeyPressed ( wxKeyEvent& evt )
|
|||||||
evt.Skip();
|
evt.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show the scanner widget.
|
// Show the scanner widget or the stamp widgets.
|
||||||
void XInsaneWidget::OnBtnScanRightClick ( wxMouseEvent& evt )
|
void XInsaneWidget::OnBtnScanRightClick ( wxMouseEvent& evt )
|
||||||
{
|
{
|
||||||
if ( m_scannerWidget->cmbDevices->GetCount() )
|
if (evt.ControlDown())
|
||||||
{
|
{
|
||||||
const wxSize current = m_scannerWidget->GetSize();
|
if (!m_dlgStampWidgets)
|
||||||
m_scannerWidget->SetSize ( wxSize ( 500, current.GetHeight() ) );
|
{
|
||||||
|
m_dlgStampWidgets = std::make_unique<wxDialog>
|
||||||
|
(this, wxID_ANY, _("Stamps"),
|
||||||
|
wxDefaultPosition, wxDefaultSize,
|
||||||
|
wxCAPTION | wxRESIZE_BORDER | wxCLOSE_BOX);
|
||||||
|
m_dlgStampWidgets->SetSize(600, 500);
|
||||||
|
m_dlgStampWidgets->SetSizer(new wxBoxSizer(wxVERTICAL));
|
||||||
|
m_dlgStampWidgets->Show ( false );
|
||||||
|
m_stampWidgets = std::make_unique<XStampWidgets> ( m_dlgStampWidgets.get());
|
||||||
|
m_stampWidgets->Setup(m_config);
|
||||||
|
m_dlgStampWidgets->GetSizer()->Add(m_stampWidgets.get(), 1, wxGROW | wxALL, 5);
|
||||||
|
}
|
||||||
|
m_dlgStampWidgets->Show();
|
||||||
}
|
}
|
||||||
MiscTools::ShowTransientPopup ( m_ptwScannerWidget.get(), m_scannerWidget.get() );
|
else
|
||||||
evt.Skip();
|
{
|
||||||
|
if ( m_scannerWidget->cmbDevices->GetCount() )
|
||||||
|
{
|
||||||
|
const wxSize current = m_scannerWidget->GetSize();
|
||||||
|
m_scannerWidget->SetSize ( wxSize ( 500, current.GetHeight() ) );
|
||||||
|
}
|
||||||
|
MiscTools::ShowTransientPopup ( m_ptwScannerWidget.get(), m_scannerWidget.get() );
|
||||||
|
}
|
||||||
|
// +++ Prevent OnLblNewDocRightClick() from being called.
|
||||||
|
// Why is OnBtnScanRightClick() not called the other way round?
|
||||||
|
evt.Skip(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start scanning.
|
// Start scanning.
|
||||||
void XInsaneWidget::OnBtnScanClick ( wxMouseEvent& evt )
|
void XInsaneWidget::OnBtnScanClick ( wxMouseEvent& evt )
|
||||||
{
|
{
|
||||||
|
if (m_scanProject->GetWip())
|
||||||
|
{
|
||||||
|
CancelScanning();
|
||||||
|
evt.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
const wxString dest = txtNewDoc->GetValue();
|
const wxString dest = txtNewDoc->GetValue();
|
||||||
if (dest.IsEmpty())
|
if (dest.IsEmpty())
|
||||||
{
|
{
|
||||||
@@ -352,22 +518,14 @@ void XInsaneWidget::OnBtnScanClick ( wxMouseEvent& evt )
|
|||||||
}
|
}
|
||||||
const uint outputType = m_scannerWidget->GetScannerOutputType();
|
const uint outputType = m_scannerWidget->GetScannerOutputType();
|
||||||
bool adf = false;
|
bool adf = false;
|
||||||
bool doubleSided = false;
|
wxString paperSize = m_scannerWidget->GetPaperSize();
|
||||||
uint total = 1;
|
|
||||||
wxString paperSize = _T("A4");
|
|
||||||
if (m_config)
|
|
||||||
{
|
|
||||||
doubleSided = m_config->ReadBool("/Scanner/DoubleSided", false);
|
|
||||||
total = m_config->ReadLong("/Scanner/Total", 1);
|
|
||||||
m_config->Read("/Scanner/Last/PaperSize", &paperSize, "A4");
|
|
||||||
}
|
|
||||||
|
|
||||||
wxFileName destFile(dest);
|
wxFileName destFile(dest);
|
||||||
const string deviceId = m_scannerWidget->GetCurrentDeviceId().ToStdString();
|
const string deviceId = m_scannerWidget->GetCurrentDeviceId().ToStdString();
|
||||||
const std::pair<int, wxString> sourceAttributes = m_scannerWidget->GetScannerSource();
|
const std::pair<int, wxString> sourceAttributes = m_scannerWidget->GetScannerSource();
|
||||||
const string source = sourceAttributes.second.ToStdString();
|
const string source = sourceAttributes.second.ToStdString();
|
||||||
const string mode = m_scannerWidget->GetScannerMode().ToStdString();
|
const string mode = m_scannerWidget->GetScannerMode().ToStdString();
|
||||||
int resolution = 300;
|
int resolution = -1; // No resolution with v4l devices.
|
||||||
if ( !m_scannerWidget->GetScannerResolution().IsEmpty() )
|
if ( !m_scannerWidget->GetScannerResolution().IsEmpty() )
|
||||||
{
|
{
|
||||||
resolution = std::stoi ( m_scannerWidget->GetScannerResolution().ToStdString() );
|
resolution = std::stoi ( m_scannerWidget->GetScannerResolution().ToStdString() );
|
||||||
@@ -379,17 +537,28 @@ void XInsaneWidget::OnBtnScanClick ( wxMouseEvent& evt )
|
|||||||
{
|
{
|
||||||
m_scanProject->SetADF(adf);
|
m_scanProject->SetADF(adf);
|
||||||
m_scanProject->SetMode(mode);
|
m_scanProject->SetMode(mode);
|
||||||
|
m_scanProject->SetResolution(resolution);
|
||||||
m_scanProject->SetOutputType(outputType);
|
m_scanProject->SetOutputType(outputType);
|
||||||
m_scanProject->SetPaperSize(paperSize);
|
m_scanProject->SetPaperSize(paperSize);
|
||||||
m_scanProject->SetDoubleSided(doubleSided);
|
m_scanProject->SetDoubleSided(m_doubleSided);
|
||||||
m_scanProject->SetTotalNumberOfSides(total);
|
m_scanProject->SetTotalNumberOfSides((uint) m_total);
|
||||||
|
if (m_stampWidgets)
|
||||||
|
{
|
||||||
|
m_stampDescriptors = m_stampWidgets->GetStampDescriptors();
|
||||||
|
m_scanProject->SetStampDescriptors(m_stampDescriptors);
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<int, int> startAndIncrement = m_scanProject->GetStartAndIncrement(m_insaneWorker.get());
|
std::pair<int, int> startAndIncrement = m_scanProject->GetStartAndIncrement(m_insaneWorker.get());
|
||||||
|
|
||||||
const int padWidth = ( ushort ) m_config->Read (_T("/Scanner/Counter/Length"), 2 );
|
const int padWidth = ( ushort ) m_config->Read (_T("/Scanner/Counter/Length"), 2 );
|
||||||
bool res = m_insaneWorker->Scan(destFile.GetPath().ToStdString(),
|
m_scanProject->UpdateControlsStatus(false);
|
||||||
destFile.GetName().ToStdString(),
|
BackgroundScan * bgScan = new BackgroundScan(this, m_insaneWorker.get(),
|
||||||
startAndIncrement.first, padWidth, startAndIncrement.second);
|
destFile.GetPath().ToStdString(),
|
||||||
|
destFile.GetName().ToStdString(),
|
||||||
|
startAndIncrement.first, padWidth,
|
||||||
|
startAndIncrement.second);
|
||||||
|
m_scanProject->SetWip(true);
|
||||||
|
bgScan->Run();
|
||||||
}
|
}
|
||||||
evt.Skip();
|
evt.Skip();
|
||||||
}
|
}
|
||||||
@@ -402,11 +571,30 @@ void XInsaneWidget::ResetScanProject()
|
|||||||
|
|
||||||
void XInsaneWidget::CancelScanning()
|
void XInsaneWidget::CancelScanning()
|
||||||
{
|
{
|
||||||
if (m_insaneWorker)
|
if (m_insaneWorker && m_scanProject->GetWip())
|
||||||
|
{
|
||||||
m_insaneWorker->Cancel();
|
m_insaneWorker->Cancel();
|
||||||
|
btnScan->Enable(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XInsaneWidget::EnableScanButton(bool enable)
|
void XInsaneWidget::EnableScanButton(bool enable)
|
||||||
{
|
{
|
||||||
|
// Called from BackgroundScannerDiscoveryEVH::Done() only;
|
||||||
btnScan->Enable(enable);
|
btnScan->Enable(enable);
|
||||||
|
m_backgroundDiscovery = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XInsaneWidget::IsScannerDiscoveryRunning()
|
||||||
|
{
|
||||||
|
if (!m_backgroundDiscovery)
|
||||||
|
return false;
|
||||||
|
return m_backgroundDiscovery->IsRunning();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XInsaneWidget::IsScanning()
|
||||||
|
{
|
||||||
|
if (!m_scanProject)
|
||||||
|
return false;
|
||||||
|
return m_scanProject->GetWip();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,18 +16,23 @@
|
|||||||
#include <InsaneWidget.h>
|
#include <InsaneWidget.h>
|
||||||
#include <InsaneWorker.h>
|
#include <InsaneWorker.h>
|
||||||
#include <XScannerWidget.h>
|
#include <XScannerWidget.h>
|
||||||
|
#include <XStampWidget.h>
|
||||||
|
#include <XStampWidgets.h>
|
||||||
#include <TimeredStatusBar.h>
|
#include <TimeredStatusBar.h>
|
||||||
#include <ConfigEditorPopup.h>
|
#include <ConfigEditorPopup.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class BackgroundScannerDiscoveryEVH;
|
class BackgroundScannerDiscovery; // Is a wxThread.
|
||||||
class ScanProjectHandler; // An event handler extending InsaneWorkerEvent.
|
class ScanProjectHandler; // An event handler extending InsaneWorkerEvent.
|
||||||
|
class XStampWidget;
|
||||||
|
struct StampDescriptor;
|
||||||
|
|
||||||
// Page index (not page number), {pixel file path, {pixel count, image width, image height}}.
|
// Page index (not page number), {pixel file path, {pixel count, image width, image height}}.
|
||||||
typedef std::map<uint, std::tuple<std::string, InsaneWorkerEvent::ImageAttributes>> PixelFilesMap;
|
typedef std::map<uint, std::tuple<std::string, InsaneWorkerEvent::ImageAttributes>> PixelFilesMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows a label, a disabled text box and a button.
|
* Shows a label, a disabled text box, and a button.
|
||||||
*
|
*
|
||||||
* Label:
|
* Label:
|
||||||
* - Right click: define the number of pages to scan and double-sided scanning.
|
* - Right click: define the number of pages to scan and double-sided scanning.
|
||||||
@@ -42,35 +47,47 @@ typedef std::map<uint, std::tuple<std::string, InsaneWorkerEvent::ImageAttribute
|
|||||||
*
|
*
|
||||||
* Text box:
|
* Text box:
|
||||||
* - shows the path and the basename of the files to create. This must be set
|
* - shows the path and the basename of the files to create. This must be set
|
||||||
* by the application in any conveniant manner.
|
* by the application in any convenient manner.
|
||||||
* Pressing the backspace key clears the text box.
|
* Pressing the backspace key clears the text box.
|
||||||
*
|
*
|
||||||
* Button:
|
* Button:
|
||||||
* - Right click: shows the scanner widget.
|
* - Right click: shows the scanner widget.
|
||||||
* - Left click: starts scanning.
|
* - Left click: starts or cancels scanning.
|
||||||
|
* - Ctrl + Right click: show the stamp widgets dialog.
|
||||||
*/
|
*/
|
||||||
class XInsaneWidget : public InsaneWidget
|
class XInsaneWidget : public InsaneWidget
|
||||||
{
|
{
|
||||||
|
DECLARE_DYNAMIC_CLASS( XInsaneWidget )
|
||||||
public:
|
public:
|
||||||
virtual ~XInsaneWidget();
|
virtual ~XInsaneWidget();
|
||||||
XInsaneWidget( wxWindow* parent, TimeredStatusBar * sb, wxConfig * config, wxWindowID id = SYMBOL_INSANEWIDGET_IDNAME, const wxPoint& pos = SYMBOL_INSANEWIDGET_POSITION, const wxSize& size = SYMBOL_INSANEWIDGET_SIZE, long style = SYMBOL_INSANEWIDGET_STYLE );
|
XInsaneWidget( wxWindow* parent, wxWindowID id = SYMBOL_INSANEWIDGET_IDNAME, const wxPoint& pos = SYMBOL_INSANEWIDGET_POSITION, const wxSize& size = SYMBOL_INSANEWIDGET_SIZE, long style = SYMBOL_INSANEWIDGET_STYLE );
|
||||||
|
|
||||||
void ResetScanProject();
|
void ResetScanProject();
|
||||||
void CancelScanning(); // Not tested, probably doesn't work as intended.
|
void CancelScanning();
|
||||||
void EnableScanButton(bool enable); // For CallAfter.
|
void EnableScanButton(bool enable); // For CallAfter.
|
||||||
|
void Setup(wxConfig * config, TimeredStatusBar * sb);
|
||||||
|
bool IsScannerDiscoveryRunning();
|
||||||
|
bool IsScanning();
|
||||||
private:
|
private:
|
||||||
wxConfig * m_config;
|
wxConfig * m_config;
|
||||||
wxWeakRef<TimeredStatusBar> m_sb;
|
wxWeakRef<TimeredStatusBar> m_sb;
|
||||||
|
std::vector<StampDescriptor*> * m_stampDescriptors;
|
||||||
|
|
||||||
// Contains a popup to define the number of pages and double-sided scanning.
|
// Contains a popup to define the number of pages and double-sided scanning.
|
||||||
std::unique_ptr<ConfigEditorPopup> m_pageStack;
|
std::unique_ptr<ConfigEditorPopup> m_pageStack;
|
||||||
// Contains the scanner widget.
|
// Contains the scanner widget.
|
||||||
std::unique_ptr<wxPopupTransientWindow> m_ptwScannerWidget;
|
std::unique_ptr<wxPopupTransientWindow> m_ptwScannerWidget;
|
||||||
|
// Contains the stamp widgets.
|
||||||
|
std::unique_ptr<wxDialog> m_dlgStampWidgets;
|
||||||
|
std::unique_ptr<XStampWidgets> m_stampWidgets;
|
||||||
// Available devices and minimal options.
|
// Available devices and minimal options.
|
||||||
std::unique_ptr<XScannerWidget> m_scannerWidget;
|
std::unique_ptr<XScannerWidget> m_scannerWidget;
|
||||||
std::unique_ptr<InsaneWorker> m_insaneWorker;
|
std::unique_ptr<InsaneWorker> m_insaneWorker;
|
||||||
std::unique_ptr<BackgroundScannerDiscoveryEVH> m_backgroundScannerDiscoveryEvh;
|
BackgroundScannerDiscovery * m_backgroundDiscovery;
|
||||||
std::unique_ptr<ScanProjectHandler> m_scanProject;
|
std::unique_ptr<ScanProjectHandler> m_scanProject;
|
||||||
|
|
||||||
|
bool m_doubleSided = false;
|
||||||
|
int m_total = 1;
|
||||||
|
|
||||||
void OnLblNewDocRightClick ( wxMouseEvent& evt );
|
void OnLblNewDocRightClick ( wxMouseEvent& evt );
|
||||||
void OnTxtNewDocKeyPressed ( wxKeyEvent& evt );
|
void OnTxtNewDocKeyPressed ( wxKeyEvent& evt );
|
||||||
|
|||||||
@@ -9,26 +9,39 @@
|
|||||||
|
|
||||||
#include "XScannerWidget.h"
|
#include "XScannerWidget.h"
|
||||||
#include "XClientData.hpp"
|
#include "XClientData.hpp"
|
||||||
#include "Common.h"
|
#include "DefsInsaneWidget.h"
|
||||||
#include <libinsane/constants.h>
|
#include <libinsane/constants.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
IMPLEMENT_CLASS( XScannerWidget, ScannerWidget )
|
||||||
|
|
||||||
|
XScannerWidget::XScannerWidget() : ScannerWidget()
|
||||||
|
{}
|
||||||
|
|
||||||
XScannerWidget::~XScannerWidget()
|
XScannerWidget::~XScannerWidget()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
XScannerWidget::XScannerWidget ( wxWindow* parent, TimeredStatusBar * sb,
|
XScannerWidget::XScannerWidget ( wxWindow* parent, wxWindowID id,
|
||||||
InsaneWorker * insaneWorker,
|
const wxPoint& pos, const wxSize& size, long int style )
|
||||||
wxWindowID id, const wxPoint& pos, const wxSize& size, long int style )
|
: ScannerWidget ( parent, id, pos, size, style )
|
||||||
: ScannerWidget ( parent, id, pos, size, style )
|
{}
|
||||||
|
|
||||||
|
void XScannerWidget::Setup ( wxConfig* config, InsaneWorker * insaneWorker,
|
||||||
|
TimeredStatusBar * sb)
|
||||||
{
|
{
|
||||||
UpdateExtensionsMap();
|
wxASSERT_MSG ( ( config != nullptr ),_T("config IS nullptr") );
|
||||||
|
wxASSERT_MSG ( ( insaneWorker != nullptr ),_T("insaneWorker IS nullptr") );
|
||||||
|
m_config = config;
|
||||||
m_sb = sb;
|
m_sb = sb;
|
||||||
m_insaneWorker = insaneWorker;
|
m_insaneWorker = insaneWorker;
|
||||||
|
|
||||||
|
UpdateExtensionsMap();
|
||||||
if (m_insaneWorker)
|
if (m_insaneWorker)
|
||||||
m_insaneWorkerEvh = m_insaneWorker->GetEventHandler();
|
m_insaneWorkerEvh = m_insaneWorker->GetEventHandler();
|
||||||
|
|
||||||
cmbOutputType->Append (Extensions[PDF]); // Use the file extension and the enum index without client data.
|
cmbOutputType->Append (Extensions[PDF]); // Use the file extension and the enum index without client data.
|
||||||
#if wxUSE_LIBPNG
|
#if wxUSE_LIBPNG
|
||||||
cmbOutputType->Append (Extensions[PNG]);
|
cmbOutputType->Append (Extensions[PNG]);
|
||||||
@@ -44,7 +57,7 @@ XScannerWidget::XScannerWidget ( wxWindow* parent, TimeredStatusBar * sb,
|
|||||||
#endif
|
#endif
|
||||||
// Paper sizes handled by podofo.
|
// Paper sizes handled by podofo.
|
||||||
cmbPaperSize->Append(wxArrayString({"A0", "A1", "A2", "A3", "A4", "A5", "A6",
|
cmbPaperSize->Append(wxArrayString({"A0", "A1", "A2", "A3", "A4", "A5", "A6",
|
||||||
"Letter", "Legal", "Tabloid"}));
|
"Letter", "Legal", "Tabloid"}));
|
||||||
|
|
||||||
btnRefreshDevices->Bind ( wxEVT_COMMAND_BUTTON_CLICKED, &XScannerWidget::OnButtonRefreshDevices, this );
|
btnRefreshDevices->Bind ( wxEVT_COMMAND_BUTTON_CLICKED, &XScannerWidget::OnButtonRefreshDevices, this );
|
||||||
cmbDevices->Bind ( wxEVT_COMMAND_COMBOBOX_SELECTED, &XScannerWidget::OnDeviceSelected, this );
|
cmbDevices->Bind ( wxEVT_COMMAND_COMBOBOX_SELECTED, &XScannerWidget::OnDeviceSelected, this );
|
||||||
@@ -54,6 +67,20 @@ XScannerWidget::XScannerWidget ( wxWindow* parent, TimeredStatusBar * sb,
|
|||||||
cmbResolution->Bind ( wxEVT_COMMAND_COMBOBOX_SELECTED, &XScannerWidget::OnResolutionSelected, this );
|
cmbResolution->Bind ( wxEVT_COMMAND_COMBOBOX_SELECTED, &XScannerWidget::OnResolutionSelected, this );
|
||||||
cmbPaperSize->Bind ( wxEVT_COMMAND_COMBOBOX_SELECTED, &XScannerWidget::OnPaperSizeSelected, this );
|
cmbPaperSize->Bind ( wxEVT_COMMAND_COMBOBOX_SELECTED, &XScannerWidget::OnPaperSizeSelected, this );
|
||||||
GetParent()->Bind ( wxEVT_SHOW, &XScannerWidget::OnActivated, this );
|
GetParent()->Bind ( wxEVT_SHOW, &XScannerWidget::OnActivated, this );
|
||||||
|
|
||||||
|
wxString lastImageType;
|
||||||
|
m_config->Read (_T("/Scanner/Last/OutputType"), &lastImageType );
|
||||||
|
if ( cmbOutputType->FindString ( lastImageType, true ) != wxNOT_FOUND )
|
||||||
|
cmbOutputType->SetStringSelection ( lastImageType );
|
||||||
|
else
|
||||||
|
cmbOutputType->Select(0);
|
||||||
|
|
||||||
|
wxString lastPaperSize;
|
||||||
|
m_config->Read (_T("/Scanner/Last/PaperSize"), &lastPaperSize );
|
||||||
|
if ( cmbPaperSize->FindString ( lastPaperSize, true ) != wxNOT_FOUND )
|
||||||
|
cmbPaperSize->SetStringSelection ( lastPaperSize );
|
||||||
|
else
|
||||||
|
cmbPaperSize->Select(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XScannerWidget::FindDevices ( bool async )
|
bool XScannerWidget::FindDevices ( bool async )
|
||||||
@@ -113,28 +140,6 @@ void XScannerWidget::OnButtonRefreshDevices ( wxCommandEvent& evt )
|
|||||||
btnRefreshDevices->Enable ( true );
|
btnRefreshDevices->Enable ( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
void XScannerWidget::SetConfig ( wxFileConfig* config )
|
|
||||||
{
|
|
||||||
m_config = config;
|
|
||||||
if ( !m_config )
|
|
||||||
return;
|
|
||||||
|
|
||||||
wxString lastImageType;
|
|
||||||
m_config->Read (_T("/Scanner/Last/OutputType"), &lastImageType );
|
|
||||||
if ( cmbOutputType->FindString ( lastImageType, true ) != wxNOT_FOUND )
|
|
||||||
cmbOutputType->SetStringSelection ( lastImageType );
|
|
||||||
else
|
|
||||||
cmbOutputType->Select(0);
|
|
||||||
|
|
||||||
wxString lastPaperSize;
|
|
||||||
m_config->Read (_T("/Scanner/Last/PaperSize"), &lastPaperSize );
|
|
||||||
if ( cmbPaperSize->FindString ( lastPaperSize, true ) != wxNOT_FOUND )
|
|
||||||
cmbPaperSize->SetStringSelection ( lastPaperSize );
|
|
||||||
else
|
|
||||||
cmbPaperSize->Select(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void XScannerWidget::OnDeviceSelected ( wxCommandEvent& evt )
|
void XScannerWidget::OnDeviceSelected ( wxCommandEvent& evt )
|
||||||
{
|
{
|
||||||
if ( !m_config || ( cmbDevices->GetSelection() == wxNOT_FOUND ) )
|
if ( !m_config || ( cmbDevices->GetSelection() == wxNOT_FOUND ) )
|
||||||
@@ -306,7 +311,10 @@ wxThread::ExitCode BackgroundScannerDiscovery::Entry()
|
|||||||
evt.SetShow ( true );
|
evt.SetShow ( true );
|
||||||
m_owner->OnActivated ( evt );
|
m_owner->OnActivated ( evt );
|
||||||
if (m_evh)
|
if (m_evh)
|
||||||
|
{
|
||||||
m_evh->OnDone();
|
m_evh->OnDone();
|
||||||
|
wxDELETE(m_evh);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ( wxThread::ExitCode ) 0;
|
return ( wxThread::ExitCode ) 0;
|
||||||
}
|
}
|
||||||
@@ -316,3 +324,5 @@ wxThread::ExitCode BackgroundScannerDiscovery::Entry()
|
|||||||
void BackgroundScannerDiscoveryEvent::OnDone()
|
void BackgroundScannerDiscoveryEvent::OnDone()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
BackgroundScannerDiscoveryEvent::~BackgroundScannerDiscoveryEvent() = default;
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
#include <ScannerWidget.h>
|
#include <ScannerWidget.h>
|
||||||
#include "TimeredStatusBar.h"
|
#include "TimeredStatusBar.h"
|
||||||
#include "InsaneWorker.h"
|
#include "InsaneWorker.h"
|
||||||
#include "Common.h"
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
class BackgroundScannerDiscoveryEvent;
|
class BackgroundScannerDiscoveryEvent;
|
||||||
@@ -33,20 +32,19 @@ class BackgroundScannerDiscoveryEvent;
|
|||||||
|
|
||||||
class XScannerWidget : public ScannerWidget
|
class XScannerWidget : public ScannerWidget
|
||||||
{
|
{
|
||||||
|
DECLARE_DYNAMIC_CLASS( XScannerWidget )
|
||||||
friend class BackgroundScannerDiscovery;
|
friend class BackgroundScannerDiscovery;
|
||||||
public:
|
public:
|
||||||
XScannerWidget() {};
|
XScannerWidget();
|
||||||
~XScannerWidget();
|
virtual ~XScannerWidget();
|
||||||
|
|
||||||
|
|
||||||
XScannerWidget ( wxWindow* parent, TimeredStatusBar * sb,
|
XScannerWidget ( wxWindow* parent, wxWindowID id = wxID_ANY,
|
||||||
InsaneWorker * insaneWorker,
|
|
||||||
wxWindowID id = wxID_ANY,
|
|
||||||
const wxPoint& pos = wxDefaultPosition,
|
const wxPoint& pos = wxDefaultPosition,
|
||||||
const wxSize& size = SYMBOL_SCANNERWIDGET_SIZE,
|
const wxSize& size = SYMBOL_SCANNERWIDGET_SIZE,
|
||||||
long int style = SYMBOL_SCANNERWIDGET_STYLE );
|
long int style = SYMBOL_SCANNERWIDGET_STYLE );
|
||||||
|
|
||||||
void SetConfig ( wxConfig * config );
|
void Setup ( wxConfig* config, InsaneWorker * insaneWorker,
|
||||||
|
TimeredStatusBar * sb = nullptr );
|
||||||
bool FindDevices ( bool async = false );
|
bool FindDevices ( bool async = false );
|
||||||
wxString GetCurrentDeviceId() const;
|
wxString GetCurrentDeviceId() const;
|
||||||
wxString GetScannerMode() const
|
wxString GetScannerMode() const
|
||||||
@@ -101,7 +99,7 @@ public:
|
|||||||
BackgroundScannerDiscovery ( XScannerWidget * owner, BackgroundScannerDiscoveryEvent * evh )
|
BackgroundScannerDiscovery ( XScannerWidget * owner, BackgroundScannerDiscoveryEvent * evh )
|
||||||
{
|
{
|
||||||
m_owner = owner;
|
m_owner = owner;
|
||||||
m_evh = evh;
|
m_evh = evh; // Owned here.
|
||||||
}
|
}
|
||||||
virtual ~BackgroundScannerDiscovery() {};
|
virtual ~BackgroundScannerDiscovery() {};
|
||||||
virtual ExitCode Entry();
|
virtual ExitCode Entry();
|
||||||
@@ -114,6 +112,7 @@ class BackgroundScannerDiscoveryEvent
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void OnDone();
|
virtual void OnDone();
|
||||||
|
virtual ~BackgroundScannerDiscoveryEvent();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ DEST=$DOMAIN/${COMPONENT_NAME}.po
|
|||||||
[ -f $DEST ] && cp $DEST $DEST.bak-$(date +%F-%T)
|
[ -f $DEST ] && cp $DEST $DEST.bak-$(date +%F-%T)
|
||||||
[ ! -f $DEST ] && touch $DEST
|
[ ! -f $DEST ] && touch $DEST
|
||||||
|
|
||||||
|
# Memo: use '--no-location' transiently to get rid of obsolete file locations.
|
||||||
|
|
||||||
xgettext --keyword=_ -d $DOMAIN $JOIN -o $DEST --c++ --from-code=UTF-8 $(find $SRC -type f -name "*.cpp")
|
xgettext --keyword=_ -d $DOMAIN $JOIN -o $DEST --c++ --from-code=UTF-8 $(find $SRC -type f -name "*.cpp")
|
||||||
xgettext --keyword=_ -d $DOMAIN -j -o $DEST --c++ --from-code=UTF-8 $(find $SRC -type f -name "*.h")
|
xgettext --keyword=_ -d $DOMAIN -j -o $DEST --c++ --from-code=UTF-8 $(find $SRC -type f -name "*.h")
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-06-26 22:47+0200\n"
|
"POT-Creation-Date: 2025-07-14 13:28+0200\n"
|
||||||
"PO-Revision-Date: 2025-06-26 22:47+0200\n"
|
"PO-Revision-Date: 2025-07-15 19:27+0200\n"
|
||||||
"Last-Translator: Saleem EDAH-TALLY <set@nmset.info>\n"
|
"Last-Translator: Saleem EDAH-TALLY <set@nmset.info>\n"
|
||||||
"Language-Team: French <kde-francophone@kde.org>\n"
|
"Language-Team: French <kde-francophone@kde.org>\n"
|
||||||
"Language: fr_FR\n"
|
"Language: fr_FR\n"
|
||||||
@@ -15,9 +15,9 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||||
"X-Generator: Lokalize 25.04.2\n"
|
"X-Generator: Lokalize 25.04.3\n"
|
||||||
|
|
||||||
#: ../../Resources/UI/S7/s7.cpp:126 ../..//Resources/UI/S7/s7.cpp:126
|
#: ../../Resources/UI/S7/s7.cpp:126
|
||||||
msgid ""
|
msgid ""
|
||||||
"Select a destination directory.\n"
|
"Select a destination directory.\n"
|
||||||
"Double-click to go to the selected directory."
|
"Double-click to go to the selected directory."
|
||||||
@@ -25,11 +25,11 @@ msgstr ""
|
|||||||
"Choisissez un dossier destination\n"
|
"Choisissez un dossier destination\n"
|
||||||
"Double-clic pour aller au dossier."
|
"Double-clic pour aller au dossier."
|
||||||
|
|
||||||
#: ../../Resources/UI/S7/s7.cpp:130 ../..//Resources/UI/S7/s7.cpp:130
|
#: ../../Resources/UI/S7/s7.cpp:130
|
||||||
msgid "Basename"
|
msgid "Basename"
|
||||||
msgstr "Nom de base"
|
msgstr "Nom de base"
|
||||||
|
|
||||||
#: ../../Resources/UI/S7/s7.cpp:132 ../..//Resources/UI/S7/s7.cpp:132
|
#: ../../Resources/UI/S7/s7.cpp:132
|
||||||
msgid ""
|
msgid ""
|
||||||
"Specify a destination file basename (without extension).\n"
|
"Specify a destination file basename (without extension).\n"
|
||||||
"\n"
|
"\n"
|
||||||
@@ -39,15 +39,15 @@ msgstr ""
|
|||||||
"\n"
|
"\n"
|
||||||
"'CTRL + clic' : à propos"
|
"'CTRL + clic' : à propos"
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:128
|
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:129
|
||||||
msgid "New"
|
msgid "New"
|
||||||
msgstr "Nouveau"
|
msgstr "Nouveau"
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:130
|
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:131
|
||||||
msgid "'Right' click to define a scan project."
|
msgid "'Right' click to define a scan project."
|
||||||
msgstr "Clic droit pour définir un projet de numérisation"
|
msgstr "Clic droit pour définir un projet de numérisation"
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:135
|
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:136
|
||||||
msgid ""
|
msgid ""
|
||||||
"Full path to destination file without the extension; it is determined by the "
|
"Full path to destination file without the extension; it is determined by the "
|
||||||
"output type."
|
"output type."
|
||||||
@@ -55,11 +55,11 @@ msgstr ""
|
|||||||
"Chemin complet du fichier de destination sans l'extension; elle est "
|
"Chemin complet du fichier de destination sans l'extension; elle est "
|
||||||
"déterminée par le format de sortie."
|
"déterminée par le format de sortie."
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:138
|
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:139
|
||||||
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:182
|
||||||
msgid "Scan"
|
msgid "Scan"
|
||||||
msgstr "Numériser"
|
msgstr "Numériser"
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:140
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"'Left click' to start the scan project.\n"
|
"'Left click' to start the scan project.\n"
|
||||||
"'Right click' to show the scanner widget."
|
"'Right click' to show the scanner widget."
|
||||||
@@ -91,139 +91,113 @@ msgstr "Mode de numérisation"
|
|||||||
msgid "Scan resolution"
|
msgid "Scan resolution"
|
||||||
msgstr "Résolution de la numérisation"
|
msgstr "Résolution de la numérisation"
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:128
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:208
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:107
|
|
||||||
msgid "A scan library error occurred."
|
msgid "A scan library error occurred."
|
||||||
msgstr "Une erreur de bibliothèque est survenue."
|
msgstr "Une erreur de bibliothèque est survenue."
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:134
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:216
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:113
|
|
||||||
msgid "A general error occurred."
|
msgid "A general error occurred."
|
||||||
msgstr "Une erreur générale est survenue."
|
msgstr "Une erreur générale est survenue."
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:138
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:221
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:117
|
|
||||||
msgid "A session read error occurred."
|
msgid "A session read error occurred."
|
||||||
msgstr "Une erreur de lecture est survenue."
|
msgstr "Une erreur de lecture est survenue."
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:145
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:233
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:124
|
|
||||||
msgid "Session cancelled."
|
msgid "Session cancelled."
|
||||||
msgstr "Session annulée."
|
msgstr "Session annulée."
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:162
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:250
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:141
|
|
||||||
msgid "Scanning: "
|
msgid "Scanning: "
|
||||||
msgstr "Numérisation :"
|
msgstr "Numérisation : "
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:164
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:252
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:143
|
|
||||||
msgid "Front face: "
|
msgid "Front face: "
|
||||||
msgstr "Recto :"
|
msgstr "Recto :"
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:166
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:254
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:145
|
|
||||||
msgid "Back face: "
|
msgid "Back face: "
|
||||||
msgstr "Verso :"
|
msgstr "Verso :"
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:170
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:258
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:149
|
|
||||||
msgid ". Turn the whole stack of pages."
|
msgid ". Turn the whole stack of pages."
|
||||||
msgstr ". Retournez toute la pile de pages."
|
msgstr ". Retournez toute la pile de pages."
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:182
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:161
|
|
||||||
msgid "Failed to create PNG image."
|
msgid "Failed to create PNG image."
|
||||||
msgstr "Échec de création d'image PNG."
|
msgstr "Échec de création d'image PNG."
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:201
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:289
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:180
|
|
||||||
msgid "Wrong paper size: "
|
msgid "Wrong paper size: "
|
||||||
msgstr "Mauvaise taille de papier :"
|
msgstr "Mauvaise taille de papier :"
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:201
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:289
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:180
|
|
||||||
msgid "; using A4."
|
msgid "; using A4."
|
||||||
msgstr "; utilisation du format A4."
|
msgstr "; utilisation du format A4."
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:207
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:296
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:186
|
|
||||||
msgid "Failed to add page to PDF document."
|
msgid "Failed to add page to PDF document."
|
||||||
msgstr "Échec d'ajout de page au document PDF."
|
msgstr "Échec d'ajout de page au document PDF."
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:217
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:255
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:196
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:234
|
|
||||||
msgid "Unhandled output file format."
|
msgid "Unhandled output file format."
|
||||||
msgstr "Format de fichier de sortie non pris en charge."
|
msgstr "Format de fichier de sortie non pris en charge."
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:264
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:339
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:243
|
|
||||||
msgid "Finished."
|
msgid "Finished."
|
||||||
msgstr "Terminé."
|
msgstr "Terminé."
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:333
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:452
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:317
|
|
||||||
msgid "Scan all front faces first, then all back faces in reverse order."
|
msgid "Scan all front faces first, then all back faces in reverse order."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Numériser tous les faces recto, puis toutes les faces verso en ordre inverse."
|
"Numériser tous les faces recto, puis toutes les faces verso en ordre inverse."
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:336
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:455
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:320
|
|
||||||
msgid "Total number of sides to scan (not total number of sheets)."
|
msgid "Total number of sides to scan (not total number of sheets)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Nombre total de faces à numériser (et non pas le nombre total de feuilles)."
|
"Nombre total de faces à numériser (et non pas le nombre total de feuilles)."
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/lib/TimeredStatusBar.cpp:44
|
|
||||||
#: ../../Resources/Utilities/TimeredStatusBar.cpp:44
|
#: ../../Resources/Utilities/TimeredStatusBar.cpp:44
|
||||||
#: ../..//Resources/Utilities/TimeredStatusBar.cpp:44
|
|
||||||
msgid "NUM"
|
msgid "NUM"
|
||||||
msgstr "NUM"
|
msgstr "NUM"
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/lib/TimeredStatusBar.cpp:52
|
|
||||||
#: ../../Resources/Utilities/TimeredStatusBar.cpp:52
|
#: ../../Resources/Utilities/TimeredStatusBar.cpp:52
|
||||||
#: ../..//Resources/Utilities/TimeredStatusBar.cpp:52
|
|
||||||
msgid "CAPS"
|
msgid "CAPS"
|
||||||
msgstr "CAPS"
|
msgstr "CAPS"
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XScannerWidget.cpp:50
|
#: ../../Resources/InsaneWidget/XScannerWidget.cpp:89
|
||||||
msgid "Searching for devices..."
|
msgid "Searching for devices..."
|
||||||
msgstr "Recherche de périphériques..."
|
msgstr "Recherche de périphériques..."
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XScannerWidget.cpp:53
|
#: ../../Resources/InsaneWidget/XScannerWidget.cpp:92
|
||||||
msgid "Could not initialise insane api."
|
msgid "Could not initialise insane api."
|
||||||
msgstr "Échec d'initialisation de la bibliothèque 'insane'."
|
msgstr "Échec d'initialisation de la bibliothèque 'insane'."
|
||||||
|
|
||||||
#: ../../XS7.cpp:46
|
|
||||||
msgid "'Shift + left' click'' to generate a new destination file name."
|
msgid "'Shift + left' click'' to generate a new destination file name."
|
||||||
msgstr "'Maj + clic gauche' pour générer un nouveau fichier de sortie."
|
msgstr "'Maj + clic gauche' pour générer un nouveau fichier de sortie."
|
||||||
|
|
||||||
#: ../../XS7.cpp:69 ../../XS7.cpp:104
|
#: ../../XS7.cpp:102
|
||||||
msgid "Could not launch default file manager"
|
msgid "Could not launch default file manager"
|
||||||
msgstr "Échec de lancement du gestionnaire de fichier par défaut."
|
msgstr "Échec de lancement du gestionnaire de fichier par défaut."
|
||||||
|
|
||||||
#: ../../XS7.cpp:93 ../../XS7.cpp:128
|
#: ../../XS7.cpp:143
|
||||||
msgid "Invalid folder name."
|
msgid "Invalid folder name."
|
||||||
msgstr "Nom de dossier invalide."
|
msgstr "Nom de dossier invalide."
|
||||||
|
|
||||||
#: ../../XS7.cpp:101 ../../XS7.cpp:136
|
#: ../../XS7.cpp:151
|
||||||
msgid "Invalid file basename."
|
msgid "Invalid file basename."
|
||||||
msgstr "Nom de base de fichier invalide."
|
msgstr "Nom de base de fichier invalide."
|
||||||
|
|
||||||
#: ../../XS7.cpp:123 ../../XS7.cpp:158
|
|
||||||
msgid "Copyright: Saleem Edah-Tally [Surgeon] [Hobbyist developer]\n"
|
msgid "Copyright: Saleem Edah-Tally [Surgeon] [Hobbyist developer]\n"
|
||||||
msgstr "Copyright: Saleem Edah-Tally [Chirurgien] [Développeur par hobby]\n"
|
msgstr "Copyright: Saleem Edah-Tally [Chirurgien] [Développeur par hobby]\n"
|
||||||
|
|
||||||
#: ../../XS7.cpp:124 ../../XS7.cpp:159
|
#: ../../XS7.cpp:174
|
||||||
msgid "License: CeCILL/CeCILL-C per file header."
|
msgid "License: CeCILL/CeCILL-C per file header."
|
||||||
msgstr "Licence : CeCILL/CeCILL-C selon les entêtes de fichier."
|
msgstr "Licence : CeCILL/CeCILL-C selon les entêtes de fichier."
|
||||||
|
|
||||||
#: ../../Resources/UI/S7/s7.h:44 ../..//Resources/UI/S7/s7.h:44
|
#: ../../Resources/UI/S7/s7.h:44
|
||||||
msgid "S7"
|
msgid "S7"
|
||||||
msgstr "S7"
|
msgstr "S7"
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/UI/InsaneWidget.h:40
|
#: ../../Resources/InsaneWidget/UI/InsaneWidget.h:41
|
||||||
msgid "InsaneWidget"
|
msgid "InsaneWidget"
|
||||||
msgstr "InsaneWidget"
|
msgstr "InsaneWidget"
|
||||||
|
|
||||||
@@ -255,25 +229,22 @@ msgstr "Résolution :"
|
|||||||
msgid "Paper size:"
|
msgid "Paper size:"
|
||||||
msgstr "Format de page :"
|
msgstr "Format de page :"
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:332
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:451
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:316
|
|
||||||
msgid "Double sided:"
|
msgid "Double sided:"
|
||||||
msgstr "Recto-verso :"
|
msgstr "Recto-verso :"
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:334
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:453
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:318
|
|
||||||
msgid "Total:"
|
msgid "Total:"
|
||||||
msgstr "Total :"
|
msgstr "Total :"
|
||||||
|
|
||||||
#: ../../XS7.cpp:46 ../../XS7.cpp:81
|
#: ../../XS7.cpp:50
|
||||||
msgid "'Shift + left' click to generate a new destination file name."
|
msgid "'Shift + left' click to generate a new destination file name."
|
||||||
msgstr "'Maj + clic gauche' pour générer un nouveau fichier de sortie."
|
msgstr "'Maj + clic gauche' pour générer un nouveau fichier de sortie."
|
||||||
|
|
||||||
#: ../../XS7.cpp:121 ../../XS7.cpp:45 ../../XS7.cpp:156
|
#: ../../Resources/UI/S7/s7app.cpp:174
|
||||||
msgid " - version "
|
msgid " - version "
|
||||||
msgstr " - version "
|
msgstr " - version "
|
||||||
|
|
||||||
#: ../../XS7.cpp:122 ../../XS7.cpp:157
|
|
||||||
msgid ""
|
msgid ""
|
||||||
", using InsaneWidget.\n"
|
", using InsaneWidget.\n"
|
||||||
"\n"
|
"\n"
|
||||||
@@ -281,22 +252,191 @@ msgstr ""
|
|||||||
", utilisant InsaneWidget.\n"
|
", utilisant InsaneWidget.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XScannerWidget.cpp:73
|
#: ../../Resources/InsaneWidget/XScannerWidget.cpp:112
|
||||||
msgid " device(s) found."
|
msgid " device(s) found."
|
||||||
msgstr " périphériques trouvé(s)."
|
msgstr " périphériques trouvé(s)."
|
||||||
|
|
||||||
#: ../../XS7.cpp:29
|
#: ../../Resources/UI/S7/s7app.cpp:158
|
||||||
msgid "Config file tag."
|
msgid "Config file tag."
|
||||||
msgstr "Suffixe du fichier de configuration."
|
msgstr "Suffixe du fichier de configuration."
|
||||||
|
|
||||||
#: ../../XS7.cpp:30
|
#: ../../Resources/UI/S7/s7app.cpp:159
|
||||||
msgid "Show version and quit."
|
msgid "Show version and quit."
|
||||||
msgstr "Afficher la version et quitter."
|
msgstr "Afficher la version et quitter."
|
||||||
|
|
||||||
#: ../../XS7.cpp:31
|
#: ../../Resources/UI/S7/s7app.cpp:160
|
||||||
msgid "Show help and quit."
|
msgid "Show help and quit."
|
||||||
msgstr "Afficher l'aide et quitter."
|
msgstr "Afficher l'aide et quitter."
|
||||||
|
|
||||||
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:352
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:515
|
||||||
msgid "Destination file missing."
|
msgid "Destination file missing."
|
||||||
msgstr "Fichier de destination manquant."
|
msgstr "Fichier de destination manquant."
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/UI/StampWidget.cpp:140
|
||||||
|
msgid ""
|
||||||
|
"Create a stamp with this text, which can be multiline.\n"
|
||||||
|
"\n"
|
||||||
|
"CTRL + S: save the current text.\n"
|
||||||
|
"CTRL + R: restore the saved text."
|
||||||
|
msgstr ""
|
||||||
|
"Créer un tampon utilisant ce texte qui peut être multi-ligne.\n"
|
||||||
|
"\n"
|
||||||
|
"CTRL + S : sauvegarder le texte actuel.\n"
|
||||||
|
"CTRL + R : restaurer le texte sauvegardé."
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/UI/StampWidget.cpp:188
|
||||||
|
msgid "Select the font of the stamp text."
|
||||||
|
msgstr "Sélectionnez la police de caractère du texte."
|
||||||
|
|
||||||
|
msgid "Select the colour of the stamp text."
|
||||||
|
msgstr "Sélectionnez la couleur du texte."
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/UI/StampWidget.cpp:199
|
||||||
|
msgid "Select the rotation angle of the stamp text."
|
||||||
|
msgstr "Sélectionnez l'angle de rotation du texte."
|
||||||
|
|
||||||
|
msgid "Stamp"
|
||||||
|
msgstr "Tampon"
|
||||||
|
|
||||||
|
#: ../../Resources/InsaneWidget/PixelToImageWriter.cpp:35
|
||||||
|
msgid "Failed to read raw file."
|
||||||
|
msgstr "Échec de lecture du fichier brut."
|
||||||
|
|
||||||
|
#: ../../Resources/InsaneWidget/PixelToImageWriter.cpp:69
|
||||||
|
msgid "Unhandled output image format."
|
||||||
|
msgstr "Format de fichier d'image en sortie non pris en charge."
|
||||||
|
|
||||||
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:270
|
||||||
|
msgid "Failed to create output image."
|
||||||
|
msgstr "Échec de création de l'image de sortie."
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/UI/StampWidget.h:57
|
||||||
|
msgid "StampWidget"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/UI/StampWidget.cpp:171
|
||||||
|
msgid "Location of the stamp on the output."
|
||||||
|
msgstr "Place du tampon dans la sortie."
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/UI/StampWidgets.cpp:127
|
||||||
|
msgid "+"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/UI/StampWidgets.cpp:129
|
||||||
|
msgid "Add a stamp widget."
|
||||||
|
msgstr "Ajouter un widget 'Tampon'."
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/UI/StampWidgets.cpp:132
|
||||||
|
msgid "-"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/UI/StampWidgets.cpp:134
|
||||||
|
msgid "Remove the selected stamp widget."
|
||||||
|
msgstr "Supprimer le widget 'Tampon' sélectionné."
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/XStampWidget.cpp:76
|
||||||
|
msgid "Centre"
|
||||||
|
msgstr "Centre"
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/XStampWidget.cpp:77
|
||||||
|
msgid "North"
|
||||||
|
msgstr "Nord"
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/XStampWidget.cpp:77
|
||||||
|
msgid "South"
|
||||||
|
msgstr "Sud"
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/XStampWidget.cpp:77
|
||||||
|
msgid "West"
|
||||||
|
msgstr "Ouest"
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/XStampWidget.cpp:78
|
||||||
|
msgid "North-east"
|
||||||
|
msgstr "Nord-est"
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/XStampWidget.cpp:78
|
||||||
|
msgid "North-west"
|
||||||
|
msgstr "Nord-ouest"
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/XStampWidget.cpp:79
|
||||||
|
msgid "South-east"
|
||||||
|
msgstr "Sud-est"
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/XStampWidget.cpp:79
|
||||||
|
msgid "South-west"
|
||||||
|
msgstr "Sud-ouest"
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/XStampWidget.cpp:77
|
||||||
|
msgid "East"
|
||||||
|
msgstr "Est"
|
||||||
|
|
||||||
|
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:141
|
||||||
|
msgid ""
|
||||||
|
"'Left click' to start the scan project.\n"
|
||||||
|
"'Right click' to show the scanner widget.\n"
|
||||||
|
"'Ctrl + Right click' to show the Stamp dialog."
|
||||||
|
msgstr ""
|
||||||
|
"'Clic gauche' pour démarrer la numérisation.\n"
|
||||||
|
"'Clic droit' pour afficher les options du numériseur.\n"
|
||||||
|
"'Ctrl + Clic droit' pour définir un tampon."
|
||||||
|
|
||||||
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:477
|
||||||
|
msgid "Stamps"
|
||||||
|
msgstr "Tampons"
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/UI/StampWidgets.h:44
|
||||||
|
msgid "StampWidgets"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/UI/StampWidget.cpp:149
|
||||||
|
msgid "Foreground:"
|
||||||
|
msgstr "Avant-plan :"
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/UI/StampWidget.cpp:154
|
||||||
|
msgid "Foreground colour of the text."
|
||||||
|
msgstr "Couleur du texte."
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/UI/StampWidget.cpp:157
|
||||||
|
msgid "Background:"
|
||||||
|
msgstr "Arrière-plan :"
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/UI/StampWidget.cpp:162
|
||||||
|
msgid "Background colour of the text."
|
||||||
|
msgstr "Couleur de l'arrière-plan."
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/UI/StampWidget.cpp:165
|
||||||
|
msgid "Location:"
|
||||||
|
msgstr "Position :"
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/UI/StampWidget.cpp:177
|
||||||
|
msgid "Click to update the preview."
|
||||||
|
msgstr "Cliquez pour actualiser l'aperçu."
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/UI/StampWidget.cpp:191
|
||||||
|
msgid "Transparent"
|
||||||
|
msgstr "Transparent"
|
||||||
|
|
||||||
|
#: ../../Resources/StampWidget/UI/StampWidget.cpp:194
|
||||||
|
msgid ""
|
||||||
|
"Check for a completely transparent background and for a transparent text."
|
||||||
|
msgstr "Activez la transparence du texte et de l'arrière-plan. "
|
||||||
|
|
||||||
|
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:189
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr "Annuler"
|
||||||
|
|
||||||
|
#: ../../XS7.cpp:75
|
||||||
|
msgid "Veto: scanner discovery is running."
|
||||||
|
msgstr "Veto : recherche de périphériques en cours."
|
||||||
|
|
||||||
|
#: ../../XS7.cpp:173
|
||||||
|
msgid "Copyright: Saleem Edah-Tally [Surgeon] [Hobbyist developer]"
|
||||||
|
msgstr "Copyright: Saleem Edah-Tally [Chirurgien] [Développeur par hobby]"
|
||||||
|
|
||||||
|
#: ../../XS7.cpp:175
|
||||||
|
msgid "version "
|
||||||
|
msgstr "version "
|
||||||
|
|
||||||
|
#: ../../XS7.cpp:175
|
||||||
|
msgid ", using InsaneWidget."
|
||||||
|
msgstr ", utilisant InsaneWidget."
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#Simple PKGBUILD that suits my need.
|
#Simple PKGBUILD that suits my need.
|
||||||
|
|
||||||
pkgname=(s7)
|
pkgname=(s7)
|
||||||
pkgver=1
|
pkgver=2
|
||||||
pkgrel=0
|
pkgrel=0
|
||||||
arch=('x86_64' 'i686' 'armv7h' 'aarch64')
|
arch=('x86_64' 'i686' 'armv7h' 'aarch64')
|
||||||
url='http://github.com/nmset/s7/'
|
url='http://github.com/nmset/s7/'
|
||||||
|
|||||||
22
Resources/StampWidget/CMakeLists.txt
Normal file
22
Resources/StampWidget/CMakeLists.txt
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
project(StampWidget)
|
||||||
|
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
|
||||||
|
|
||||||
|
find_package(wxWidgets COMPONENTS base core CONFIG REQUIRED)
|
||||||
|
|
||||||
|
include_directories(${CMAKE_CURRENT_LIST_DIR}
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/UI)
|
||||||
|
|
||||||
|
add_library(stampwidget STATIC
|
||||||
|
|
||||||
|
DefsStampWidget.h
|
||||||
|
UI/StampWidget.cpp
|
||||||
|
UI/StampWidgets.cpp
|
||||||
|
XStampWidget.cpp
|
||||||
|
XStampWidgets.cpp
|
||||||
|
StampWorker.cpp)
|
||||||
|
|
||||||
|
target_link_libraries(stampwidget
|
||||||
|
${wxWidgets_LIBRARIES})
|
||||||
30
Resources/StampWidget/DefsStampWidget.h
Normal file
30
Resources/StampWidget/DefsStampWidget.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
// /*
|
||||||
|
// * File: Common.h
|
||||||
|
// * Author: Saleem Edah-Tally - nmset@yandex.com
|
||||||
|
// * License : CeCILL-C
|
||||||
|
// * Copyright Saleem Edah-Tally - © 2025
|
||||||
|
// *
|
||||||
|
// * Created on 27 06 2025, 20:34
|
||||||
|
// */
|
||||||
|
|
||||||
|
#ifndef COMMON_H
|
||||||
|
#define COMMON_H
|
||||||
|
|
||||||
|
#include <wx/wx.h>
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
enum {CENTRE = 0, NORTH, SOUTH, EAST, WEST,
|
||||||
|
NORTH_EAST, NORTH_WEST, SOUTH_EAST, SOUTH_WEST};
|
||||||
|
|
||||||
|
struct StampDescriptor
|
||||||
|
{
|
||||||
|
wxImage image;
|
||||||
|
wxString text;
|
||||||
|
wxFont font = wxNullFont;
|
||||||
|
wxColour foregroundColour = wxNullColour;
|
||||||
|
wxColour backgroundColour = wxNullColour;
|
||||||
|
int rotationAngle = 45;
|
||||||
|
int location = 0;
|
||||||
|
bool transparent = true;
|
||||||
|
};
|
||||||
|
#endif // COMMON_H
|
||||||
121
Resources/StampWidget/StampWorker.cpp
Normal file
121
Resources/StampWidget/StampWorker.cpp
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
// /*
|
||||||
|
// * File: StampWorker.cpp
|
||||||
|
// * Author: Saleem Edah-Tally - nmset@yandex.com
|
||||||
|
// * License : CeCILL-C
|
||||||
|
// * Copyright Saleem Edah-Tally - © 2025
|
||||||
|
// *
|
||||||
|
// * Created on 02 07 2025, 21:23
|
||||||
|
// */
|
||||||
|
|
||||||
|
#include "StampWorker.h"
|
||||||
|
#include <math.h> // M_PI
|
||||||
|
|
||||||
|
wxImage StampWorker::CreateStamp(StampDescriptor * descriptor, int scanResolution)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Rescale the font point size of the stamp according to the scan resolution.
|
||||||
|
* Exclude rescaling on v4l that does not have a resolution parameter.
|
||||||
|
*/
|
||||||
|
wxFont dcFont(descriptor->font);
|
||||||
|
double scale = (scanResolution > 0)
|
||||||
|
? (double) scanResolution / 72.0
|
||||||
|
:1.0;
|
||||||
|
|
||||||
|
wxCoord extentWidth, extentHeight, textLineHeight;
|
||||||
|
{
|
||||||
|
wxMemoryDC dc;
|
||||||
|
if (scale != 1.0)
|
||||||
|
dcFont.SetFractionalPointSize(descriptor->font.GetFractionalPointSize() * scale);
|
||||||
|
dc.SetFont(dcFont); // Mandatory despite set below.
|
||||||
|
dc.GetMultiLineTextExtent(descriptor->text, &extentWidth, &extentHeight, &textLineHeight, &dcFont);
|
||||||
|
}
|
||||||
|
wxBitmap bmp;
|
||||||
|
// bmp.UseAlpha(true); // Not mandatory.
|
||||||
|
bmp.Create(extentWidth, extentHeight); // Memo: See CreateWithDIPSize
|
||||||
|
wxImage img0, img;
|
||||||
|
|
||||||
|
wxMemoryDC dc(bmp);
|
||||||
|
dc.SetFont(dcFont);
|
||||||
|
if (descriptor->transparent)
|
||||||
|
{
|
||||||
|
// +++, Use the red channel only: used by ConvertColourToAlpha().
|
||||||
|
// The chosen value is inversely proportional to the transparency of the text itself.
|
||||||
|
dc.SetTextForeground(wxColour(128, 0, 0)); // A good mean is reasonable.
|
||||||
|
dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dc.SetTextForeground(descriptor->foregroundColour);
|
||||||
|
dc.SetTextBackground(descriptor->backgroundColour);
|
||||||
|
dc.SetBackgroundMode(wxBRUSHSTYLE_SOLID);
|
||||||
|
}
|
||||||
|
|
||||||
|
dc.DrawText(descriptor->text, wxPoint(0, 0));
|
||||||
|
|
||||||
|
img0 = bmp.ConvertToImage();
|
||||||
|
if (!descriptor->transparent)
|
||||||
|
img0.InitAlpha(); // So that there is no dark surrounding if it is rotated.
|
||||||
|
|
||||||
|
img = img0.Rotate((M_PI / 180.0) * descriptor->rotationAngle, wxPoint(0, 0));
|
||||||
|
if (descriptor->transparent)
|
||||||
|
{
|
||||||
|
img.ConvertColourToAlpha(descriptor->foregroundColour.GetRed(),
|
||||||
|
descriptor->foregroundColour.GetGreen(),
|
||||||
|
descriptor->foregroundColour.GetBlue()); // The target colour is passed in.
|
||||||
|
img.ChangeSaturation(-0.7); // Slightly better looking.
|
||||||
|
}
|
||||||
|
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StampWorker::StampBackground(wxImage& background,
|
||||||
|
const wxImage& stamp, int location)
|
||||||
|
{
|
||||||
|
// Simply pasting the stamp on the background, i.e., the scanned page.
|
||||||
|
wxPoint bgCentre(background.GetWidth() / 2, background.GetHeight() / 2);
|
||||||
|
wxPoint stampCentre(stamp.GetWidth() / 2, stamp.GetHeight() / 2);
|
||||||
|
int x = 0, y = 0;
|
||||||
|
switch (location)
|
||||||
|
{
|
||||||
|
case NORTH:
|
||||||
|
x = bgCentre.x - stampCentre.x;
|
||||||
|
y = 0;
|
||||||
|
break;
|
||||||
|
case SOUTH:
|
||||||
|
x = bgCentre.x - stampCentre.x;
|
||||||
|
y = background.GetHeight() - stamp.GetHeight();
|
||||||
|
break;
|
||||||
|
case EAST:
|
||||||
|
x = background.GetWidth() - stamp.GetWidth();
|
||||||
|
y = bgCentre.y - stampCentre.y;
|
||||||
|
break;
|
||||||
|
case WEST:
|
||||||
|
x = 0;
|
||||||
|
y = bgCentre.y - stampCentre.y;
|
||||||
|
break;
|
||||||
|
case NORTH_EAST:
|
||||||
|
x = background.GetWidth() - stamp.GetWidth();
|
||||||
|
y = 0;
|
||||||
|
break;
|
||||||
|
case NORTH_WEST:
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
break;
|
||||||
|
case SOUTH_EAST:
|
||||||
|
x = background.GetWidth() - stamp.GetWidth();
|
||||||
|
y = background.GetHeight() - stamp.GetHeight();
|
||||||
|
break;
|
||||||
|
case SOUTH_WEST:
|
||||||
|
x = 0;
|
||||||
|
y = background.GetHeight() - stamp.GetHeight();
|
||||||
|
break;
|
||||||
|
default: // CENTRE
|
||||||
|
x = bgCentre.x - stampCentre.x;
|
||||||
|
y = bgCentre.y - stampCentre.y;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxPoint stampLocation(x, y);
|
||||||
|
background.Paste(stamp, stampLocation.x, stampLocation.y, wxIMAGE_ALPHA_BLEND_COMPOSE);
|
||||||
|
}
|
||||||
|
|
||||||
38
Resources/StampWidget/StampWorker.h
Normal file
38
Resources/StampWidget/StampWorker.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// /*
|
||||||
|
// * File: StampWorker.h
|
||||||
|
// * Author: Saleem Edah-Tally - nmset@yandex.com
|
||||||
|
// * License : CeCILL-C
|
||||||
|
// * Copyright Saleem Edah-Tally - © 2025
|
||||||
|
// *
|
||||||
|
// * Created on 02 07 2025, 21:23
|
||||||
|
// */
|
||||||
|
|
||||||
|
#ifndef STAMPWORKER_H
|
||||||
|
#define STAMPWORKER_H
|
||||||
|
|
||||||
|
#include <wx/wx.h>
|
||||||
|
#include "DefsStampWidget.h"
|
||||||
|
|
||||||
|
struct StampDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A stamp is understood here as\n
|
||||||
|
* - a transparent text in a transparent frame with no borders\n
|
||||||
|
* - an opaque text on an opaque background with no borders.\n
|
||||||
|
*
|
||||||
|
* The text may be rotated. Actually, an initial image with the text is rotated
|
||||||
|
* and its new orthogonal bounds accepted (fortunately, we don't have to compute
|
||||||
|
* that).\n
|
||||||
|
* The font point size is rescaled to match the scan resolution. If the
|
||||||
|
* scanResolution parameter is invalid (<=0), the font is not rescaled.
|
||||||
|
*/
|
||||||
|
class StampWorker
|
||||||
|
{
|
||||||
|
DECLARE_DYNAMIC_CLASS( StampWorker )
|
||||||
|
public:
|
||||||
|
static wxImage CreateStamp(StampDescriptor * descriptor, int scanResolution = -1);
|
||||||
|
static void StampBackground(wxImage& background, const wxImage& stamp, int location = CENTRE);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // STAMPWORKER_H
|
||||||
239
Resources/StampWidget/UI/StampWidget.cpp
Normal file
239
Resources/StampWidget/UI/StampWidget.cpp
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: StampWidget.cpp
|
||||||
|
// Purpose:
|
||||||
|
// Author: Saleem EDAH-TALLY
|
||||||
|
// Modified by:
|
||||||
|
// Created: mar. 01 juil. 2025 19:14:05
|
||||||
|
// RCS-ID:
|
||||||
|
// Copyright: Copyright Saleem EDAH-TALLY. All rights reserved.
|
||||||
|
// Licence:
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// For compilers that support precompilation, includes "wx/wx.h".
|
||||||
|
#include "wx/wxprec.h"
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
#pragma hdrstop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WX_PRECOMP
|
||||||
|
#include "wx/wx.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////@begin includes
|
||||||
|
////@end includes
|
||||||
|
|
||||||
|
#include "StampWidget.h"
|
||||||
|
|
||||||
|
////@begin XPM images
|
||||||
|
////@end XPM images
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* StampWidget type definition
|
||||||
|
*/
|
||||||
|
|
||||||
|
IMPLEMENT_DYNAMIC_CLASS( StampWidget, wxPanel )
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* StampWidget event table definition
|
||||||
|
*/
|
||||||
|
|
||||||
|
BEGIN_EVENT_TABLE( StampWidget, wxPanel )
|
||||||
|
|
||||||
|
////@begin StampWidget event table entries
|
||||||
|
////@end StampWidget event table entries
|
||||||
|
|
||||||
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* StampWidget constructors
|
||||||
|
*/
|
||||||
|
|
||||||
|
StampWidget::StampWidget()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
StampWidget::StampWidget( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
Create(parent, id, pos, size, style);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* StampWidget creator
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool StampWidget::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
|
||||||
|
{
|
||||||
|
////@begin StampWidget creation
|
||||||
|
SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);
|
||||||
|
wxPanel::Create( parent, id, pos, size, style );
|
||||||
|
|
||||||
|
CreateControls();
|
||||||
|
if (GetSizer())
|
||||||
|
{
|
||||||
|
GetSizer()->SetSizeHints(this);
|
||||||
|
}
|
||||||
|
Centre();
|
||||||
|
////@end StampWidget creation
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* StampWidget destructor
|
||||||
|
*/
|
||||||
|
|
||||||
|
StampWidget::~StampWidget()
|
||||||
|
{
|
||||||
|
////@begin StampWidget destruction
|
||||||
|
////@end StampWidget destruction
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Member initialisation
|
||||||
|
*/
|
||||||
|
|
||||||
|
void StampWidget::Init()
|
||||||
|
{
|
||||||
|
////@begin StampWidget member initialisation
|
||||||
|
szStampWidgetMain = NULL;
|
||||||
|
txtStamp = NULL;
|
||||||
|
szStampWidgetH0 = NULL;
|
||||||
|
szStampWidgetFlexGrid = NULL;
|
||||||
|
lblForegroundColour = NULL;
|
||||||
|
cpkForegroundStamp = NULL;
|
||||||
|
lblBackgroundColour = NULL;
|
||||||
|
cpkBackgroundStamp = NULL;
|
||||||
|
lblLocation = NULL;
|
||||||
|
cmbStampLocation = NULL;
|
||||||
|
panBitmapPreview = NULL;
|
||||||
|
szBitmapPreviewInPanel = NULL;
|
||||||
|
szStampWidgetH1 = NULL;
|
||||||
|
fpkStamp = NULL;
|
||||||
|
tglTransparent = NULL;
|
||||||
|
sldTextRotationAngle = NULL;
|
||||||
|
////@end StampWidget member initialisation
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Control creation for StampWidget
|
||||||
|
*/
|
||||||
|
|
||||||
|
void StampWidget::CreateControls()
|
||||||
|
{
|
||||||
|
////@begin StampWidget content construction
|
||||||
|
StampWidget* itemPanel1 = this;
|
||||||
|
|
||||||
|
szStampWidgetMain = new wxBoxSizer(wxVERTICAL);
|
||||||
|
itemPanel1->SetSizer(szStampWidgetMain);
|
||||||
|
|
||||||
|
txtStamp = new wxTextCtrl( itemPanel1, ID_TEXTCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE );
|
||||||
|
if (StampWidget::ShowToolTips())
|
||||||
|
txtStamp->SetToolTip(_("Create a stamp with this text, which can be multiline.\n\nCTRL + S: save the current text.\nCTRL + R: restore the saved text."));
|
||||||
|
szStampWidgetMain->Add(txtStamp, 0, wxGROW|wxALL, 5);
|
||||||
|
|
||||||
|
szStampWidgetH0 = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
szStampWidgetMain->Add(szStampWidgetH0, 0, wxALIGN_LEFT|wxALL, 5);
|
||||||
|
|
||||||
|
szStampWidgetFlexGrid = new wxFlexGridSizer(0, 2, 0, 0);
|
||||||
|
szStampWidgetH0->Add(szStampWidgetFlexGrid, 1, wxGROW|wxALL, 5);
|
||||||
|
|
||||||
|
lblForegroundColour = new wxStaticText( itemPanel1, ID_STATIC_FOREGROUND_COLOUR, _("Foreground:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
szStampWidgetFlexGrid->Add(lblForegroundColour, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||||
|
|
||||||
|
cpkForegroundStamp = new wxColourPickerCtrl( itemPanel1, ID_COLOURCTRL_FOREGROUND, wxColour(), wxDefaultPosition, wxDefaultSize, wxCLRP_DEFAULT_STYLE );
|
||||||
|
if (StampWidget::ShowToolTips())
|
||||||
|
cpkForegroundStamp->SetToolTip(_("Foreground colour of the text."));
|
||||||
|
szStampWidgetFlexGrid->Add(cpkForegroundStamp, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||||
|
|
||||||
|
lblBackgroundColour = new wxStaticText( itemPanel1, ID_STATIC_BACKGROUND_COLOUR, _("Background:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
szStampWidgetFlexGrid->Add(lblBackgroundColour, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||||
|
|
||||||
|
cpkBackgroundStamp = new wxColourPickerCtrl( itemPanel1, ID_COLOURCTRL_BACKGROUND, wxColour(255, 255, 255), wxDefaultPosition, wxDefaultSize, wxCLRP_DEFAULT_STYLE );
|
||||||
|
if (StampWidget::ShowToolTips())
|
||||||
|
cpkBackgroundStamp->SetToolTip(_("Background colour of the text."));
|
||||||
|
szStampWidgetFlexGrid->Add(cpkBackgroundStamp, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||||
|
|
||||||
|
lblLocation = new wxStaticText( itemPanel1, ID_STATIC_LOCATION, _("Location:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
szStampWidgetFlexGrid->Add(lblLocation, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||||
|
|
||||||
|
wxArrayString cmbStampLocationStrings;
|
||||||
|
cmbStampLocation = new wxComboBox( itemPanel1, ID_COMBOBOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, cmbStampLocationStrings, wxCB_READONLY );
|
||||||
|
if (StampWidget::ShowToolTips())
|
||||||
|
cmbStampLocation->SetToolTip(_("Location of the stamp on the output."));
|
||||||
|
szStampWidgetFlexGrid->Add(cmbStampLocation, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||||
|
|
||||||
|
panBitmapPreview = new wxPanel( itemPanel1, ID_PANEL_BITMAP_PREVIEW, wxDefaultPosition, wxSize(200, 200), wxSUNKEN_BORDER|wxTAB_TRAVERSAL );
|
||||||
|
panBitmapPreview->SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);
|
||||||
|
if (StampWidget::ShowToolTips())
|
||||||
|
panBitmapPreview->SetToolTip(_("Click to update the preview."));
|
||||||
|
szStampWidgetH0->Add(panBitmapPreview, 0, wxALIGN_TOP|wxALL, 5);
|
||||||
|
|
||||||
|
szBitmapPreviewInPanel = new wxBoxSizer(wxVERTICAL);
|
||||||
|
panBitmapPreview->SetSizer(szBitmapPreviewInPanel);
|
||||||
|
|
||||||
|
szStampWidgetH1 = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
szStampWidgetMain->Add(szStampWidgetH1, 0, wxGROW|wxALL, 5);
|
||||||
|
|
||||||
|
fpkStamp = new wxFontPickerCtrl( itemPanel1, ID_FONTCTRL, wxFont(), wxDefaultPosition, wxDefaultSize, wxFNTP_FONTDESC_AS_LABEL );
|
||||||
|
if (StampWidget::ShowToolTips())
|
||||||
|
fpkStamp->SetToolTip(_("Select the font of the stamp text."));
|
||||||
|
szStampWidgetH1->Add(fpkStamp, 1, wxGROW|wxALL, 5);
|
||||||
|
|
||||||
|
tglTransparent = new wxToggleButton( itemPanel1, ID_TOGGLE_TRANSPARENT, _("Transparent"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
tglTransparent->SetValue(true);
|
||||||
|
if (StampWidget::ShowToolTips())
|
||||||
|
tglTransparent->SetToolTip(_("Check for a completely transparent background and for a transparent text."));
|
||||||
|
szStampWidgetH1->Add(tglTransparent, 0, wxGROW|wxALL, 5);
|
||||||
|
|
||||||
|
sldTextRotationAngle = new wxSlider( itemPanel1, ID_SLIDER, 45, -180, 180, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL|wxSL_AUTOTICKS|wxSL_LABELS );
|
||||||
|
if (StampWidget::ShowToolTips())
|
||||||
|
sldTextRotationAngle->SetToolTip(_("Select the rotation angle of the stamp text."));
|
||||||
|
szStampWidgetMain->Add(sldTextRotationAngle, 0, wxGROW|wxALL, 5);
|
||||||
|
|
||||||
|
////@end StampWidget content construction
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Should we show tooltips?
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool StampWidget::ShowToolTips()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get bitmap resources
|
||||||
|
*/
|
||||||
|
|
||||||
|
wxBitmap StampWidget::GetBitmapResource( const wxString& name )
|
||||||
|
{
|
||||||
|
// Bitmap retrieval
|
||||||
|
////@begin StampWidget bitmap retrieval
|
||||||
|
wxUnusedVar(name);
|
||||||
|
return wxNullBitmap;
|
||||||
|
////@end StampWidget bitmap retrieval
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get icon resources
|
||||||
|
*/
|
||||||
|
|
||||||
|
wxIcon StampWidget::GetIconResource( const wxString& name )
|
||||||
|
{
|
||||||
|
// Icon retrieval
|
||||||
|
////@begin StampWidget icon retrieval
|
||||||
|
wxUnusedVar(name);
|
||||||
|
return wxNullIcon;
|
||||||
|
////@end StampWidget icon retrieval
|
||||||
|
}
|
||||||
129
Resources/StampWidget/UI/StampWidget.h
Normal file
129
Resources/StampWidget/UI/StampWidget.h
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: StampWidget.h
|
||||||
|
// Purpose:
|
||||||
|
// Author: Saleem EDAH-TALLY
|
||||||
|
// Modified by:
|
||||||
|
// Created: mar. 01 juil. 2025 19:14:05
|
||||||
|
// RCS-ID:
|
||||||
|
// Copyright: Copyright Saleem EDAH-TALLY. All rights reserved.
|
||||||
|
// Licence:
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef _STAMPWIDGET_H_
|
||||||
|
#define _STAMPWIDGET_H_
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Includes
|
||||||
|
*/
|
||||||
|
|
||||||
|
////@begin includes
|
||||||
|
#include "wx/clrpicker.h"
|
||||||
|
#include "wx/fontpicker.h"
|
||||||
|
#include "wx/tglbtn.h"
|
||||||
|
////@end includes
|
||||||
|
#include "wx/combobox.h"
|
||||||
|
#include "wx/stattext.h"
|
||||||
|
/*!
|
||||||
|
* Forward declarations
|
||||||
|
*/
|
||||||
|
|
||||||
|
////@begin forward declarations
|
||||||
|
class wxBoxSizer;
|
||||||
|
class wxFlexGridSizer;
|
||||||
|
class wxColourPickerCtrl;
|
||||||
|
class wxFontPickerCtrl;
|
||||||
|
class wxToggleButton;
|
||||||
|
////@end forward declarations
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Control identifiers
|
||||||
|
*/
|
||||||
|
|
||||||
|
////@begin control identifiers
|
||||||
|
#define ID_STAMPWIDGET 10000
|
||||||
|
#define ID_TEXTCTRL 10001
|
||||||
|
#define ID_STATIC_FOREGROUND_COLOUR 10008
|
||||||
|
#define ID_COLOURCTRL_FOREGROUND 10003
|
||||||
|
#define ID_STATIC_BACKGROUND_COLOUR 10009
|
||||||
|
#define ID_COLOURCTRL_BACKGROUND 10006
|
||||||
|
#define ID_STATIC_LOCATION 10010
|
||||||
|
#define ID_COMBOBOX 10005
|
||||||
|
#define ID_PANEL_BITMAP_PREVIEW 10011
|
||||||
|
#define ID_FONTCTRL 10002
|
||||||
|
#define ID_TOGGLE_TRANSPARENT 10007
|
||||||
|
#define ID_SLIDER 10004
|
||||||
|
#define SYMBOL_STAMPWIDGET_STYLE wxTAB_TRAVERSAL
|
||||||
|
#define SYMBOL_STAMPWIDGET_TITLE _("StampWidget")
|
||||||
|
#define SYMBOL_STAMPWIDGET_IDNAME ID_STAMPWIDGET
|
||||||
|
#define SYMBOL_STAMPWIDGET_SIZE wxSize(400, 300)
|
||||||
|
#define SYMBOL_STAMPWIDGET_POSITION wxDefaultPosition
|
||||||
|
////@end control identifiers
|
||||||
|
|
||||||
|
#include <wx/panel.h>
|
||||||
|
#include <wx/slider.h>
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* StampWidget class declaration
|
||||||
|
*/
|
||||||
|
|
||||||
|
class StampWidget: public wxPanel
|
||||||
|
{
|
||||||
|
DECLARE_DYNAMIC_CLASS( StampWidget )
|
||||||
|
DECLARE_EVENT_TABLE()
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructors
|
||||||
|
StampWidget();
|
||||||
|
StampWidget( wxWindow* parent, wxWindowID id = SYMBOL_STAMPWIDGET_IDNAME, const wxPoint& pos = SYMBOL_STAMPWIDGET_POSITION, const wxSize& size = SYMBOL_STAMPWIDGET_SIZE, long style = SYMBOL_STAMPWIDGET_STYLE );
|
||||||
|
|
||||||
|
/// Creation
|
||||||
|
bool Create( wxWindow* parent, wxWindowID id = SYMBOL_STAMPWIDGET_IDNAME, const wxPoint& pos = SYMBOL_STAMPWIDGET_POSITION, const wxSize& size = SYMBOL_STAMPWIDGET_SIZE, long style = SYMBOL_STAMPWIDGET_STYLE );
|
||||||
|
|
||||||
|
/// Destructor
|
||||||
|
~StampWidget();
|
||||||
|
|
||||||
|
/// Initialises member variables
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
/// Creates the controls and sizers
|
||||||
|
void CreateControls();
|
||||||
|
|
||||||
|
////@begin StampWidget event handler declarations
|
||||||
|
|
||||||
|
////@end StampWidget event handler declarations
|
||||||
|
|
||||||
|
////@begin StampWidget member function declarations
|
||||||
|
|
||||||
|
/// Retrieves bitmap resources
|
||||||
|
wxBitmap GetBitmapResource( const wxString& name );
|
||||||
|
|
||||||
|
/// Retrieves icon resources
|
||||||
|
wxIcon GetIconResource( const wxString& name );
|
||||||
|
////@end StampWidget member function declarations
|
||||||
|
|
||||||
|
/// Should we show tooltips?
|
||||||
|
static bool ShowToolTips();
|
||||||
|
|
||||||
|
////@begin StampWidget member variables
|
||||||
|
wxBoxSizer* szStampWidgetMain;
|
||||||
|
wxTextCtrl* txtStamp;
|
||||||
|
wxBoxSizer* szStampWidgetH0;
|
||||||
|
wxFlexGridSizer* szStampWidgetFlexGrid;
|
||||||
|
wxStaticText* lblForegroundColour;
|
||||||
|
wxColourPickerCtrl* cpkForegroundStamp;
|
||||||
|
wxStaticText* lblBackgroundColour;
|
||||||
|
wxColourPickerCtrl* cpkBackgroundStamp;
|
||||||
|
wxStaticText* lblLocation;
|
||||||
|
wxComboBox* cmbStampLocation;
|
||||||
|
wxPanel* panBitmapPreview;
|
||||||
|
wxBoxSizer* szBitmapPreviewInPanel;
|
||||||
|
wxBoxSizer* szStampWidgetH1;
|
||||||
|
wxFontPickerCtrl* fpkStamp;
|
||||||
|
wxToggleButton* tglTransparent;
|
||||||
|
wxSlider* sldTextRotationAngle;
|
||||||
|
////@end StampWidget member variables
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
// _STAMPWIDGET_H_
|
||||||
1612
Resources/StampWidget/UI/StampWidget.pjd
Normal file
1612
Resources/StampWidget/UI/StampWidget.pjd
Normal file
File diff suppressed because it is too large
Load Diff
1
Resources/StampWidget/UI/StampWidget.rc
Normal file
1
Resources/StampWidget/UI/StampWidget.rc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
#include "wx/msw/wx.rc"
|
||||||
178
Resources/StampWidget/UI/StampWidgets.cpp
Normal file
178
Resources/StampWidget/UI/StampWidgets.cpp
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: StampWidgets.cpp
|
||||||
|
// Purpose:
|
||||||
|
// Author: Saleem EDAH-TALLY
|
||||||
|
// Modified by:
|
||||||
|
// Created: dim. 06 juil. 2025 22:33:34
|
||||||
|
// RCS-ID:
|
||||||
|
// Copyright: Copyright Saleem EDAH-TALLY. All rights reserved.
|
||||||
|
// Licence:
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// For compilers that support precompilation, includes "wx/wx.h".
|
||||||
|
#include "wx/wxprec.h"
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
#pragma hdrstop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WX_PRECOMP
|
||||||
|
#include "wx/wx.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////@begin includes
|
||||||
|
#include "wx/imaglist.h"
|
||||||
|
////@end includes
|
||||||
|
|
||||||
|
#include "StampWidgets.h"
|
||||||
|
|
||||||
|
////@begin XPM images
|
||||||
|
////@end XPM images
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* StampWidgets type definition
|
||||||
|
*/
|
||||||
|
|
||||||
|
IMPLEMENT_DYNAMIC_CLASS( StampWidgets, wxPanel )
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* StampWidgets event table definition
|
||||||
|
*/
|
||||||
|
|
||||||
|
BEGIN_EVENT_TABLE( StampWidgets, wxPanel )
|
||||||
|
|
||||||
|
////@begin StampWidgets event table entries
|
||||||
|
////@end StampWidgets event table entries
|
||||||
|
|
||||||
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* StampWidgets constructors
|
||||||
|
*/
|
||||||
|
|
||||||
|
StampWidgets::StampWidgets()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
StampWidgets::StampWidgets( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
Create(parent, id, pos, size, style);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* StampWidgets creator
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool StampWidgets::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
|
||||||
|
{
|
||||||
|
////@begin StampWidgets creation
|
||||||
|
SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);
|
||||||
|
wxPanel::Create( parent, id, pos, size, style );
|
||||||
|
|
||||||
|
CreateControls();
|
||||||
|
Centre();
|
||||||
|
////@end StampWidgets creation
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* StampWidgets destructor
|
||||||
|
*/
|
||||||
|
|
||||||
|
StampWidgets::~StampWidgets()
|
||||||
|
{
|
||||||
|
////@begin StampWidgets destruction
|
||||||
|
////@end StampWidgets destruction
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Member initialisation
|
||||||
|
*/
|
||||||
|
|
||||||
|
void StampWidgets::Init()
|
||||||
|
{
|
||||||
|
////@begin StampWidgets member initialisation
|
||||||
|
szNoteBookMain = NULL;
|
||||||
|
szNoteBookButtons = NULL;
|
||||||
|
btnAddStampWidget = NULL;
|
||||||
|
btnDeleteStampWidget = NULL;
|
||||||
|
nbStampWidgets = NULL;
|
||||||
|
////@end StampWidgets member initialisation
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Control creation for StampWidgets
|
||||||
|
*/
|
||||||
|
|
||||||
|
void StampWidgets::CreateControls()
|
||||||
|
{
|
||||||
|
////@begin StampWidgets content construction
|
||||||
|
StampWidgets* itemPanel1 = this;
|
||||||
|
|
||||||
|
szNoteBookMain = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
itemPanel1->SetSizer(szNoteBookMain);
|
||||||
|
|
||||||
|
szNoteBookButtons = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
szNoteBookMain->Add(szNoteBookButtons, 0, wxALIGN_TOP, 5);
|
||||||
|
|
||||||
|
btnAddStampWidget = new wxButton( itemPanel1, ID_BUTTON_NB, _("+"), wxDefaultPosition, wxSize(30, -1), 0 );
|
||||||
|
if (StampWidgets::ShowToolTips())
|
||||||
|
btnAddStampWidget->SetToolTip(_("Add a stamp widget."));
|
||||||
|
szNoteBookButtons->Add(btnAddStampWidget, 0, wxALIGN_CENTER_VERTICAL|wxFIXED_MINSIZE, 1);
|
||||||
|
|
||||||
|
btnDeleteStampWidget = new wxButton( itemPanel1, ID_BUTTON_NB1, _("-"), wxDefaultPosition, wxSize(30, -1), 0 );
|
||||||
|
if (StampWidgets::ShowToolTips())
|
||||||
|
btnDeleteStampWidget->SetToolTip(_("Remove the selected stamp widget."));
|
||||||
|
szNoteBookButtons->Add(btnDeleteStampWidget, 0, wxALIGN_CENTER_VERTICAL, 1);
|
||||||
|
|
||||||
|
nbStampWidgets = new wxNotebook( itemPanel1, ID_NOTEBOOK_STAMPWIDGETS_, wxDefaultPosition, wxDefaultSize, wxBK_DEFAULT );
|
||||||
|
|
||||||
|
szNoteBookMain->Add(nbStampWidgets, 1, wxGROW|wxALL, 5);
|
||||||
|
|
||||||
|
////@end StampWidgets content construction
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Should we show tooltips?
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool StampWidgets::ShowToolTips()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get bitmap resources
|
||||||
|
*/
|
||||||
|
|
||||||
|
wxBitmap StampWidgets::GetBitmapResource( const wxString& name )
|
||||||
|
{
|
||||||
|
// Bitmap retrieval
|
||||||
|
////@begin StampWidgets bitmap retrieval
|
||||||
|
wxUnusedVar(name);
|
||||||
|
return wxNullBitmap;
|
||||||
|
////@end StampWidgets bitmap retrieval
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get icon resources
|
||||||
|
*/
|
||||||
|
|
||||||
|
wxIcon StampWidgets::GetIconResource( const wxString& name )
|
||||||
|
{
|
||||||
|
// Icon retrieval
|
||||||
|
////@begin StampWidgets icon retrieval
|
||||||
|
wxUnusedVar(name);
|
||||||
|
return wxNullIcon;
|
||||||
|
////@end StampWidgets icon retrieval
|
||||||
|
}
|
||||||
103
Resources/StampWidget/UI/StampWidgets.h
Normal file
103
Resources/StampWidget/UI/StampWidgets.h
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: StampWidgets.h
|
||||||
|
// Purpose:
|
||||||
|
// Author: Saleem EDAH-TALLY
|
||||||
|
// Modified by:
|
||||||
|
// Created: dim. 06 juil. 2025 22:33:34
|
||||||
|
// RCS-ID:
|
||||||
|
// Copyright: Copyright Saleem EDAH-TALLY. All rights reserved.
|
||||||
|
// Licence:
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef _STAMPWIDGETS_H_
|
||||||
|
#define _STAMPWIDGETS_H_
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Includes
|
||||||
|
*/
|
||||||
|
|
||||||
|
////@begin includes
|
||||||
|
#include "wx/notebook.h"
|
||||||
|
////@end includes
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Forward declarations
|
||||||
|
*/
|
||||||
|
|
||||||
|
////@begin forward declarations
|
||||||
|
class wxBoxSizer;
|
||||||
|
class wxNotebook;
|
||||||
|
////@end forward declarations
|
||||||
|
#include <wx/panel.h>
|
||||||
|
#include <wx/button.h>
|
||||||
|
/*!
|
||||||
|
* Control identifiers
|
||||||
|
*/
|
||||||
|
|
||||||
|
////@begin control identifiers
|
||||||
|
#define ID_STAMPWIDGETS 10000
|
||||||
|
#define ID_BUTTON_NB 10002
|
||||||
|
#define ID_BUTTON_NB1 10003
|
||||||
|
#define ID_NOTEBOOK_STAMPWIDGETS_ 10001
|
||||||
|
#define SYMBOL_STAMPWIDGETS_STYLE wxTAB_TRAVERSAL
|
||||||
|
#define SYMBOL_STAMPWIDGETS_TITLE _("StampWidgets")
|
||||||
|
#define SYMBOL_STAMPWIDGETS_IDNAME ID_STAMPWIDGETS
|
||||||
|
#define SYMBOL_STAMPWIDGETS_SIZE wxSize(400, 300)
|
||||||
|
#define SYMBOL_STAMPWIDGETS_POSITION wxDefaultPosition
|
||||||
|
////@end control identifiers
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* StampWidgets class declaration
|
||||||
|
*/
|
||||||
|
|
||||||
|
class StampWidgets: public wxPanel
|
||||||
|
{
|
||||||
|
DECLARE_DYNAMIC_CLASS( StampWidgets )
|
||||||
|
DECLARE_EVENT_TABLE()
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructors
|
||||||
|
StampWidgets();
|
||||||
|
StampWidgets( wxWindow* parent, wxWindowID id = SYMBOL_STAMPWIDGETS_IDNAME, const wxPoint& pos = SYMBOL_STAMPWIDGETS_POSITION, const wxSize& size = SYMBOL_STAMPWIDGETS_SIZE, long style = SYMBOL_STAMPWIDGETS_STYLE );
|
||||||
|
|
||||||
|
/// Creation
|
||||||
|
bool Create( wxWindow* parent, wxWindowID id = SYMBOL_STAMPWIDGETS_IDNAME, const wxPoint& pos = SYMBOL_STAMPWIDGETS_POSITION, const wxSize& size = SYMBOL_STAMPWIDGETS_SIZE, long style = SYMBOL_STAMPWIDGETS_STYLE );
|
||||||
|
|
||||||
|
/// Destructor
|
||||||
|
~StampWidgets();
|
||||||
|
|
||||||
|
/// Initialises member variables
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
/// Creates the controls and sizers
|
||||||
|
void CreateControls();
|
||||||
|
|
||||||
|
////@begin StampWidgets event handler declarations
|
||||||
|
|
||||||
|
////@end StampWidgets event handler declarations
|
||||||
|
|
||||||
|
////@begin StampWidgets member function declarations
|
||||||
|
|
||||||
|
/// Retrieves bitmap resources
|
||||||
|
wxBitmap GetBitmapResource( const wxString& name );
|
||||||
|
|
||||||
|
/// Retrieves icon resources
|
||||||
|
wxIcon GetIconResource( const wxString& name );
|
||||||
|
////@end StampWidgets member function declarations
|
||||||
|
|
||||||
|
/// Should we show tooltips?
|
||||||
|
static bool ShowToolTips();
|
||||||
|
|
||||||
|
////@begin StampWidgets member variables
|
||||||
|
wxBoxSizer* szNoteBookMain;
|
||||||
|
wxBoxSizer* szNoteBookButtons;
|
||||||
|
wxButton* btnAddStampWidget;
|
||||||
|
wxButton* btnDeleteStampWidget;
|
||||||
|
wxNotebook* nbStampWidgets;
|
||||||
|
////@end StampWidgets member variables
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
// _STAMPWIDGETS_H_
|
||||||
230
Resources/StampWidget/XStampWidget.cpp
Normal file
230
Resources/StampWidget/XStampWidget.cpp
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
// /*
|
||||||
|
// * File: XStampWidget.cpp
|
||||||
|
// * Author: Saleem Edah-Tally - nmset@yandex.com
|
||||||
|
// * License : CeCILL-C
|
||||||
|
// * Copyright Saleem Edah-Tally - © 2025
|
||||||
|
// *
|
||||||
|
// * Created on 01 07 2025, 20:35
|
||||||
|
// */
|
||||||
|
|
||||||
|
#include "XStampWidget.h"
|
||||||
|
#include "DefsStampWidget.h"
|
||||||
|
#include "StampWorker.h"
|
||||||
|
#include <wx/bmpbndl.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
IMPLEMENT_CLASS( XStampWidget, StampWidget )
|
||||||
|
|
||||||
|
XStampWidget::XStampWidget(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
|
||||||
|
: StampWidget(parent, id, pos, size, style)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool XStampWidget::Setup(wxConfig * config)
|
||||||
|
{
|
||||||
|
m_config = config;
|
||||||
|
if (!m_config)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const wxString fontDesc = m_config->Read("/Stamp/FontDesc", "");
|
||||||
|
if (!fontDesc.IsEmpty())
|
||||||
|
{
|
||||||
|
wxFont font = wxNullFont;
|
||||||
|
font.SetNativeFontInfo(fontDesc);
|
||||||
|
if (font.IsOk())
|
||||||
|
{
|
||||||
|
fpkStamp->SetSelectedFont(font);
|
||||||
|
fpkStamp->Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
long rgb = m_config->Read("/Stamp/ForegroundRGB", wxNOT_FOUND);
|
||||||
|
if (rgb > wxNOT_FOUND)
|
||||||
|
{
|
||||||
|
wxColour foregroundColour = wxNullColour;
|
||||||
|
foregroundColour.SetRGB((wxUint32) rgb);
|
||||||
|
if (foregroundColour.IsOk())
|
||||||
|
{
|
||||||
|
cpkForegroundStamp->SetColour(foregroundColour);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rgb = m_config->Read("/Stamp/BackgroundRGB", wxNOT_FOUND);
|
||||||
|
if (rgb > wxNOT_FOUND)
|
||||||
|
{
|
||||||
|
wxColour backgroundColour = wxNullColour;
|
||||||
|
backgroundColour.SetRGB((wxUint32) rgb);
|
||||||
|
if (backgroundColour.IsOk())
|
||||||
|
{
|
||||||
|
cpkBackgroundStamp->SetColour(backgroundColour);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int textRotationAngle = m_config->Read("/Stamp/RotationAngle", 45);
|
||||||
|
sldTextRotationAngle->SetValue(textRotationAngle);
|
||||||
|
bool transparency = m_config->ReadBool("/Stamp/Transparency", true);
|
||||||
|
tglTransparent->SetValue(transparency);
|
||||||
|
wxCommandEvent evt;
|
||||||
|
evt.SetInt(transparency);
|
||||||
|
OnTransparencyToggled(evt);
|
||||||
|
|
||||||
|
fpkStamp->Bind(wxEVT_FONTPICKER_CHANGED, &XStampWidget::OnFontChanged, this);
|
||||||
|
cpkForegroundStamp->Bind(wxEVT_COLOURPICKER_CHANGED, &XStampWidget::OnForegroundColourChanged, this);
|
||||||
|
cpkBackgroundStamp->Bind(wxEVT_COLOURPICKER_CHANGED, &XStampWidget::OnBackgroundColourChanged, this);
|
||||||
|
// *End* of any mouse and any keyboard interaction.
|
||||||
|
sldTextRotationAngle->Bind(wxEVT_SCROLL_CHANGED, &XStampWidget::OnAngleSliderChanged, this);
|
||||||
|
txtStamp->Bind(wxEVT_KEY_UP, &XStampWidget::OnTxtKeyPressed, this);
|
||||||
|
tglTransparent->Bind(wxEVT_TOGGLEBUTTON, &XStampWidget::OnTransparencyToggled, this);
|
||||||
|
|
||||||
|
wxArrayString stampLocations ({_("Centre"),
|
||||||
|
_("North"), _("South"), _("East"), _("West"),
|
||||||
|
_("North-east"), _("North-west"),
|
||||||
|
_("South-east"), _("South-west")});
|
||||||
|
cmbStampLocation->Append(stampLocations);
|
||||||
|
int location = m_config->Read("/Stamp/Location", wxNOT_FOUND);
|
||||||
|
cmbStampLocation->Select((location >= cmbStampLocation->GetCount() || location < 0) ? 0 : location);
|
||||||
|
cmbStampLocation->Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, &XStampWidget::OnLocationChanged, this);
|
||||||
|
|
||||||
|
// A panel container is used to have its borders.
|
||||||
|
m_sbmpPreview = new wxGenericStaticBitmap(panBitmapPreview, wxID_ANY, wxBitmapBundle(wxNullBitmap), wxDefaultPosition, panBitmapPreview->GetSize());
|
||||||
|
szBitmapPreviewInPanel->Add(m_sbmpPreview, 0, wxGROW | wxALL, 5);
|
||||||
|
m_sbmpPreview->SetScaleMode(wxStaticBitmapBase::Scale_AspectFit);
|
||||||
|
|
||||||
|
m_sbmpPreview->Bind(wxEVT_LEFT_UP, &XStampWidget::OnBitmapPreview, this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XStampWidget::OnFontChanged(wxFontPickerEvent& evt)
|
||||||
|
{
|
||||||
|
if (!m_config)
|
||||||
|
{
|
||||||
|
evt.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const wxString desc = evt.GetFont().GetNativeFontInfoDesc();
|
||||||
|
m_config->Write("/Stamp/FontDesc", desc);
|
||||||
|
m_config->Flush();
|
||||||
|
|
||||||
|
evt.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
void XStampWidget::OnForegroundColourChanged(wxColourPickerEvent& evt)
|
||||||
|
{
|
||||||
|
if (!m_config)
|
||||||
|
{
|
||||||
|
evt.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const wxUint32 rgb = evt.GetColour().GetRGB();
|
||||||
|
m_config->Write("/Stamp/ForegroundRGB", (long) rgb);
|
||||||
|
m_config->Flush();
|
||||||
|
|
||||||
|
evt.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
void XStampWidget::OnBackgroundColourChanged(wxColourPickerEvent& evt)
|
||||||
|
{
|
||||||
|
if (!m_config)
|
||||||
|
{
|
||||||
|
evt.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const wxUint32 rgb = evt.GetColour().GetRGB();
|
||||||
|
m_config->Write("/Stamp/BackgroundRGB", (long) rgb);
|
||||||
|
m_config->Flush();
|
||||||
|
|
||||||
|
evt.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
void XStampWidget::OnAngleSliderChanged(wxScrollEvent& evt)
|
||||||
|
{
|
||||||
|
if (!m_config)
|
||||||
|
{
|
||||||
|
evt.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_config->Write("/Stamp/RotationAngle", evt.GetInt());
|
||||||
|
m_config->Flush();
|
||||||
|
evt.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
void XStampWidget::OnTxtKeyPressed(wxKeyEvent& evt)
|
||||||
|
{
|
||||||
|
if (!m_config || !evt.ControlDown())
|
||||||
|
{
|
||||||
|
evt.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (evt.GetKeyCode() == 'S')
|
||||||
|
{
|
||||||
|
if (txtStamp->IsEmpty())
|
||||||
|
{
|
||||||
|
evt.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_config->Write("/Stamp/Text", txtStamp->GetValue());
|
||||||
|
m_config->Flush();
|
||||||
|
}
|
||||||
|
else if (evt.GetKeyCode() == 'R')
|
||||||
|
{
|
||||||
|
wxString last;
|
||||||
|
if (m_config->Read("/Stamp/Text", &last))
|
||||||
|
{
|
||||||
|
txtStamp->SetValue(last);
|
||||||
|
txtStamp->SetSelection(last.Len(), last.Len());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
evt.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
void XStampWidget::OnLocationChanged(wxCommandEvent& evt)
|
||||||
|
{
|
||||||
|
if (!m_config)
|
||||||
|
{
|
||||||
|
evt.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_config->Write("/Stamp/Location", evt.GetSelection());
|
||||||
|
m_config->Flush();
|
||||||
|
evt.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
void XStampWidget::OnTransparencyToggled(wxCommandEvent& evt)
|
||||||
|
{
|
||||||
|
lblBackgroundColour->Show(evt.GetInt() == 0);
|
||||||
|
cpkBackgroundStamp->Show(evt.GetInt() == 0);
|
||||||
|
if (GetSizer())
|
||||||
|
GetSizer()->Layout();
|
||||||
|
|
||||||
|
if (!m_config)
|
||||||
|
{
|
||||||
|
evt.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_config->Write("/Stamp/Transparency", evt.GetInt());
|
||||||
|
m_config->Flush();
|
||||||
|
evt.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
StampDescriptor * XStampWidget::GetStampDescriptor()
|
||||||
|
{
|
||||||
|
m_descriptor.reset(nullptr);
|
||||||
|
m_descriptor = std::make_unique<StampDescriptor> ();
|
||||||
|
m_descriptor->text = txtStamp->GetValue();
|
||||||
|
m_descriptor->font = fpkStamp->GetSelectedFont();
|
||||||
|
m_descriptor->foregroundColour = cpkForegroundStamp->GetColour();
|
||||||
|
m_descriptor->backgroundColour = cpkBackgroundStamp->GetColour();
|
||||||
|
m_descriptor->rotationAngle = sldTextRotationAngle->GetValue();
|
||||||
|
m_descriptor->location = cmbStampLocation->GetSelection();
|
||||||
|
m_descriptor->transparent = tglTransparent->GetValue();
|
||||||
|
// Not setting image, it is to be created.
|
||||||
|
return m_descriptor.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void XStampWidget::OnBitmapPreview(wxMouseEvent& evt)
|
||||||
|
{
|
||||||
|
StampDescriptor * descriptor = GetStampDescriptor();
|
||||||
|
wxImage preview = StampWorker::CreateStamp(descriptor, 72);
|
||||||
|
m_sbmpPreview->SetBitmap(wxBitmapBundle(preview));
|
||||||
|
GetSizer()->Layout();
|
||||||
|
evt.Skip();
|
||||||
|
}
|
||||||
52
Resources/StampWidget/XStampWidget.h
Normal file
52
Resources/StampWidget/XStampWidget.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
// /*
|
||||||
|
// * File: XStampWidget.h
|
||||||
|
// * Author: Saleem Edah-Tally - nmset@yandex.com
|
||||||
|
// * License : CeCILL-C
|
||||||
|
// * Copyright Saleem Edah-Tally - © 2025
|
||||||
|
// *
|
||||||
|
// * Created on 01 07 2025, 20:35
|
||||||
|
// */
|
||||||
|
|
||||||
|
#ifndef XSTAMPWIDGET_H
|
||||||
|
#define XSTAMPWIDGET_H
|
||||||
|
|
||||||
|
#include "StampWidget.h"
|
||||||
|
#include <wx/wx.h>
|
||||||
|
#include <wx/config.h>
|
||||||
|
#include <wx/generic/statbmpg.h>
|
||||||
|
|
||||||
|
struct StampDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This widget collects inputs for the creation of a stamp on scan pages.\n
|
||||||
|
* - text
|
||||||
|
* - font
|
||||||
|
* - foreground colour
|
||||||
|
* - background colour
|
||||||
|
* - angle of rotation
|
||||||
|
* - transparency.
|
||||||
|
*/
|
||||||
|
class XStampWidget : public StampWidget
|
||||||
|
{
|
||||||
|
DECLARE_DYNAMIC_CLASS( XStampWidget )
|
||||||
|
public:
|
||||||
|
XStampWidget( wxWindow* parent, wxWindowID id = SYMBOL_STAMPWIDGET_IDNAME, const wxPoint& pos = SYMBOL_STAMPWIDGET_POSITION, const wxSize& size = SYMBOL_STAMPWIDGET_SIZE, long style = SYMBOL_STAMPWIDGET_STYLE );
|
||||||
|
|
||||||
|
bool Setup(wxConfig * config);
|
||||||
|
StampDescriptor * GetStampDescriptor();
|
||||||
|
private:
|
||||||
|
wxConfig * m_config;
|
||||||
|
std::unique_ptr<StampDescriptor> m_descriptor;
|
||||||
|
wxGenericStaticBitmap * m_sbmpPreview;
|
||||||
|
|
||||||
|
void OnFontChanged(wxFontPickerEvent& evt);
|
||||||
|
void OnForegroundColourChanged(wxColourPickerEvent& evt);
|
||||||
|
void OnBackgroundColourChanged(wxColourPickerEvent& evt);
|
||||||
|
void OnAngleSliderChanged(wxScrollEvent& evt);
|
||||||
|
void OnTxtKeyPressed ( wxKeyEvent& evt );
|
||||||
|
void OnLocationChanged(wxCommandEvent& evt);
|
||||||
|
void OnTransparencyToggled(wxCommandEvent& evt);
|
||||||
|
void OnBitmapPreview(wxMouseEvent& evt);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // XSTAMPWIDGET_H
|
||||||
88
Resources/StampWidget/XStampWidgets.cpp
Normal file
88
Resources/StampWidget/XStampWidgets.cpp
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
// /*
|
||||||
|
// * File: XStampWidgets.cpp
|
||||||
|
// * Author: Saleem Edah-Tally - nmset@yandex.com
|
||||||
|
// * License : CeCILL-C
|
||||||
|
// * Copyright Saleem Edah-Tally - © 2025
|
||||||
|
// *
|
||||||
|
// * Created on 06 07 2025, 22:41
|
||||||
|
// */
|
||||||
|
|
||||||
|
#include "XStampWidgets.h"
|
||||||
|
#include <XStampWidget.h>
|
||||||
|
#include <DefsStampWidget.h>
|
||||||
|
|
||||||
|
IMPLEMENT_CLASS( XStampWidgets, StampWidgets )
|
||||||
|
|
||||||
|
XStampWidgets::XStampWidgets(wxWindow* parent, wxWindowID id, const wxPoint& pos,
|
||||||
|
const wxSize& size, long style)
|
||||||
|
: StampWidgets(parent, id, pos, size, style)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool XStampWidgets::Setup(wxFileConfig* config)
|
||||||
|
{
|
||||||
|
m_config = config;
|
||||||
|
if (!m_config)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wxMouseEvent evt;
|
||||||
|
AddStampWidget(evt);
|
||||||
|
btnAddStampWidget->Bind(wxEVT_LEFT_UP, &XStampWidgets::AddStampWidget, this);
|
||||||
|
btnDeleteStampWidget->Bind(wxEVT_LEFT_UP, &XStampWidgets::DeleteStampWidget, this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XStampWidgets::AddStampWidget(wxMouseEvent& evt)
|
||||||
|
{
|
||||||
|
XStampWidget * stampWidget = new XStampWidget(nbStampWidgets);
|
||||||
|
stampWidget->Setup(m_config);
|
||||||
|
stampWidget->Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, &XStampWidgets::OnStampLocationChanged, this);
|
||||||
|
nbStampWidgets->AddPage(stampWidget, stampWidget->cmbStampLocation->GetStringSelection(), true);
|
||||||
|
if (GetParent()->GetSizer())
|
||||||
|
GetParent()->GetSizer()->Layout();
|
||||||
|
|
||||||
|
evt.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
void XStampWidgets::DeleteStampWidget(wxMouseEvent& evt)
|
||||||
|
{
|
||||||
|
int selectedPage = nbStampWidgets->GetSelection();
|
||||||
|
if (selectedPage == wxNOT_FOUND)
|
||||||
|
{
|
||||||
|
evt.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nbStampWidgets->DeletePage(selectedPage);
|
||||||
|
evt.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<StampDescriptor*> * XStampWidgets::GetStampDescriptors()
|
||||||
|
{
|
||||||
|
m_stampDescriptors.clear(); // Stored as unique_ptr in XStampWidget.
|
||||||
|
for (uint i = 0; i < nbStampWidgets->GetPageCount(); i++)
|
||||||
|
{
|
||||||
|
XStampWidget * stampWidget = static_cast<XStampWidget*> (nbStampWidgets->GetPage(i));
|
||||||
|
if (stampWidget)
|
||||||
|
{
|
||||||
|
m_stampDescriptors.push_back(stampWidget->GetStampDescriptor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &m_stampDescriptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XStampWidgets::OnStampLocationChanged(wxCommandEvent& evt)
|
||||||
|
{
|
||||||
|
int selectedPage = nbStampWidgets->GetSelection();
|
||||||
|
if (selectedPage == wxNOT_FOUND)
|
||||||
|
{
|
||||||
|
evt.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
XStampWidget * stampWidget = static_cast<XStampWidget*> (nbStampWidgets->GetPage(selectedPage));
|
||||||
|
if (!stampWidget)
|
||||||
|
{
|
||||||
|
evt.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nbStampWidgets->SetPageText(selectedPage, stampWidget->cmbStampLocation->GetStringSelection());
|
||||||
|
evt.Skip();
|
||||||
|
}
|
||||||
41
Resources/StampWidget/XStampWidgets.h
Normal file
41
Resources/StampWidget/XStampWidgets.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
// /*
|
||||||
|
// * File: XStampWidgets.h
|
||||||
|
// * Author: Saleem Edah-Tally - nmset@yandex.com
|
||||||
|
// * License : CeCILL-C
|
||||||
|
// * Copyright Saleem Edah-Tally - © 2025
|
||||||
|
// *
|
||||||
|
// * Created on 06 07 2025, 22:41
|
||||||
|
// */
|
||||||
|
|
||||||
|
#ifndef XSTAMPWIDGETS_H
|
||||||
|
#define XSTAMPWIDGETS_H
|
||||||
|
|
||||||
|
#include "StampWidgets.h"
|
||||||
|
#include <wx/wx.h>
|
||||||
|
#include <wx/config.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
struct StampDescriptor;
|
||||||
|
|
||||||
|
class XStampWidgets : public StampWidgets
|
||||||
|
{
|
||||||
|
DECLARE_DYNAMIC_CLASS( XStampWidgets )
|
||||||
|
public:
|
||||||
|
XStampWidgets(wxWindow* parent, wxWindowID id = SYMBOL_STAMPWIDGETS_IDNAME,
|
||||||
|
const wxPoint& pos = SYMBOL_STAMPWIDGETS_POSITION,
|
||||||
|
const wxSize& size = SYMBOL_STAMPWIDGETS_SIZE,
|
||||||
|
long style = SYMBOL_STAMPWIDGETS_STYLE);
|
||||||
|
bool Setup(wxConfig * config);
|
||||||
|
std::vector<StampDescriptor*> * GetStampDescriptors();
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxConfig * m_config;
|
||||||
|
std::vector<StampDescriptor*> m_stampDescriptors;
|
||||||
|
|
||||||
|
void AddStampWidget(wxMouseEvent& evt);
|
||||||
|
void DeleteStampWidget(wxMouseEvent& evt);
|
||||||
|
void OnStampLocationChanged(wxCommandEvent& evt);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // XSTAMPWIDGETS_H
|
||||||
@@ -419,7 +419,7 @@
|
|||||||
<bool name="proxy-wxRIGHT">1</bool>
|
<bool name="proxy-wxRIGHT">1</bool>
|
||||||
<bool name="proxy-wxSHAPED">0</bool>
|
<bool name="proxy-wxSHAPED">0</bool>
|
||||||
<bool name="proxy-wxTOP">1</bool>
|
<bool name="proxy-wxTOP">1</bool>
|
||||||
<string name="title">"wxBoxSizer V"</string>
|
<string name="title">"wxBoxSizer V: szMain"</string>
|
||||||
<long name="title-mode">0</long>
|
<long name="title-mode">0</long>
|
||||||
<string name="type">"dialog-control-document"</string>
|
<string name="type">"dialog-control-document"</string>
|
||||||
<document>
|
<document>
|
||||||
@@ -526,7 +526,7 @@ Double-click to go to the selected directory."</string>
|
|||||||
<long name="proxy-Height">-1</long>
|
<long name="proxy-Height">-1</long>
|
||||||
<string name="proxy-Help text">"Basename"</string>
|
<string name="proxy-Help text">"Basename"</string>
|
||||||
<bool name="proxy-Hidden">0</bool>
|
<bool name="proxy-Hidden">0</bool>
|
||||||
<string name="proxy-Id name">"ID_TEXTCTRL"</string>
|
<string name="proxy-Id name">"ID_TEXTCTRL_S7"</string>
|
||||||
<long name="proxy-Id value">10003</long>
|
<long name="proxy-Id value">10003</long>
|
||||||
<string name="proxy-Implementation filename">""</string>
|
<string name="proxy-Implementation filename">""</string>
|
||||||
<string name="proxy-Initial value">""</string>
|
<string name="proxy-Initial value">""</string>
|
||||||
@@ -576,7 +576,7 @@ Double-click to go to the selected directory."</string>
|
|||||||
<bool name="proxy-wxWANTS_CHARS">0</bool>
|
<bool name="proxy-wxWANTS_CHARS">0</bool>
|
||||||
<long name="proxy-X">-1</long>
|
<long name="proxy-X">-1</long>
|
||||||
<long name="proxy-Y">-1</long>
|
<long name="proxy-Y">-1</long>
|
||||||
<string name="title">"wxTextCtrl: ID_TEXTCTRL"</string>
|
<string name="title">"wxTextCtrl: ID_TEXTCTRL_S7"</string>
|
||||||
<long name="title-mode">0</long>
|
<long name="title-mode">0</long>
|
||||||
<string name="type">"dialog-control-document"</string>
|
<string name="type">"dialog-control-document"</string>
|
||||||
</document>
|
</document>
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ void S7::CreateControls()
|
|||||||
dpkDestination->SetToolTip(_("Select a destination directory.\nDouble-click to go to the selected directory."));
|
dpkDestination->SetToolTip(_("Select a destination directory.\nDouble-click to go to the selected directory."));
|
||||||
szMain->Add(dpkDestination, 0, wxGROW|wxALL, 5);
|
szMain->Add(dpkDestination, 0, wxGROW|wxALL, 5);
|
||||||
|
|
||||||
txtBasename = new wxTextCtrl( panMain, ID_TEXTCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
txtBasename = new wxTextCtrl( panMain, ID_TEXTCTRL_S7, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
txtBasename->SetHelpText(_("Basename"));
|
txtBasename->SetHelpText(_("Basename"));
|
||||||
if (S7::ShowToolTips())
|
if (S7::ShowToolTips())
|
||||||
txtBasename->SetToolTip(_("Specify a destination file basename (without extension).\n\n'CTRL + click' for about information."));
|
txtBasename->SetToolTip(_("Specify a destination file basename (without extension).\n\n'CTRL + click' for about information."));
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class wxDirPickerCtrl;
|
|||||||
#define ID_S7 10000
|
#define ID_S7 10000
|
||||||
#define ID_PANEL 10001
|
#define ID_PANEL 10001
|
||||||
#define ID_DIRPICKERCTRL 10002
|
#define ID_DIRPICKERCTRL 10002
|
||||||
#define ID_TEXTCTRL 10003
|
#define ID_TEXTCTRL_S7 10003
|
||||||
#define SYMBOL_S7_STYLE wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU|wxCLOSE_BOX
|
#define SYMBOL_S7_STYLE wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU|wxCLOSE_BOX
|
||||||
#define SYMBOL_S7_TITLE _("S7")
|
#define SYMBOL_S7_TITLE _("S7")
|
||||||
#define SYMBOL_S7_IDNAME ID_S7
|
#define SYMBOL_S7_IDNAME ID_S7
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include <globals.h>
|
#include <globals.h>
|
||||||
#include "s7app.h"
|
#include "s7app.h"
|
||||||
#include <XS7.h>
|
#include <XS7.h>
|
||||||
|
#include <wx/cmdline.h>
|
||||||
|
|
||||||
////@begin XPM images
|
////@begin XPM images
|
||||||
|
|
||||||
@@ -40,6 +41,7 @@
|
|||||||
IMPLEMENT_APP( S7App )
|
IMPLEMENT_APP( S7App )
|
||||||
////@end implement app
|
////@end implement app
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* S7App type definition
|
* S7App type definition
|
||||||
@@ -122,15 +124,16 @@ bool S7App::OnInit()
|
|||||||
translations->AddCatalog(_APPNAME_);
|
translations->AddCatalog(_APPNAME_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool res = ParseCmdLine();
|
||||||
|
if ( !res )
|
||||||
|
return res;
|
||||||
|
|
||||||
|
SetConfig();
|
||||||
XS7 * appWindow = new XS7(nullptr);
|
XS7 * appWindow = new XS7(nullptr);
|
||||||
SetTopWindow(appWindow);
|
SetTopWindow(appWindow);
|
||||||
appWindow->Show ( false );
|
appWindow->Show ( false );
|
||||||
bool res = appWindow->ParseCmdLine();
|
appWindow->Setup(m_config.get());
|
||||||
if ( res )
|
appWindow->Show();
|
||||||
{
|
|
||||||
appWindow->Setup();
|
|
||||||
appWindow->Show();
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -147,3 +150,42 @@ int S7App::OnExit()
|
|||||||
////@end S7App cleanup
|
////@end S7App cleanup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool S7App::ParseCmdLine()
|
||||||
|
{
|
||||||
|
wxCmdLineParser p;
|
||||||
|
p.SetCmdLine ( wxApp::GetInstance()->argc, wxApp::GetInstance()->argv );
|
||||||
|
p.SetSwitchChars ( _T ( "-" ) );
|
||||||
|
p.AddOption ( _T ( "c" ), wxEmptyString, _ ( "Config file tag." ) );
|
||||||
|
p.AddSwitch ( _T ( "v" ), wxEmptyString, _ ( "Show version and quit." ) );
|
||||||
|
p.AddSwitch ( _T ( "h" ), wxEmptyString, _ ( "Show help and quit." ) );
|
||||||
|
p.Parse ( false );
|
||||||
|
if ( p.Found ( _T ( "c" ) ) )
|
||||||
|
{
|
||||||
|
p.Found ( _T ( "c" ), &m_configTag );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( p.Found ( _T ( "h" ) ) )
|
||||||
|
{
|
||||||
|
p.Usage();
|
||||||
|
return false; //Exit code is 255, not clean.
|
||||||
|
}
|
||||||
|
if ( p.Found ( _T ( "v" ) ) )
|
||||||
|
{
|
||||||
|
cout << ( _APPNAME_ + _ ( " - version " ) + to_string(_APPVERSION_) ) << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void S7App::SetConfig()
|
||||||
|
{
|
||||||
|
const wxString configDir = wxFileConfig::GetLocalFile ( _APPNAME_, wxCONFIG_USE_SUBDIR ).GetPath();
|
||||||
|
if ( !wxFileName::Exists ( configDir ) )
|
||||||
|
wxFileName::Mkdir ( configDir );
|
||||||
|
|
||||||
|
const wxString configBaseName = m_configTag.IsEmpty()
|
||||||
|
? _APPNAME_
|
||||||
|
: _APPNAME_ + wxString("-") + m_configTag;
|
||||||
|
m_config = std::make_unique<wxFileConfig>(_APPNAME_, _T("SET"), configBaseName,
|
||||||
|
wxEmptyString, wxCONFIG_USE_SUBDIR);
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
#include "wx/image.h"
|
#include "wx/image.h"
|
||||||
////@end includes
|
////@end includes
|
||||||
|
|
||||||
|
#include "wx/config.h"
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Forward declarations
|
* Forward declarations
|
||||||
*/
|
*/
|
||||||
@@ -66,6 +68,15 @@ public:
|
|||||||
////@end S7App member variables
|
////@end S7App member variables
|
||||||
private:
|
private:
|
||||||
wxLocale m_locale;
|
wxLocale m_locale;
|
||||||
|
std::unique_ptr<wxConfig> m_config = nullptr;
|
||||||
|
/*
|
||||||
|
* An optional tag for wxConfig files. This allows using different profiles
|
||||||
|
* by specifying the -c command line option.
|
||||||
|
*/
|
||||||
|
wxString m_configTag;
|
||||||
|
|
||||||
|
bool ParseCmdLine();
|
||||||
|
void SetConfig();
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ PopupTransientWindow* ConfigEditorPopup::CreatePopup()
|
|||||||
return m_popup;
|
return m_popup;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCheckBox* ConfigEditorPopup::AddCheckBox ( const wxString& label, const wxString& configPath )
|
wxCheckBox* ConfigEditorPopup::AddCheckBox ( const wxString& label, const wxString& configPath,
|
||||||
|
bool * clientVar)
|
||||||
{
|
{
|
||||||
wxASSERT_MSG ( ( m_config != nullptr ),_T("CONFIG IS nullptr") );
|
wxASSERT_MSG ( ( m_config != nullptr ),_T("CONFIG IS nullptr") );
|
||||||
wxString * cPath = new wxString ( configPath );
|
wxString * cPath = new wxString ( configPath );
|
||||||
@@ -38,13 +39,22 @@ wxCheckBox* ConfigEditorPopup::AddCheckBox ( const wxString& label, const wxStri
|
|||||||
m_flxsz->Add ( lbl, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 0 );
|
m_flxsz->Add ( lbl, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 0 );
|
||||||
wxCheckBox * cb = new wxCheckBox ( m_pan, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxCHK_2STATE );
|
wxCheckBox * cb = new wxCheckBox ( m_pan, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxCHK_2STATE );
|
||||||
m_flxsz->Add ( cb, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 0 );
|
m_flxsz->Add ( cb, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 0 );
|
||||||
cb->SetValue ( m_config->ReadBool ( configPath, false ) );
|
cb->SetValue ( (!clientVar) ? m_config->ReadBool ( configPath, false ) : *clientVar);
|
||||||
cb->SetClientData ( cPath );
|
cb->SetClientData ( cPath );
|
||||||
cb->Bind ( wxEVT_DESTROY, &ConfigEditorPopup::OnControlDestroy, this );
|
cb->Bind ( wxEVT_DESTROY, &ConfigEditorPopup::OnControlDestroy, this );
|
||||||
|
if (clientVar)
|
||||||
|
{
|
||||||
|
cb->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, [cb, clientVar] (wxCommandEvent& evt)
|
||||||
|
{
|
||||||
|
*clientVar = cb->GetValue();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
return cb;
|
return cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxSpinCtrl* ConfigEditorPopup::AddSpinCtrl ( const wxString& label, const wxString& configPath )
|
wxSpinCtrl* ConfigEditorPopup::AddSpinCtrl ( const wxString& label, const wxString& configPath,
|
||||||
|
int * clientVar)
|
||||||
{
|
{
|
||||||
wxASSERT_MSG ( ( m_config != nullptr ),_T("CONFIG IS nullptr") );
|
wxASSERT_MSG ( ( m_config != nullptr ),_T("CONFIG IS nullptr") );
|
||||||
wxString * cPath = new wxString ( configPath );
|
wxString * cPath = new wxString ( configPath );
|
||||||
@@ -52,13 +62,22 @@ wxSpinCtrl* ConfigEditorPopup::AddSpinCtrl ( const wxString& label, const wxStri
|
|||||||
m_flxsz->Add ( lbl, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxGROW | wxALL, 0 );
|
m_flxsz->Add ( lbl, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxGROW | wxALL, 0 );
|
||||||
wxSpinCtrl * spn = new wxSpinCtrl ( m_pan, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS | wxALIGN_RIGHT, -100, 100 );
|
wxSpinCtrl * spn = new wxSpinCtrl ( m_pan, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS | wxALIGN_RIGHT, -100, 100 );
|
||||||
m_flxsz->Add ( spn, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 0 );
|
m_flxsz->Add ( spn, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 0 );
|
||||||
spn->SetValue ( ( int ) m_config->ReadLong ( configPath, 0 ) );
|
spn->SetValue ((!clientVar) ? ( int ) m_config->ReadLong ( configPath, 0 ) : *clientVar);
|
||||||
spn->SetClientData ( cPath );
|
spn->SetClientData ( cPath );
|
||||||
spn->Bind ( wxEVT_DESTROY, &ConfigEditorPopup::OnControlDestroy, this );
|
spn->Bind ( wxEVT_DESTROY, &ConfigEditorPopup::OnControlDestroy, this );
|
||||||
|
if (clientVar)
|
||||||
|
{
|
||||||
|
spn->Bind(wxEVT_COMMAND_SPINCTRL_UPDATED, [spn, clientVar] (wxSpinEvent& evt)
|
||||||
|
{
|
||||||
|
*clientVar = spn->GetValue();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
return spn;
|
return spn;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxTextCtrl* ConfigEditorPopup::AddTextCtrl ( const wxString& label, const wxString& configPath )
|
wxTextCtrl* ConfigEditorPopup::AddTextCtrl ( const wxString& label, const wxString& configPath,
|
||||||
|
wxString * clientVar)
|
||||||
{
|
{
|
||||||
wxASSERT_MSG ( ( m_config != nullptr ),_T("CONFIG IS nullptr") );
|
wxASSERT_MSG ( ( m_config != nullptr ),_T("CONFIG IS nullptr") );
|
||||||
wxString * cPath = new wxString ( configPath );
|
wxString * cPath = new wxString ( configPath );
|
||||||
@@ -66,9 +85,17 @@ wxTextCtrl* ConfigEditorPopup::AddTextCtrl ( const wxString& label, const wxStri
|
|||||||
m_flxsz->Add ( lbl, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxGROW | wxALL, 0 );
|
m_flxsz->Add ( lbl, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxGROW | wxALL, 0 );
|
||||||
wxTextCtrl * txt = new wxTextCtrl ( m_pan, wxID_ANY );
|
wxTextCtrl * txt = new wxTextCtrl ( m_pan, wxID_ANY );
|
||||||
m_flxsz->Add ( txt, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 0 );
|
m_flxsz->Add ( txt, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 0 );
|
||||||
txt->SetValue ( m_config->Read ( configPath, wxEmptyString ) );
|
txt->SetValue ( (!clientVar) ? m_config->Read ( configPath, wxEmptyString ) : *clientVar );
|
||||||
txt->SetClientData ( cPath );
|
txt->SetClientData ( cPath );
|
||||||
txt->Bind ( wxEVT_DESTROY, &ConfigEditorPopup::OnControlDestroy, this );
|
txt->Bind ( wxEVT_DESTROY, &ConfigEditorPopup::OnControlDestroy, this );
|
||||||
|
if (clientVar)
|
||||||
|
{
|
||||||
|
txt->Bind(wxEVT_COMMAND_TEXT_UPDATED, [txt, clientVar] (wxCommandEvent& evt)
|
||||||
|
{
|
||||||
|
*clientVar = txt->GetValue();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
return txt;
|
return txt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ public:
|
|||||||
virtual ~ConfigEditorPopup();
|
virtual ~ConfigEditorPopup();
|
||||||
PopupTransientWindow* CreatePopup();
|
PopupTransientWindow* CreatePopup();
|
||||||
void ShowPopup();
|
void ShowPopup();
|
||||||
wxCheckBox* AddCheckBox ( const wxString& label, const wxString& configPath );
|
wxCheckBox* AddCheckBox(const wxString& label, const wxString& configPath, bool * clientVar = nullptr);
|
||||||
wxSpinCtrl* AddSpinCtrl ( const wxString& label, const wxString& configPath );
|
wxSpinCtrl* AddSpinCtrl ( const wxString& label, const wxString& configPath, int * clientVar = nullptr );
|
||||||
wxTextCtrl * AddTextCtrl ( const wxString& label, const wxString& configPath );
|
wxTextCtrl * AddTextCtrl ( const wxString& label, const wxString& configPath, wxString * clientVar = nullptr );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wxConfig * m_config = nullptr;
|
wxConfig * m_config = nullptr;
|
||||||
|
|||||||
@@ -116,6 +116,15 @@ void MiscTools::MessageBox ( const wxString& msg, const bool notify )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MiscTools::AsyncMessageBox(const wxString& msg, const bool notify)
|
||||||
|
{
|
||||||
|
wxTheApp->CallAfter([msg, notify] ()
|
||||||
|
{
|
||||||
|
MiscTools::MessageBox(msg, notify);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
wxTextValidator* MiscTools::MakeFileNameValidator ( bool excludeSpace )
|
wxTextValidator* MiscTools::MakeFileNameValidator ( bool excludeSpace )
|
||||||
{
|
{
|
||||||
wxTextValidator * tval = new wxTextValidator ( wxFILTER_EXCLUDE_CHAR_LIST );
|
wxTextValidator * tval = new wxTextValidator ( wxFILTER_EXCLUDE_CHAR_LIST );
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ public:
|
|||||||
* Shows a message as a modal dialog or as a notification.
|
* Shows a message as a modal dialog or as a notification.
|
||||||
*/
|
*/
|
||||||
static void MessageBox ( const wxString& msg, const bool notify = false );
|
static void MessageBox ( const wxString& msg, const bool notify = false );
|
||||||
|
static void AsyncMessageBox ( const wxString& msg, const bool notify = false );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a validator excluding file name forbidden characters, path
|
* Creates a validator excluding file name forbidden characters, path
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ TimeredStatusBar::TimeredStatusBar ( wxWindow * parent)
|
|||||||
{
|
{
|
||||||
m_numFields = 3;
|
m_numFields = 3;
|
||||||
/* We use default reasonable widths for CAPS and NUM. */
|
/* We use default reasonable widths for CAPS and NUM. */
|
||||||
const int widths[3] = {-1, 70, 70};
|
const int widths[3] = {-1, 70, 90};
|
||||||
SetFieldsCount ( m_numFields, widths );
|
SetFieldsCount ( m_numFields, widths );
|
||||||
m_timer.Stop();
|
m_timer.Stop();
|
||||||
m_timer.SetOwner ( this );
|
m_timer.SetOwner ( this );
|
||||||
|
|||||||
107
XS7.cpp
107
XS7.cpp
@@ -14,56 +14,25 @@
|
|||||||
#include "page.xpm"
|
#include "page.xpm"
|
||||||
#include <wx/stdpaths.h>
|
#include <wx/stdpaths.h>
|
||||||
#include <wx/cmdline.h>
|
#include <wx/cmdline.h>
|
||||||
|
#include <wx/aboutdlg.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
IMPLEMENT_CLASS( XS7, S7 )
|
||||||
|
|
||||||
XS7::XS7(wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style)
|
XS7::XS7(wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style)
|
||||||
: S7(parent, id, caption, pos, size, style)
|
: S7(parent, id, caption, pos, size, style)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool XS7::ParseCmdLine()
|
void XS7::Setup(wxConfig * config)
|
||||||
{
|
{
|
||||||
wxCmdLineParser p;
|
m_config = config;
|
||||||
p.SetCmdLine ( wxApp::GetInstance()->argc, wxApp::GetInstance()->argv );
|
|
||||||
p.SetSwitchChars ( _T ( "-" ) );
|
|
||||||
p.AddOption ( _T ( "c" ), wxEmptyString, _ ( "Config file tag." ) );
|
|
||||||
p.AddSwitch ( _T ( "v" ), wxEmptyString, _ ( "Show version and quit." ) );
|
|
||||||
p.AddSwitch ( _T ( "h" ), wxEmptyString, _ ( "Show help and quit." ) );
|
|
||||||
p.Parse ( false );
|
|
||||||
if ( p.Found ( _T ( "c" ) ) )
|
|
||||||
{
|
|
||||||
p.Found ( _T ( "c" ), &m_configTag );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ( p.Found ( _T ( "h" ) ) )
|
|
||||||
{
|
|
||||||
p.Usage();
|
|
||||||
return false; //Exit code is 255, not clean.
|
|
||||||
}
|
|
||||||
if ( p.Found ( _T ( "v" ) ) )
|
|
||||||
{
|
|
||||||
cout << ( _APPNAME_ + _ ( " - version " ) + to_string(_APPVERSION_) ) << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void XS7::Setup()
|
|
||||||
{
|
|
||||||
const wxString configDir = wxFileConfig::GetLocalFile ( _APPNAME_, wxCONFIG_USE_SUBDIR ).GetPath();
|
|
||||||
if ( !wxFileName::Exists ( configDir ) )
|
|
||||||
wxFileName::Mkdir ( configDir );
|
|
||||||
|
|
||||||
const wxString configBaseName = m_configTag.IsEmpty()
|
|
||||||
? _APPNAME_
|
|
||||||
: _APPNAME_ + wxString("-") + m_configTag;
|
|
||||||
m_config = std::make_unique<wxFileConfig>(_APPNAME_, _T("SET"), configBaseName,
|
|
||||||
wxEmptyString, wxCONFIG_USE_SUBDIR);
|
|
||||||
TimeredStatusBar * sb = new TimeredStatusBar(this);
|
TimeredStatusBar * sb = new TimeredStatusBar(this);
|
||||||
SetStatusBar(sb);
|
SetStatusBar(sb);
|
||||||
|
|
||||||
m_insaneWidget = new XInsaneWidget(panMain, sb, m_config.get());
|
m_insaneWidget = new XInsaneWidget(panMain);
|
||||||
szMain->Add(m_insaneWidget, 0, wxGROW | wxALL);
|
m_insaneWidget->Setup(m_config, sb);
|
||||||
|
szMain->Insert(2, m_insaneWidget, 1, wxGROW | wxALL);
|
||||||
|
|
||||||
dpkDestination->Bind ( wxEVT_DIRPICKER_CHANGED, &XS7::OnDpkRepositoryChange, this );
|
dpkDestination->Bind ( wxEVT_DIRPICKER_CHANGED, &XS7::OnDpkRepositoryChange, this );
|
||||||
dpkDestination->GetTextCtrl()->Bind ( wxEVT_LEFT_DCLICK, &XS7::OnDpkDoubleClick, this );
|
dpkDestination->GetTextCtrl()->Bind ( wxEVT_LEFT_DCLICK, &XS7::OnDpkDoubleClick, this );
|
||||||
@@ -73,7 +42,7 @@ void XS7::Setup()
|
|||||||
|
|
||||||
txtBasename->SetValidator(*MiscTools::MakeFileNameValidator(false));
|
txtBasename->SetValidator(*MiscTools::MakeFileNameValidator(false));
|
||||||
txtBasename->Bind(wxEVT_LEFT_UP, &XS7::OnAbout, this);
|
txtBasename->Bind(wxEVT_LEFT_UP, &XS7::OnAbout, this);
|
||||||
MiscTools::RestoreSizePos(m_config.get(), this, wxString("/" + wxString(_APPNAME_)));
|
MiscTools::RestoreSizePos(m_config, this, wxString("/" + wxString(_APPNAME_)));
|
||||||
|
|
||||||
S7::SetTitle(wxString(_APPNAME_) + " - version " + to_string(_APPVERSION_));
|
S7::SetTitle(wxString(_APPNAME_) + " - version " + to_string(_APPVERSION_));
|
||||||
|
|
||||||
@@ -81,14 +50,43 @@ void XS7::Setup()
|
|||||||
wxString fixedTip = _("'Shift + left' click to generate a new destination file name.");
|
wxString fixedTip = _("'Shift + left' click to generate a new destination file name.");
|
||||||
fixedTip += _T("\n") + m_insaneWidget->lblNewDoc->GetToolTipText();
|
fixedTip += _T("\n") + m_insaneWidget->lblNewDoc->GetToolTipText();
|
||||||
m_insaneWidget->lblNewDoc->SetToolTip(fixedTip);
|
m_insaneWidget->lblNewDoc->SetToolTip(fixedTip);
|
||||||
|
|
||||||
|
Bind(wxEVT_CLOSE_WINDOW, &XS7::OnClose, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
XS7::~XS7()
|
XS7::~XS7()
|
||||||
{
|
{
|
||||||
if (m_config)
|
if (m_config)
|
||||||
MiscTools::SaveSizePos(m_config.get(), this, wxString("/") + _APPNAME_);
|
MiscTools::SaveSizePos(m_config, this, wxString("/") + _APPNAME_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XS7::OnClose(wxCloseEvent& evt)
|
||||||
|
{
|
||||||
|
if (!m_insaneWidget)
|
||||||
|
{
|
||||||
|
evt.Skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (m_insaneWidget->IsScannerDiscoveryRunning())
|
||||||
|
{
|
||||||
|
evt.Veto();
|
||||||
|
TimeredStatusBar * sb = static_cast<TimeredStatusBar*> (GetStatusBar());
|
||||||
|
if (sb)
|
||||||
|
sb->SetTransientText(_("Veto: scanner discovery is running."));
|
||||||
|
evt.Skip(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(m_insaneWidget->IsScanning())
|
||||||
|
{
|
||||||
|
m_insaneWidget->CancelScanning();
|
||||||
|
evt.Skip(false); // The window remains open.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
evt.Skip();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void XS7::OnDpkRepositoryChange ( wxFileDirPickerEvent& evt )
|
void XS7::OnDpkRepositoryChange ( wxFileDirPickerEvent& evt )
|
||||||
{
|
{
|
||||||
m_config->Write ( _T ( "/DocRoot" ), dpkDestination->GetPath() );
|
m_config->Write ( _T ( "/DocRoot" ), dpkDestination->GetPath() );
|
||||||
@@ -114,6 +112,18 @@ void XS7::OnAppKeyPressed(wxKeyEvent& evt)
|
|||||||
{
|
{
|
||||||
if (evt.GetKeyCode() == 'Q')
|
if (evt.GetKeyCode() == 'Q')
|
||||||
Close();
|
Close();
|
||||||
|
// Create a new instance of the application window.
|
||||||
|
if (evt.GetKeyCode() == 'N')
|
||||||
|
{
|
||||||
|
static int instanceId = 0;
|
||||||
|
instanceId++;
|
||||||
|
XS7 * instance = new XS7(nullptr, wxID_ANY);
|
||||||
|
instance->Show(false);
|
||||||
|
instance->Setup(m_config);
|
||||||
|
const wxString title = instance->GetTitle() + _T(" (#") + to_string(instanceId) + _T(")");
|
||||||
|
instance->SetTitle(title);
|
||||||
|
instance->Show(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (evt.GetKeyCode() == WXK_ESCAPE)
|
if (evt.GetKeyCode() == WXK_ESCAPE)
|
||||||
if (m_insaneWidget)
|
if (m_insaneWidget)
|
||||||
@@ -123,7 +133,7 @@ void XS7::OnAppKeyPressed(wxKeyEvent& evt)
|
|||||||
|
|
||||||
void XS7::OnNewDocLeftClick ( wxMouseEvent& evt )
|
void XS7::OnNewDocLeftClick ( wxMouseEvent& evt )
|
||||||
{
|
{
|
||||||
if ( !evt.ShiftDown() )
|
if ( !evt.ShiftDown() || !m_insaneWidget->lblNewDoc->IsEnabled() )
|
||||||
{
|
{
|
||||||
evt.Skip();
|
evt.Skip();
|
||||||
return;
|
return;
|
||||||
@@ -158,11 +168,14 @@ void XS7::OnAbout(wxMouseEvent& evt)
|
|||||||
evt.Skip();
|
evt.Skip();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const wxString msg = wxString(_APPNAME_) + _(" - version ") + to_string((_APPVERSION_))
|
wxAboutDialogInfo info;
|
||||||
+ _ (", using InsaneWidget.\n\n")
|
info.AddDeveloper("Saleem Edah-Tally");
|
||||||
+ _ ( "Copyright: Saleem Edah-Tally [Surgeon] [Hobbyist developer]\n" )
|
info.SetCopyright(_("Copyright: Saleem Edah-Tally [Surgeon] [Hobbyist developer]"));
|
||||||
+ _ ( "License: CeCILL/CeCILL-C per file header." );
|
info.SetLicence(_ ( "License: CeCILL/CeCILL-C per file header." ));
|
||||||
|
info.SetVersion(_("version ") + to_string(_APPVERSION_) + _ (", using InsaneWidget."));
|
||||||
|
info.AddTranslator("Saleem Edah-Tally (FR)");
|
||||||
|
info.SetIcon(page_xpm);
|
||||||
|
wxAboutBox(info, this);
|
||||||
|
|
||||||
MiscTools::MessageBox(msg);
|
|
||||||
evt.Skip();
|
evt.Skip();
|
||||||
}
|
}
|
||||||
|
|||||||
14
XS7.h
14
XS7.h
@@ -17,27 +17,23 @@
|
|||||||
|
|
||||||
class XS7 : public S7
|
class XS7 : public S7
|
||||||
{
|
{
|
||||||
|
DECLARE_DYNAMIC_CLASS( XS7 )
|
||||||
public:
|
public:
|
||||||
XS7(wxWindow* parent, wxWindowID id = SYMBOL_S7_IDNAME, const wxString& caption = SYMBOL_S7_TITLE,
|
XS7(wxWindow* parent, wxWindowID id = SYMBOL_S7_IDNAME, const wxString& caption = SYMBOL_S7_TITLE,
|
||||||
const wxPoint& pos = SYMBOL_S7_POSITION, const wxSize& size = SYMBOL_S7_SIZE, long style = SYMBOL_S7_STYLE );
|
const wxPoint& pos = SYMBOL_S7_POSITION, const wxSize& size = SYMBOL_S7_SIZE, long style = SYMBOL_S7_STYLE );
|
||||||
virtual ~XS7();
|
virtual ~XS7();
|
||||||
bool ParseCmdLine();
|
|
||||||
void Setup();
|
void Setup(wxConfig * config);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<wxConfig> m_config = nullptr;
|
wxConfig * m_config = nullptr;
|
||||||
XInsaneWidget * m_insaneWidget = nullptr;
|
XInsaneWidget * m_insaneWidget = nullptr;
|
||||||
|
|
||||||
/*
|
|
||||||
* An optional tag for wxConfig files. This allows using different profiles
|
|
||||||
* by specifying the -c command line option.
|
|
||||||
*/
|
|
||||||
wxString m_configTag;
|
|
||||||
|
|
||||||
void OnDpkRepositoryChange ( wxFileDirPickerEvent& evt );
|
void OnDpkRepositoryChange ( wxFileDirPickerEvent& evt );
|
||||||
void OnDpkDoubleClick ( wxMouseEvent& evt );
|
void OnDpkDoubleClick ( wxMouseEvent& evt );
|
||||||
void OnAppKeyPressed(wxKeyEvent& evt);
|
void OnAppKeyPressed(wxKeyEvent& evt);
|
||||||
void OnNewDocLeftClick ( wxMouseEvent& evt ); // wxStaticText in m_insaneWidget.
|
void OnNewDocLeftClick ( wxMouseEvent& evt ); // wxStaticText in m_insaneWidget.
|
||||||
|
void OnClose(wxCloseEvent& evt);
|
||||||
void OnAbout(wxMouseEvent& evt);
|
void OnAbout(wxMouseEvent& evt);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user