Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 40 additions & 14 deletions src/device/scannerdevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
// 2 print normal messages
// 3 print debugging messages
// 4 print everything
QString logLevel = "1";
QString logLevel = "2";
#ifdef QT_DEBUG
logLevel = "2";
#endif
Expand All @@ -97,10 +97,11 @@
ScannerDevice::~ScannerDevice()
{
#ifndef _WIN32
qCInfo(app) << "🔥 ScannerDevice destructor called - this should NOT happen during device list refresh!";
closeDevice(); // Ensure device is closed if open

Check warning on line 101 in src/device/scannerdevice.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Virtual function 'closeDevice' is called from destructor '~ScannerDevice()' at line 101. Dynamic binding is not used.
if (m_saneInitialized) {
sane_exit();
qCDebug(app) << "SANE backend exited successfully";
qCInfo(app) << "SANE backend exited from destructor";
}
#endif
}
Expand Down Expand Up @@ -140,17 +141,28 @@
return deviceNames;
}


// Try calling sane_get_devices with different parameters
qCDebug(app) << "Attempting to get device list (include network devices)";
const SANE_Device **device_list = nullptr;
SANE_Status status = sane_get_devices(&device_list, SANE_TRUE);

// First attempt: Get ALL devices including network devices (ESCL/AirScan)
qCDebug(app) << "First attempt: Getting ALL devices (including network devices)";
SANE_Status status = sane_get_devices(&device_list, SANE_FALSE);
qCDebug(app) << "Device list status:" << sane_strstatus(status);

if (status != SANE_STATUS_GOOD || !device_list) {
qCDebug(app) << "Retrying device list (local devices only)";
// If first attempt fails or returns no devices, wait and retry
// This is especially important for network devices (ESCL/AirScan) which need discovery time
if (status != SANE_STATUS_GOOD || !device_list || (device_list && !device_list[0])) {

Check warning on line 153 in src/device/scannerdevice.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Condition 'device_list' is always true
qCInfo(app) << "First attempt returned no devices, waiting for network discovery...";
QThread::msleep(2000); // Wait 2 seconds for network device discovery

qCDebug(app) << "Retrying: Getting ALL devices (including network devices)";
status = sane_get_devices(&device_list, SANE_FALSE);
qCDebug(app) << "Device list retry status:" << sane_strstatus(status);

if (status != SANE_STATUS_GOOD || !device_list || (device_list && !device_list[0])) {

Check warning on line 161 in src/device/scannerdevice.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Condition 'device_list' is always true
qCDebug(app) << "Still no devices, trying local devices only";
status = sane_get_devices(&device_list, SANE_TRUE);
qCDebug(app) << "Local devices only status:" << sane_strstatus(status);
}
}

if (status != SANE_STATUS_GOOD) {
Expand Down Expand Up @@ -193,14 +205,22 @@
}

qCDebug(app) << "Enumerating available scanner devices";
int deviceCount = 0;

// First count devices
for (int i = 0; device_list[i] != nullptr; ++i) {
deviceCount++;
}
qCInfo(app) << "Found" << deviceCount << "SANE devices total";

for (int i = 0; device_list[i] != nullptr; ++i) {
const SANE_Device *dev = device_list[i];
if (dev) {
qCDebug(app) << "Device found:";
qCDebug(app) << " Name:" << (dev->name ? dev->name : "null");
qCDebug(app) << " Vendor:" << (dev->vendor ? dev->vendor : "null");
qCDebug(app) << " Model:" << (dev->model ? dev->model : "null");
qCDebug(app) << " Type:" << (dev->type ? dev->type : "null");
qCInfo(app) << "Device" << (i+1) << "/" << deviceCount << ":";
qCInfo(app) << " Name:" << (dev->name ? dev->name : "null");
qCInfo(app) << " Vendor:" << (dev->vendor ? dev->vendor : "null");
qCInfo(app) << " Model:" << (dev->model ? dev->model : "null");
qCInfo(app) << " Type:" << (dev->type ? dev->type : "null");

if (dev->name) {
deviceNames.append(QString::fromUtf8(dev->name));
Expand All @@ -211,10 +231,16 @@
.arg(dev->model ? QString::fromUtf8(dev->model) : "Unknown")
.arg(dev->type ? QString::fromUtf8(dev->type) : "Unknown");

qCDebug(app) << "Added device:" << dev->name << "-" << deviceInfo;
qCInfo(app) << "✅ Successfully added device:" << dev->name << "-" << deviceInfo;
} else {
qCWarning(app) << "❌ Device has null name, skipping";
}
} else {
qCWarning(app) << "❌ Device at index" << i << "is null";
}
}

qCInfo(app) << "Final device list contains" << deviceNames.size() << "devices:" << deviceNames;

#if ADD_TEST_DEVICE
// If no devices found, add a virtual test device
Expand Down
31 changes: 24 additions & 7 deletions src/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ MainWindow::MainWindow(QWidget *parent)
: DMainWindow(parent)
{
// --- Initialize Devices ---
QSharedPointer<ScannerDevice> scannerDevice(new ScannerDevice(this));
// Note: Don't pass 'this' as parent when using QSharedPointer to avoid double-deletion
QSharedPointer<ScannerDevice> scannerDevice(new ScannerDevice(nullptr));
scannerDevice->initialize();
QSharedPointer<WebcamDevice> webcamDevice(new WebcamDevice(this));
QSharedPointer<WebcamDevice> webcamDevice(new WebcamDevice(nullptr));
webcamDevice->initialize();

// Store devices in map
Expand Down Expand Up @@ -106,14 +107,30 @@ void MainWindow::updateDeviceList()
auto webcam = qSharedPointerCast<WebcamDevice>(m_devices["webcam"]);

if (scanner && webcam) {
// 更新ScannersWidget中的设备列表
m_scannersWidget->updateDeviceList(scanner, webcam);
// 给网络设备发现预留更多时间(特别是首次启动)
static bool firstRun = true;
int delay = firstRun ? 3000 : 500; // 首次启动等待3秒,后续等待0.5秒

if (firstRun) {
qCInfo(app) << "First device list update, allowing extra time for network device discovery...";
firstRun = false;
}

// 使用定时器延迟更新设备列表
QTimer::singleShot(delay, this, [this]() {
// 重新获取设备指针,避免捕获过期指针
auto scanner = qSharedPointerCast<ScannerDevice>(m_devices["scanner"]);
auto webcam = qSharedPointerCast<WebcamDevice>(m_devices["webcam"]);

if (scanner && webcam) {
m_scannersWidget->updateDeviceList(scanner, webcam);
}
QTimer::singleShot(500, this, &MainWindow::hideLoading);
});
} else {
qDebug(app) << "Error: Failed to cast device pointers";
QTimer::singleShot(500, this, &MainWindow::hideLoading);
}


QTimer::singleShot(500, this, &MainWindow::hideLoading);
}

void MainWindow::showScanView(const QString &device, bool isScanner)
Expand Down