Add a 'Stamp' widget.
Place one or multiple stamps on scanned pages in defined locations. A stamp is understood here as - a transparent text in a transparent frame with no borders - an opaque text on an opaque background with no borders. Stamp parameters: - text - font - foreground colour - background colour - angle of rotation - transparency. Locations: - centre - cardinal directions - inter-cardinal directions.
This commit is contained in:
@@ -9,23 +9,24 @@ find_package(LibInsane REQUIRED)
|
||||
find_package(PoDoFo REQUIRED)
|
||||
find_package(Paper REQUIRED)
|
||||
|
||||
|
||||
include_directories(${CMAKE_CURRENT_LIST_DIR}
|
||||
${CMAKE_CURRENT_LIST_DIR}/UI
|
||||
${CMAKE_CURRENT_LIST_DIR}/../StampWidget
|
||||
${CMAKE_CURRENT_LIST_DIR}/../StampWidget/UI
|
||||
${CMAKE_CURRENT_LIST_DIR}/../Utilities)
|
||||
|
||||
|
||||
add_library(insanewidget STATIC
|
||||
UI/InsaneWidget.cpp
|
||||
UI/ScannerWidget.cpp
|
||||
|
||||
Common.h
|
||||
DefsInsaneWidget.h
|
||||
XInsaneWidget.cpp
|
||||
XScannerWidget.cpp
|
||||
InsaneWorker.cpp
|
||||
PixelToImageWriter.cpp
|
||||
PixelToPdfWriter.cpp)
|
||||
|
||||
target_link_libraries(insanewidget minutils
|
||||
target_link_libraries(insanewidget minutils stampwidget
|
||||
${wxWidgets_LIBRARIES}
|
||||
${LIBINSANE_LIBRARIES}
|
||||
${PODOFO_LIBRARIES}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// /*
|
||||
// * File: Common.h
|
||||
// * File: DefsInsaneWidget.h
|
||||
// * Author: Saleem Edah-Tally - nmset@yandex.com
|
||||
// * License : CeCILL-C
|
||||
// * Copyright Saleem Edah-Tally - © 2025
|
||||
// *
|
||||
// * Created on 27 06 2025, 20:34
|
||||
// * Created on 08 07 2025, 20:44
|
||||
// */
|
||||
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
#ifndef DEFSINSANEWIDGET_H
|
||||
#define DEFSINSANEWIDGET_H
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
@@ -27,4 +27,4 @@ static void UpdateExtensionsMap()
|
||||
Extensions[PNM] = "pnm";
|
||||
}
|
||||
|
||||
#endif // COMMON_H
|
||||
#endif // DEFSINSANEWIDGET_H
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <paper.h>
|
||||
#include <libinsane/log.h>
|
||||
#include <libinsane/safebet.h>
|
||||
#include <libinsane/error.h>
|
||||
#include <libinsane/util.h>
|
||||
@@ -273,7 +272,8 @@ bool InsaneWorker::ConfigureDevice(const std::string& deviceId,
|
||||
* Sounds weird but needed.
|
||||
*/
|
||||
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;
|
||||
if (GetBottomRight(br))
|
||||
{
|
||||
|
||||
@@ -8,14 +8,17 @@
|
||||
// */
|
||||
|
||||
#include "PixelToImageWriter.h"
|
||||
#include <Common.h>
|
||||
#include <StampWorker.h>
|
||||
#include <fstream>
|
||||
#include <DefsInsaneWidget.h>
|
||||
#include <DefsStampWidget.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool PixelToImageWriter::Convert(const std::string& pixelFilePath,
|
||||
int imageWidth, int imageHeight,
|
||||
int outputFormat, wxImage * image)
|
||||
int imageWidth, int imageHeight,
|
||||
std::vector<StampDescriptor*> * descriptors,
|
||||
int outputFormat, wxImage * image)
|
||||
{
|
||||
UpdateExtensionsMap();
|
||||
wxImage * outImage = image;
|
||||
@@ -35,6 +38,16 @@ bool PixelToImageWriter::Convert(const std::string& pixelFilePath,
|
||||
raw.assign(istreambuf_iterator<char>(ifs), istreambuf_iterator<char>());
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -10,19 +10,26 @@
|
||||
#ifndef PIXELTOIMAGEWRITER_H
|
||||
#define PIXELTOIMAGEWRITER_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "DefsInsaneWidget.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <wx/wx.h>
|
||||
|
||||
struct StampDescriptor;
|
||||
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
DECLARE_DYNAMIC_CLASS( PixelToImageWriter )
|
||||
public:
|
||||
static bool Convert(const std::string& pixelFilePath,
|
||||
int imageWidth, int imageHeight, int outputFormat = PNG,
|
||||
wxImage * image = nullptr);
|
||||
int imageWidth, int imageHeight, std::vector<StampDescriptor*> * descriptors,
|
||||
int outputFormat = PNG, wxImage * image = nullptr);
|
||||
};
|
||||
|
||||
#endif // PIXELTOIMAGEWRITER_H
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
|
||||
#include "PixelToPdfWriter.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
#include <StampWorker.h>
|
||||
#include <DefsInsaneWidget.h>
|
||||
#include <DefsStampWidget.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace PoDoFo;
|
||||
@@ -29,8 +33,9 @@ PixelToPdfWriter::PixelToPdfWriter()
|
||||
}
|
||||
|
||||
|
||||
bool PixelToPdfWriter::AddPageAt(const std::string& pixelFile, uint width, uint height, uint index,
|
||||
PoDoFo::PdfPageSize pageSize, PoDoFo::PdfColorSpace)
|
||||
bool PixelToPdfWriter::AddPageAt(const std::string& pixelFile, uint width, uint height, uint index,
|
||||
std::vector<StampDescriptor*> * descriptors,
|
||||
PoDoFo::PdfPageSize pageSize, PoDoFo::PdfColorSpace)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -46,6 +51,23 @@ bool PixelToPdfWriter::AddPageAt(const std::string& pixelFile, uint width, uint
|
||||
ifstream ifs(pixelFile, ios::binary);
|
||||
string content;
|
||||
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);
|
||||
|
||||
const uint pageNumber = m_doc.GetPages().GetCount();
|
||||
|
||||
@@ -12,13 +12,18 @@
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <podofo/podofo.h>
|
||||
#include <wx/wx.h>
|
||||
|
||||
struct StampDescriptor;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* page dimensions.\n
|
||||
* Account for page size.
|
||||
* Account for page size.\n
|
||||
* Optionally, a stamp image may be blended on the page.
|
||||
*/
|
||||
class PixelToPdfWriter
|
||||
{
|
||||
@@ -27,6 +32,7 @@ public:
|
||||
|
||||
PixelToPdfWriter();
|
||||
bool AddPageAt(const std::string& pixelFile, uint width, uint height, uint index,
|
||||
std::vector<StampDescriptor*> * descriptors,
|
||||
PoDoFo::PdfPageSize pageSize = PoDoFo::PdfPageSize::A4,
|
||||
PoDoFo::PdfColorSpace = PoDoFo::PdfColorSpace::DeviceRGB /*Unused*/);
|
||||
void Save(const std::string& pdfFile);
|
||||
|
||||
@@ -103,6 +103,7 @@ InsaneWidget::~InsaneWidget()
|
||||
void InsaneWidget::Init()
|
||||
{
|
||||
////@begin InsaneWidget member initialisation
|
||||
szInsaneWidgetMain = NULL;
|
||||
lblNewDoc = NULL;
|
||||
txtNewDoc = NULL;
|
||||
btnScan = NULL;
|
||||
@@ -119,11 +120,11 @@ void InsaneWidget::CreateControls()
|
||||
////@begin InsaneWidget content construction
|
||||
InsaneWidget* itemPanel1 = this;
|
||||
|
||||
wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
|
||||
itemPanel1->SetSizer(itemBoxSizer2);
|
||||
szInsaneWidgetMain = new wxBoxSizer(wxVERTICAL);
|
||||
itemPanel1->SetSizer(szInsaneWidgetMain);
|
||||
|
||||
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 );
|
||||
if (InsaneWidget::ShowToolTips())
|
||||
@@ -137,7 +138,7 @@ void InsaneWidget::CreateControls()
|
||||
|
||||
btnScan = new wxButton( itemPanel1, ID_Scan_BTN, _("Scan"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
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);
|
||||
|
||||
////@end InsaneWidget content construction
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
|
||||
////@begin forward declarations
|
||||
class wxBoxSizer;
|
||||
////@end forward declarations
|
||||
|
||||
/*!
|
||||
@@ -39,7 +40,7 @@
|
||||
#define SYMBOL_INSANEWIDGET_STYLE wxTAB_TRAVERSAL
|
||||
#define SYMBOL_INSANEWIDGET_TITLE _("InsaneWidget")
|
||||
#define SYMBOL_INSANEWIDGET_IDNAME ID_INSANEWIDGET
|
||||
#define SYMBOL_INSANEWIDGET_SIZE wxSize(400, 300)
|
||||
#define SYMBOL_INSANEWIDGET_SIZE wxDefaultSize
|
||||
#define SYMBOL_INSANEWIDGET_POSITION wxDefaultPosition
|
||||
////@end control identifiers
|
||||
|
||||
@@ -87,6 +88,7 @@ public:
|
||||
static bool ShowToolTips();
|
||||
|
||||
////@begin InsaneWidget member variables
|
||||
wxBoxSizer* szInsaneWidgetMain;
|
||||
wxStaticText* lblNewDoc;
|
||||
wxTextCtrl* txtNewDoc;
|
||||
wxButton* btnScan;
|
||||
|
||||
@@ -245,7 +245,7 @@
|
||||
<string name="proxy-Font">""</string>
|
||||
<string name="proxy-Foreground colour">""</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>
|
||||
<bool name="proxy-Hidden">0</bool>
|
||||
<string name="proxy-Icon">""</string>
|
||||
@@ -257,7 +257,7 @@
|
||||
<string name="proxy-Texture style">"Tiled"</string>
|
||||
<string name="proxy-Title">"InsaneWidget"</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>
|
||||
<bool name="proxy-wxBORDER_THEME">0</bool>
|
||||
<bool name="proxy-wxCAPTION">0</bool>
|
||||
@@ -303,13 +303,21 @@
|
||||
<long name="is-transient">0</long>
|
||||
<long name="locked">0</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-Platform">"<Any platform>"</string>
|
||||
<long name="proxy-Stretch factor">0</long>
|
||||
<bool name="proxy-wxADJUST_MINSIZE">0</bool>
|
||||
<bool name="proxy-wxBOTTOM">1</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-wxRIGHT">1</bool>
|
||||
<bool name="proxy-wxSHAPED">0</bool>
|
||||
<bool name="proxy-wxTOP">1</bool>
|
||||
<string name="title">"wxBoxSizer V"</string>
|
||||
<long name="title-mode">0</long>
|
||||
<string name="type">"dialog-control-document"</string>
|
||||
@@ -538,7 +546,8 @@
|
||||
<bool name="proxy-Separate files">0</bool>
|
||||
<long name="proxy-Stretch factor">0</long>
|
||||
<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>
|
||||
<bool name="proxy-wxADJUST_MINSIZE">0</bool>
|
||||
<bool name="proxy-wxBOTTOM">1</bool>
|
||||
@@ -654,13 +663,21 @@
|
||||
<long name="is-transient">0</long>
|
||||
<long name="locked">0</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-Orientation">"Vertical"</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-wxBOTTOM">1</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-wxRIGHT">1</bool>
|
||||
<bool name="proxy-wxSHAPED">0</bool>
|
||||
<bool name="proxy-wxTOP">1</bool>
|
||||
<string name="title">"wxBoxSizer V"</string>
|
||||
<long name="title-mode">0</long>
|
||||
<string name="type">"dialog-control-document"</string>
|
||||
|
||||
@@ -12,7 +12,10 @@
|
||||
#include <MiscTools.h>
|
||||
#include "PixelToImageWriter.h"
|
||||
#include "PixelToPdfWriter.h"
|
||||
#include <Common.h>
|
||||
#include <DefsInsaneWidget.h>
|
||||
#include <DefsStampWidget.h>
|
||||
#include <XStampWidget.h>
|
||||
#include <StampWorker.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -46,13 +49,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.
|
||||
* However,
|
||||
* deviceId, source, sourceIndex, mode, resolution, paperSize
|
||||
* 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
|
||||
* 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)
|
||||
{
|
||||
@@ -60,6 +66,12 @@ public:
|
||||
return;
|
||||
m_mode = mode;
|
||||
}
|
||||
void SetResolution(int resolution)
|
||||
{
|
||||
if (m_pixelFiles.size())
|
||||
return;
|
||||
m_resolution = resolution;
|
||||
}
|
||||
void SetOutputType(int outputType)
|
||||
{
|
||||
if (m_pixelFiles.size())
|
||||
@@ -101,6 +113,10 @@ public:
|
||||
return;
|
||||
m_paperSize = paperSize;
|
||||
}
|
||||
void SetStampDescriptors(vector<StampDescriptor*> * descriptors)
|
||||
{
|
||||
m_stampDescriptors = descriptors;
|
||||
}
|
||||
std::pair<int, int> GetStartAndIncrement(InsaneWorker * insaneWorker)
|
||||
{
|
||||
wxASSERT_MSG(insaneWorker != nullptr, "insaneWorker is NULL.");
|
||||
@@ -162,11 +178,12 @@ public:
|
||||
|
||||
m_sb->SetStatusText(msg);
|
||||
};
|
||||
|
||||
|
||||
if (m_outputType != PDF)
|
||||
{
|
||||
// Convert pixel file to PNG using netpbm.
|
||||
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.");
|
||||
cerr << msg << endl;
|
||||
@@ -191,7 +208,8 @@ public:
|
||||
cerr << msg << endl;
|
||||
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.");
|
||||
cerr << msg << endl;
|
||||
@@ -241,6 +259,17 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
void OnStartScanSession(uint pageIndex, const ImageAttributes& imageAttributes) override
|
||||
{
|
||||
if (!m_stampDescriptors)
|
||||
return;
|
||||
for (StampDescriptor * descriptor : *m_stampDescriptors)
|
||||
{
|
||||
if (descriptor->text.IsEmpty())
|
||||
continue;
|
||||
descriptor->image = StampWorker::CreateStamp(descriptor, m_resolution);
|
||||
}
|
||||
}
|
||||
void Reset()
|
||||
{
|
||||
// Don't reset calculated variables that depend on widgets.
|
||||
@@ -255,7 +284,9 @@ private:
|
||||
wxWeakRef<TimeredStatusBar> m_sb = nullptr;
|
||||
std::unique_ptr<PixelToPdfWriter> m_pixelToPdfWriter;
|
||||
PixelFilesMap m_pixelFiles;
|
||||
vector<StampDescriptor*> * m_stampDescriptors = nullptr;
|
||||
string m_mode = "Color";
|
||||
int m_resolution = -1;
|
||||
uint m_outputType = PDF;
|
||||
wxString m_paperSize = _T("A4");
|
||||
bool m_adf = false;
|
||||
@@ -268,12 +299,20 @@ private:
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLASS( XInsaneWidget, InsaneWidget )
|
||||
|
||||
XInsaneWidget::XInsaneWidget(wxWindow* parent, TimeredStatusBar * sb, wxConfig * config, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
|
||||
: InsaneWidget(parent, id, pos, size, style)
|
||||
{
|
||||
UpdateExtensionsMap();
|
||||
m_config = config;
|
||||
m_sb = sb;
|
||||
}
|
||||
|
||||
XInsaneWidget::~XInsaneWidget() = default; // Important for mixing unique_ptr and PIMPL.
|
||||
|
||||
void XInsaneWidget::Setup()
|
||||
{
|
||||
lblNewDoc->Bind ( wxEVT_RIGHT_UP, &XInsaneWidget::OnLblNewDocRightClick, this );
|
||||
txtNewDoc->Bind ( wxEVT_KEY_UP, &XInsaneWidget::OnTxtNewDocKeyPressed, this );
|
||||
|
||||
@@ -283,7 +322,7 @@ XInsaneWidget::XInsaneWidget(wxWindow* parent, TimeredStatusBar * sb, wxConfig *
|
||||
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->SetConfig ( m_config );
|
||||
|
||||
|
||||
btnScan->Enable(false);
|
||||
btnScan->Bind ( wxEVT_RIGHT_UP, &XInsaneWidget::OnBtnScanRightClick, this );
|
||||
btnScan->Bind ( wxEVT_LEFT_UP, &XInsaneWidget::OnBtnScanClick, this );
|
||||
@@ -293,7 +332,6 @@ XInsaneWidget::XInsaneWidget(wxWindow* parent, TimeredStatusBar * sb, wxConfig *
|
||||
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.
|
||||
void XInsaneWidget::OnLblNewDocRightClick ( wxMouseEvent& evt )
|
||||
@@ -328,16 +366,38 @@ void XInsaneWidget::OnTxtNewDocKeyPressed ( wxKeyEvent& evt )
|
||||
evt.Skip();
|
||||
}
|
||||
|
||||
// Show the scanner widget.
|
||||
// Show the scanner widget or the stamp widgets.
|
||||
void XInsaneWidget::OnBtnScanRightClick ( wxMouseEvent& evt )
|
||||
{
|
||||
if ( m_scannerWidget->cmbDevices->GetCount() )
|
||||
if (evt.ControlDown())
|
||||
{
|
||||
const wxSize current = m_scannerWidget->GetSize();
|
||||
m_scannerWidget->SetSize ( wxSize ( 500, current.GetHeight() ) );
|
||||
if (!m_dlgStampWidgets)
|
||||
{
|
||||
m_dlgStampWidgets = std::make_unique<wxDialog>
|
||||
(nullptr, 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() );
|
||||
evt.Skip();
|
||||
else
|
||||
{
|
||||
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.
|
||||
@@ -367,7 +427,7 @@ void XInsaneWidget::OnBtnScanClick ( wxMouseEvent& evt )
|
||||
const std::pair<int, wxString> sourceAttributes = m_scannerWidget->GetScannerSource();
|
||||
const string source = sourceAttributes.second.ToStdString();
|
||||
const string mode = m_scannerWidget->GetScannerMode().ToStdString();
|
||||
int resolution = 300;
|
||||
int resolution = -1; // No resolution with v4l devices.
|
||||
if ( !m_scannerWidget->GetScannerResolution().IsEmpty() )
|
||||
{
|
||||
resolution = std::stoi ( m_scannerWidget->GetScannerResolution().ToStdString() );
|
||||
@@ -379,10 +439,13 @@ void XInsaneWidget::OnBtnScanClick ( wxMouseEvent& evt )
|
||||
{
|
||||
m_scanProject->SetADF(adf);
|
||||
m_scanProject->SetMode(mode);
|
||||
m_scanProject->SetResolution(resolution);
|
||||
m_scanProject->SetOutputType(outputType);
|
||||
m_scanProject->SetPaperSize(paperSize);
|
||||
m_scanProject->SetDoubleSided(doubleSided);
|
||||
m_scanProject->SetTotalNumberOfSides(total);
|
||||
m_stampDescriptors = m_stampWidgets->GetStampDescriptors();
|
||||
m_scanProject->SetStampDescriptors(m_stampDescriptors);
|
||||
|
||||
std::pair<int, int> startAndIncrement = m_scanProject->GetStartAndIncrement(m_insaneWorker.get());
|
||||
|
||||
|
||||
@@ -16,18 +16,23 @@
|
||||
#include <InsaneWidget.h>
|
||||
#include <InsaneWorker.h>
|
||||
#include <XScannerWidget.h>
|
||||
#include <XStampWidget.h>
|
||||
#include <XStampWidgets.h>
|
||||
#include <TimeredStatusBar.h>
|
||||
#include <ConfigEditorPopup.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
class BackgroundScannerDiscoveryEVH;
|
||||
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}}.
|
||||
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:
|
||||
* - Right click: define the number of pages to scan and double-sided scanning.
|
||||
@@ -48,9 +53,11 @@ typedef std::map<uint, std::tuple<std::string, InsaneWorkerEvent::ImageAttribute
|
||||
* Button:
|
||||
* - Right click: shows the scanner widget.
|
||||
* - Left click: starts scanning.
|
||||
* - Ctrl + Right click: show the stamp widgets dialog.
|
||||
*/
|
||||
class XInsaneWidget : public InsaneWidget
|
||||
{
|
||||
DECLARE_DYNAMIC_CLASS( XInsaneWidget )
|
||||
public:
|
||||
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 );
|
||||
@@ -58,14 +65,19 @@ public:
|
||||
void ResetScanProject();
|
||||
void CancelScanning(); // Not tested, probably doesn't work as intended.
|
||||
void EnableScanButton(bool enable); // For CallAfter.
|
||||
void Setup();
|
||||
private:
|
||||
wxConfig * m_config;
|
||||
wxWeakRef<TimeredStatusBar> m_sb;
|
||||
std::vector<StampDescriptor*> * m_stampDescriptors;
|
||||
|
||||
// Contains a popup to define the number of pages and double-sided scanning.
|
||||
std::unique_ptr<ConfigEditorPopup> m_pageStack;
|
||||
// Contains the scanner widget.
|
||||
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.
|
||||
std::unique_ptr<XScannerWidget> m_scannerWidget;
|
||||
std::unique_ptr<InsaneWorker> m_insaneWorker;
|
||||
|
||||
@@ -9,13 +9,15 @@
|
||||
|
||||
#include "XScannerWidget.h"
|
||||
#include "XClientData.hpp"
|
||||
#include "Common.h"
|
||||
#include "DefsInsaneWidget.h"
|
||||
#include <libinsane/constants.h>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
IMPLEMENT_CLASS( XScannerWidget, ScannerWidget )
|
||||
|
||||
XScannerWidget::~XScannerWidget()
|
||||
{}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include <ScannerWidget.h>
|
||||
#include "TimeredStatusBar.h"
|
||||
#include "InsaneWorker.h"
|
||||
#include "Common.h"
|
||||
#include <map>
|
||||
|
||||
class BackgroundScannerDiscoveryEvent;
|
||||
@@ -33,6 +32,7 @@ class BackgroundScannerDiscoveryEvent;
|
||||
|
||||
class XScannerWidget : public ScannerWidget
|
||||
{
|
||||
DECLARE_DYNAMIC_CLASS( XScannerWidget )
|
||||
friend class BackgroundScannerDiscovery;
|
||||
public:
|
||||
XScannerWidget() {};
|
||||
|
||||
Reference in New Issue
Block a user