Allow cancelling a scan session.

- perform scanning in a thread
 - change the label of the scan button
 - trigger cancel with the same button and with the ESC key
 - process all GUI updates in asynchronous mode.

Do not use a top window as parent of popups:
 - If a top window goes away in an application with multiple instances of
 XInsaneWidget, any call to a scanner widget leads to a crash.

Minor changes.
This commit is contained in:
Saleem Edah-Tally
2025-07-11 21:10:59 +02:00
parent 3350f86ddf
commit 4b23b1f3de
12 changed files with 206 additions and 215 deletions

View File

@@ -31,6 +31,10 @@ 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.
Outputs: Outputs:
- a single PDF file with the number of requested pages - a single PDF file with the number of requested pages

View File

@@ -30,5 +30,4 @@ target_link_libraries(insanewidget minutils stampwidget
${wxWidgets_LIBRARIES} ${wxWidgets_LIBRARIES}
${LIBINSANE_LIBRARIES} ${LIBINSANE_LIBRARIES}
${PODOFO_LIBRARIES} ${PODOFO_LIBRARIES}
${NETPBM_LIBRARIES}
${PAPER_LIBRARIES}) ${PAPER_LIBRARIES})

View File

@@ -22,7 +22,6 @@
using namespace std; using namespace std;
#define IERR(e) ("[" + to_string(e) + "] " + lis_strerror(e)) #define IERR(e) ("[" + to_string(e) + "] " + lis_strerror(e))
static bool gs_cancelRequested = false;
InsaneWorker::InsaneWorker ( InsaneWorkerEvent * evh ) InsaneWorker::InsaneWorker ( InsaneWorkerEvent * evh )
{ {
@@ -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 << "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;
@@ -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,

View File

@@ -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";

View File

@@ -40,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
{ {
@@ -117,6 +156,41 @@ public:
{ {
m_stampDescriptors = 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.");
@@ -130,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,
@@ -158,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;
@@ -175,20 +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, if (!PixelToImageWriter::Convert(filePath, imageAttributes.width, imageAttributes.height,
m_stampDescriptors, m_outputType)) 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();
@@ -214,7 +296,7 @@ public:
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();
@@ -251,16 +333,19 @@ 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 void OnStartScanSession(uint pageIndex, const ImageAttributes& imageAttributes) override
{ {
// Dealing with stamps only.
if (!m_stampDescriptors) if (!m_stampDescriptors)
return; return;
for (StampDescriptor * descriptor : *m_stampDescriptors) for (StampDescriptor * descriptor : *m_stampDescriptors)
@@ -277,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:
@@ -295,6 +381,7 @@ 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?
}; };
@@ -316,7 +403,12 @@ void XInsaneWidget::Setup()
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());
@@ -336,12 +428,17 @@ void XInsaneWidget::Setup()
// 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 )
{ {
@@ -403,6 +500,12 @@ void XInsaneWidget::OnBtnScanRightClick ( wxMouseEvent& evt )
// 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())
{ {
@@ -453,9 +556,14 @@ void XInsaneWidget::OnBtnScanClick ( wxMouseEvent& evt )
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();
} }
@@ -468,8 +576,11 @@ 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)

View File

@@ -63,7 +63,7 @@ public:
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, 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 );
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(); void Setup();
private: private:

View File

@@ -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")

View File

@@ -1,23 +1,23 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package. # This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
# #
# SPDX-FileCopyrightText: 2025 Saleem EDAH-TALLY <set@nmset.info> #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-07-09 16:00+0200\n" "POT-Creation-Date: 2025-07-11 21:35+0200\n"
"PO-Revision-Date: 2025-07-09 16:03+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Saleem EDAH-TALLY <set@nmset.info>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: French <kde-francophone@kde.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: fr_FR\n" "Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"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"
"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,24 +39,15 @@ msgstr ""
"\n" "\n"
"'CTRL + clic' : à propos" "'CTRL + clic' : à propos"
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:128
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:129 #: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:129
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:132
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:125
msgid "New" msgid "New"
msgstr "Nouveau" msgstr "Nouveau"
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:130
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:131 #: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:131
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:134
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:127
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 #: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:136
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:139
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:132
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."
@@ -64,16 +55,12 @@ 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/UI/InsaneWidget.cpp:139
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:142 #: ../../Resources/InsaneWidget/XInsaneWidget.cpp:188
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:135 #: ../../Resources/InsaneWidget/XInsaneWidget.cpp:302
msgid "Scan" msgid "Scan"
msgstr "Numériser" msgstr "Numériser"
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:140
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:141
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:144
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."
@@ -105,179 +92,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:171
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:107
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:132
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:133
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:177
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:113
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:138
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:139
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:181
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:117
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:142
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:143
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:190
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:124
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:149
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:150
msgid "Session cancelled." msgid "Session cancelled."
msgstr "Session annulée." msgstr "Session annulée."
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:162 #: ../../Resources/InsaneWidget/XInsaneWidget.cpp:208
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:141
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:166
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:167
msgid "Scanning: " msgid "Scanning: "
msgstr "Numérisation :" msgstr "Numérisation :"
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:164 #: ../../Resources/InsaneWidget/XInsaneWidget.cpp:210
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:143
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:168
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:169
msgid "Front face: " msgid "Front face: "
msgstr "Recto :" msgstr "Recto :"
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:166 #: ../../Resources/InsaneWidget/XInsaneWidget.cpp:212
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:145
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:170
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:171
msgid "Back face: " msgid "Back face: "
msgstr "Verso :" msgstr "Verso :"
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:170 #: ../../Resources/InsaneWidget/XInsaneWidget.cpp:216
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:149
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:174
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:175
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:248
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:180
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:206
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:207
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:248
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:180
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:206
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:207
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:255
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:186
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:212
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:213
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:214
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:298
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:243
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:255
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:256
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:257
msgid "Finished." msgid "Finished."
msgstr "Terminé." msgstr "Terminé."
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:333 #: ../../Resources/InsaneWidget/XInsaneWidget.cpp:398
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:317
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:356
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:355
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:351
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:352
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:401
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:320
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:359
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:358
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:354
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:355
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:62
#: ../../Resources/InsaneWidget/XScannerWidget.cpp:64 #: ../../Resources/InsaneWidget/XScannerWidget.cpp:64
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:65
#: ../../Resources/InsaneWidget/XScannerWidget.cpp:67 #: ../../Resources/InsaneWidget/XScannerWidget.cpp:67
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:105 ../../XS7.cpp:107 #: ../../XS7.cpp:107
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:129 ../../XS7.cpp:131 #: ../../XS7.cpp:136
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:137 ../../XS7.cpp:139 #: ../../XS7.cpp:144
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 ../../XS7.cpp:159 ../../XS7.cpp:161 #: ../../XS7.cpp:166
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:160 ../../XS7.cpp:162 #: ../../XS7.cpp:167
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:45
#: ../../Resources/InsaneWidget/UI/InsaneWidget.h:49
#: ../../Resources/InsaneWidget/UI/InsaneWidget.h:41 #: ../../Resources/InsaneWidget/UI/InsaneWidget.h:41
msgid "InsaneWidget" msgid "InsaneWidget"
msgstr "InsaneWidget" msgstr "InsaneWidget"
@@ -310,34 +231,23 @@ 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:397
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:316
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:355
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:354
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:350
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:351
msgid "Double sided:" msgid "Double sided:"
msgstr "Recto-verso :" msgstr "Recto-verso :"
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:334 #: ../../Resources/InsaneWidget/XInsaneWidget.cpp:399
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:318
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:357
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:356
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:352
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:353
msgid "Total:" msgid "Total:"
msgstr "Total :" msgstr "Total :"
#: ../../XS7.cpp:46 ../../XS7.cpp:81 ../../XS7.cpp:82 ../../XS7.cpp:84 #: ../../XS7.cpp:84
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 ../../XS7.cpp:157 #: ../../XS7.cpp:47 ../../XS7.cpp:164
#: ../../XS7.cpp:47 ../../XS7.cpp:159
msgid " - version " msgid " - version "
msgstr " - version " msgstr " - version "
#: ../../XS7.cpp:122 ../../XS7.cpp:157 ../../XS7.cpp:158 ../../XS7.cpp:160 #: ../../XS7.cpp:165
msgid "" msgid ""
", using InsaneWidget.\n" ", using InsaneWidget.\n"
"\n" "\n"
@@ -345,34 +255,26 @@ msgstr ""
", utilisant InsaneWidget.\n" ", utilisant InsaneWidget.\n"
"\n" "\n"
#: ../../Resources/InsaneWidget/XScannerWidget.cpp:73
#: ../../Resources/InsaneWidget/XScannerWidget.cpp:85
#: ../../Resources/InsaneWidget/XScannerWidget.cpp:87 #: ../../Resources/InsaneWidget/XScannerWidget.cpp:87
msgid " device(s) found." msgid " device(s) found."
msgstr " périphériques trouvé(s)." msgstr " périphériques trouvé(s)."
#: ../../XS7.cpp:29 ../../XS7.cpp:31 #: ../../XS7.cpp:31
msgid "Config file tag." msgid "Config file tag."
msgstr "Suffixe du fichier de configuration." msgstr "Suffixe du fichier de configuration."
#: ../../XS7.cpp:30 ../../XS7.cpp:32 #: ../../XS7.cpp:32
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 ../../XS7.cpp:33 #: ../../XS7.cpp:33
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:461
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:391
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:390
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:408
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:409
msgid "Destination file missing." msgid "Destination file missing."
msgstr "Fichier de destination manquant." msgstr "Fichier de destination manquant."
#: ../../Resources/InsaneWidget/UI/StampWidget.cpp:130
#: ../../Resources/InsaneWidget/UI/StampWidget.cpp:131
#: ../../Resources/StampWidget/UI/StampWidget.cpp:140 #: ../../Resources/StampWidget/UI/StampWidget.cpp:140
msgid "" msgid ""
"Create a stamp with this text, which can be multiline.\n" "Create a stamp with this text, which can be multiline.\n"
@@ -385,134 +287,92 @@ msgstr ""
"CTRL + S : sauvegarder le texte actuel.\n" "CTRL + S : sauvegarder le texte actuel.\n"
"CTRL + R : restaurer le texte sauvegardé." "CTRL + R : restaurer le texte sauvegardé."
#: ../../Resources/InsaneWidget/UI/StampWidget.cpp:138
#: ../../Resources/InsaneWidget/UI/StampWidget.cpp:139
#: ../../Resources/StampWidget/UI/StampWidget.cpp:188 #: ../../Resources/StampWidget/UI/StampWidget.cpp:188
msgid "Select the font of the stamp text." msgid "Select the font of the stamp text."
msgstr "Sélectionnez la police de caractère du texte." msgstr "Sélectionnez la police de caractère du texte."
#: ../../Resources/InsaneWidget/UI/StampWidget.cpp:143
#: ../../Resources/InsaneWidget/UI/StampWidget.cpp:144
msgid "Select the colour of the stamp text." msgid "Select the colour of the stamp text."
msgstr "Sélectionnez la couleur du texte." msgstr "Sélectionnez la couleur du texte."
#: ../../Resources/InsaneWidget/UI/StampWidget.cpp:148
#: ../../Resources/InsaneWidget/UI/StampWidget.cpp:155
#: ../../Resources/StampWidget/UI/StampWidget.cpp:199 #: ../../Resources/StampWidget/UI/StampWidget.cpp:199
msgid "Select the rotation angle of the stamp text." msgid "Select the rotation angle of the stamp text."
msgstr "Sélectionnez l'angle de rotation du texte." msgstr "Sélectionnez l'angle de rotation du texte."
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:144
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:147
msgid "Stamp" msgid "Stamp"
msgstr "Tampon" msgstr "Tampon"
#: ../../Resources/InsaneWidget/PixelToImageWriter.cpp:34
#: ../../Resources/InsaneWidget/PixelToImageWriter.cpp:35 #: ../../Resources/InsaneWidget/PixelToImageWriter.cpp:35
msgid "Failed to read raw file." msgid "Failed to read raw file."
msgstr "Échec de lecture du fichier brut." msgstr "Échec de lecture du fichier brut."
#: ../../Resources/InsaneWidget/PixelToImageWriter.cpp:60
#: ../../Resources/InsaneWidget/PixelToImageWriter.cpp:68
#: ../../Resources/InsaneWidget/PixelToImageWriter.cpp:69 #: ../../Resources/InsaneWidget/PixelToImageWriter.cpp:69
msgid "Unhandled output image format." msgid "Unhandled output image format."
msgstr "Format de fichier d'image en sortie non pris en charge." msgstr "Format de fichier d'image en sortie non pris en charge."
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:187 #: ../../Resources/InsaneWidget/XInsaneWidget.cpp:229
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:188
msgid "Failed to create output image." msgid "Failed to create output image."
msgstr "Échec de création de l'image de sortie." msgstr "Échec de création de l'image de sortie."
#: ../../Resources/InsaneWidget/UI/StampWidget.h:46
#: ../../Resources/InsaneWidget/UI/StampWidget.h:47
#: ../../Resources/StampWidget/UI/StampWidget.h:57 #: ../../Resources/StampWidget/UI/StampWidget.h:57
msgid "StampWidget" msgid "StampWidget"
msgstr "" msgstr ""
#: ../../Resources/InsaneWidget/UI/StampWidget.cpp:150
#: ../../Resources/StampWidget/UI/StampWidget.cpp:171 #: ../../Resources/StampWidget/UI/StampWidget.cpp:171
msgid "Location of the stamp on the output." msgid "Location of the stamp on the output."
msgstr "Place du tampon dans la sortie." msgstr "Place du tampon dans la sortie."
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:156
#: ../../Resources/InsaneWidget/UI/StampWidgets.cpp:127
#: ../../Resources/StampWidget/UI/StampWidgets.cpp:127 #: ../../Resources/StampWidget/UI/StampWidgets.cpp:127
msgid "+" msgid "+"
msgstr "" msgstr ""
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:158
#: ../../Resources/InsaneWidget/UI/StampWidgets.cpp:129
#: ../../Resources/StampWidget/UI/StampWidgets.cpp:129 #: ../../Resources/StampWidget/UI/StampWidgets.cpp:129
msgid "Add a stamp widget." msgid "Add a stamp widget."
msgstr "Ajouter un widget 'Tampon'." msgstr "Ajouter un widget 'Tampon'."
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:161
#: ../../Resources/InsaneWidget/UI/StampWidgets.cpp:132
#: ../../Resources/StampWidget/UI/StampWidgets.cpp:132 #: ../../Resources/StampWidget/UI/StampWidgets.cpp:132
msgid "-" msgid "-"
msgstr "" msgstr ""
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:163
#: ../../Resources/InsaneWidget/UI/StampWidgets.cpp:134
#: ../../Resources/StampWidget/UI/StampWidgets.cpp:134 #: ../../Resources/StampWidget/UI/StampWidgets.cpp:134
msgid "Remove the selected stamp widget." msgid "Remove the selected stamp widget."
msgstr "Supprimer le widget 'Tampon' sélectionné." msgstr "Supprimer le widget 'Tampon' sélectionné."
#: ../../Resources/InsaneWidget/XStampWidget.cpp:56
#: ../../Resources/InsaneWidget/XStampWidget.cpp:57
#: ../../Resources/StampWidget/XStampWidget.cpp:76 #: ../../Resources/StampWidget/XStampWidget.cpp:76
msgid "Centre" msgid "Centre"
msgstr "Centre" msgstr "Centre"
#: ../../Resources/InsaneWidget/XStampWidget.cpp:57
#: ../../Resources/InsaneWidget/XStampWidget.cpp:58
#: ../../Resources/StampWidget/XStampWidget.cpp:77 #: ../../Resources/StampWidget/XStampWidget.cpp:77
msgid "North" msgid "North"
msgstr "Nord" msgstr "Nord"
#: ../../Resources/InsaneWidget/XStampWidget.cpp:57
#: ../../Resources/InsaneWidget/XStampWidget.cpp:58
#: ../../Resources/StampWidget/XStampWidget.cpp:77 #: ../../Resources/StampWidget/XStampWidget.cpp:77
msgid "South" msgid "South"
msgstr "Sud" msgstr "Sud"
#: ../../Resources/InsaneWidget/XStampWidget.cpp:57
#: ../../Resources/InsaneWidget/XStampWidget.cpp:58
#: ../../Resources/StampWidget/XStampWidget.cpp:77 #: ../../Resources/StampWidget/XStampWidget.cpp:77
msgid "West" msgid "West"
msgstr "Ouest" msgstr "Ouest"
#: ../../Resources/InsaneWidget/XStampWidget.cpp:58
#: ../../Resources/InsaneWidget/XStampWidget.cpp:59
#: ../../Resources/StampWidget/XStampWidget.cpp:78 #: ../../Resources/StampWidget/XStampWidget.cpp:78
msgid "North-east" msgid "North-east"
msgstr "Nord-est" msgstr "Nord-est"
#: ../../Resources/InsaneWidget/XStampWidget.cpp:58
#: ../../Resources/InsaneWidget/XStampWidget.cpp:59
#: ../../Resources/StampWidget/XStampWidget.cpp:78 #: ../../Resources/StampWidget/XStampWidget.cpp:78
msgid "North-west" msgid "North-west"
msgstr "Nord-ouest" msgstr "Nord-ouest"
#: ../../Resources/InsaneWidget/XStampWidget.cpp:59
#: ../../Resources/InsaneWidget/XStampWidget.cpp:60
#: ../../Resources/StampWidget/XStampWidget.cpp:79 #: ../../Resources/StampWidget/XStampWidget.cpp:79
msgid "South-east" msgid "South-east"
msgstr "Sud-est" msgstr "Sud-est"
#: ../../Resources/InsaneWidget/XStampWidget.cpp:59
#: ../../Resources/InsaneWidget/XStampWidget.cpp:60
#: ../../Resources/StampWidget/XStampWidget.cpp:79 #: ../../Resources/StampWidget/XStampWidget.cpp:79
msgid "South-west" msgid "South-west"
msgstr "Sud-ouest" msgstr "Sud-ouest"
#: ../../Resources/InsaneWidget/XStampWidget.cpp:57
#: ../../Resources/InsaneWidget/XStampWidget.cpp:58
#: ../../Resources/StampWidget/XStampWidget.cpp:77 #: ../../Resources/StampWidget/XStampWidget.cpp:77
msgid "East" msgid "East"
msgstr "Est" msgstr "Est"
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:137
#: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:141 #: ../../Resources/InsaneWidget/UI/InsaneWidget.cpp:141
msgid "" msgid ""
"'Left click' to start the scan project.\n" "'Left click' to start the scan project.\n"
@@ -523,12 +383,10 @@ msgstr ""
"'Clic droit' pour afficher les options du numériseur.\n" "'Clic droit' pour afficher les options du numériseur.\n"
"'Ctrl + Clic droit' pour définir un tampon." "'Ctrl + Clic droit' pour définir un tampon."
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:376 #: ../../Resources/InsaneWidget/XInsaneWidget.cpp:423
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:377
msgid "Stamps" msgid "Stamps"
msgstr "Tampons" msgstr "Tampons"
#: ../../Resources/InsaneWidget/UI/StampWidgets.h:44
#: ../../Resources/StampWidget/UI/StampWidgets.h:44 #: ../../Resources/StampWidget/UI/StampWidgets.h:44
msgid "StampWidgets" msgid "StampWidgets"
msgstr "" msgstr ""
@@ -565,3 +423,7 @@ msgstr "Transparent"
msgid "" msgid ""
"Check for a completely transparent background and for a transparent text." "Check for a completely transparent background and for a transparent text."
msgstr "Activez la transparence du texte et de l'arrière-plan. " msgstr "Activez la transparence du texte et de l'arrière-plan. "
#: ../../Resources/InsaneWidget/XInsaneWidget.cpp:511
msgid "Cancel"
msgstr "Annuler"

View File

@@ -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 );

View File

@@ -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

View File

@@ -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 );

View File

@@ -126,7 +126,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;