将sane设置对话框移动到HGSaneUI库中

This commit is contained in:
luoliangyi 2023-03-31 16:39:02 +08:00
parent d54aca17db
commit 1c01b7e76e
32 changed files with 8967 additions and 7 deletions

View File

@ -131,6 +131,8 @@ unix {
} }
INCLUDEPATH += $$PWD/../../../modules INCLUDEPATH += $$PWD/../../../modules
INCLUDEPATH += $$PWD/../../../utility
INCLUDEPATH += $$PWD/../../../modules/saneui
INCLUDEPATH += $$PWD/../../../../sdk/include INCLUDEPATH += $$PWD/../../../../sdk/include
DESTDIR = $$PWD/../../build/$${MY_OS}/$${OEM_NAME}/$${MY_ARCH}/$${MY_CONFIGURE} DESTDIR = $$PWD/../../build/$${MY_OS}/$${OEM_NAME}/$${MY_ARCH}/$${MY_CONFIGURE}
@ -171,7 +173,7 @@ win32 {
SRCDLL_FILE = $${DESTDIR}/$${TARGET}.dll SRCDLL_FILE = $${DESTDIR}/$${TARGET}.dll
SRCDLL_FILE = $$replace(SRCDLL_FILE, /, \\) SRCDLL_FILE = $$replace(SRCDLL_FILE, /, \\)
message(SRCDLL_FILE: $$SRCDLL_FILE) message(SRCDLL_FILE: $$SRCDLL_FILE)
SRCHEADER_FILE = $${PWD}/../../../modules/saneui/*.h SRCHEADER_FILE = $${PWD}/../../../modules/saneui/HGSaneUI.h
SRCHEADER_FILE = $$replace(SRCHEADER_FILE, /, \\) SRCHEADER_FILE = $$replace(SRCHEADER_FILE, /, \\)
message(SRCHEADER_FILE: $$SRCHEADER_FILE) message(SRCHEADER_FILE: $$SRCHEADER_FILE)
SRCPDB_FILE = $${DESTDIR}/$${TARGET}.pdb SRCPDB_FILE = $${DESTDIR}/$${TARGET}.pdb
@ -202,15 +204,42 @@ unix {
SOURCES += \ SOURCES += \
../../../modules/saneui/HGSaneUI.cpp \ ../../../modules/saneui/HGSaneUI.cpp \
../../../modules/saneui/cfg/cJSON.c \
../../../modules/saneui/cfg/gb_json.cpp \
../../../modules/saneui/cutdialog.cpp \
../../../modules/saneui/cutpapertool.cpp \
../../../modules/saneui/device_menu.cpp \
../../../modules/saneui/dialog_device_scan.cpp \ ../../../modules/saneui/dialog_device_scan.cpp \
../../../modules/saneui/dialog_device_select.cpp \ ../../../modules/saneui/dialog_device_select.cpp \
../../../modules/saneui/dllmain.cpp ../../../modules/saneui/dialog_input.cpp \
../../../modules/saneui/dllmain.cpp \
../../../modules/saneui/gaosixy.cpp \
../../../modules/saneui/hg_settingdialog.cpp \
../../../modules/saneui/setpicclrtool.cpp \
../../../modules/saneui/widget.cpp \
../../../utility/HGString.cpp
HEADERS += \ HEADERS += \
../../../modules/saneui/HGSaneUI.h \ ../../../modules/saneui/HGSaneUI.h \
../../../modules/saneui/cfg/cJSON.h \
../../../modules/saneui/cfg/gb_json.h \
../../../modules/saneui/cutdialog.h \
../../../modules/saneui/cutpapertool.h \
../../../modules/saneui/device_menu.h \
../../../modules/saneui/dialog_device_scan.hpp \ ../../../modules/saneui/dialog_device_scan.hpp \
../../../modules/saneui/dialog_device_select.hpp ../../../modules/saneui/dialog_device_select.hpp \
../../../modules/saneui/dialog_input.h \
../../../modules/saneui/gaosixy.h \
../../../modules/saneui/hg_settingdialog.h \
../../../modules/saneui/setpicclrtool.h \
../../../modules/saneui/widget.h \
../../../utility/HGString.h
FORMS += \ FORMS += \
../../../modules/saneui/cutdialog.ui \
../../../modules/saneui/cutpapertool.ui \
../../../modules/saneui/dialog_device_scan.ui \ ../../../modules/saneui/dialog_device_scan.ui \
../../../modules/saneui/dialog_device_select.ui ../../../modules/saneui/dialog_device_select.ui \
../../../modules/saneui/dialog_input.ui \
../../../modules/saneui/setpicclrtool.ui \
../../../modules/saneui/widget.ui

View File

@ -17,6 +17,7 @@ HGSaneManagerImpl::HGSaneManagerImpl()
m_f_sane_get_parameters = NULL; m_f_sane_get_parameters = NULL;
m_f_sane_get_option_descriptor = NULL; m_f_sane_get_option_descriptor = NULL;
m_f_sane_control_option = NULL; m_f_sane_control_option = NULL;
m_f_sane_io_control = NULL;
memset(&m_saneApi, 0, sizeof(SANEAPI)); memset(&m_saneApi, 0, sizeof(SANEAPI));
} }
@ -243,6 +244,10 @@ HGResult HGSaneManagerImpl::FindFunctions()
if (HGBASE_ERR_OK != ret) if (HGBASE_ERR_OK != ret)
break; break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_hgsane_io_control", (HGPointer*)&m_f_sane_io_control);
if (HGBASE_ERR_OK != ret)
break;
} while (0); } while (0);
m_saneApi.sane_get_devices_api = m_f_sane_get_devices; m_saneApi.sane_get_devices_api = m_f_sane_get_devices;
@ -256,6 +261,7 @@ HGResult HGSaneManagerImpl::FindFunctions()
m_saneApi.sane_get_parameters_api = m_f_sane_get_parameters; m_saneApi.sane_get_parameters_api = m_f_sane_get_parameters;
m_saneApi.sane_get_option_descriptor_api = m_f_sane_get_option_descriptor; m_saneApi.sane_get_option_descriptor_api = m_f_sane_get_option_descriptor;
m_saneApi.sane_control_option_api = m_f_sane_control_option; m_saneApi.sane_control_option_api = m_f_sane_control_option;
m_saneApi.sane_io_control_api = m_f_sane_io_control;
return ret; return ret;
} }
@ -373,7 +379,7 @@ HGResult HGSaneDeviceImpl::ShowSettingDlg(HGWindow parent)
return HGBASE_ERR_FAIL; return HGBASE_ERR_FAIL;
} }
if (-2 == show_setting_ui(&m_mgrImpl->m_saneApi, m_devHandle, parent)) if (-2 == show_setting_ui(&m_mgrImpl->m_saneApi, m_devHandle, m_devName.c_str(), parent))
{ {
return HGBASE_ERR_NOTSUPPORT; return HGBASE_ERR_NOTSUPPORT;
} }

View File

@ -25,6 +25,8 @@ typedef SANE_String_Const (*f_sane_strstatus)(SANE_Status status);
typedef SANE_Status (*f_sane_get_parameters)(SANE_Handle handle, SANE_Parameters* params); typedef SANE_Status (*f_sane_get_parameters)(SANE_Handle handle, SANE_Parameters* params);
typedef const SANE_Option_Descriptor* (*f_sane_get_option_descriptor)(SANE_Handle handle, SANE_Int option); typedef const SANE_Option_Descriptor* (*f_sane_get_option_descriptor)(SANE_Handle handle, SANE_Int option);
typedef SANE_Status (*f_sane_control_option)(SANE_Handle handle, SANE_Int option, SANE_Action action, void* value, SANE_Int* info); typedef SANE_Status (*f_sane_control_option)(SANE_Handle handle, SANE_Int option, SANE_Action action, void* value, SANE_Int* info);
// 非标准接口
typedef SANE_Status (*f_sane_io_control)(SANE_Handle h, unsigned long code, void* data, unsigned* len);
class HGSaneManagerImpl class HGSaneManagerImpl
{ {
@ -59,6 +61,7 @@ private:
f_sane_get_parameters m_f_sane_get_parameters; f_sane_get_parameters m_f_sane_get_parameters;
f_sane_get_option_descriptor m_f_sane_get_option_descriptor; f_sane_get_option_descriptor m_f_sane_get_option_descriptor;
f_sane_control_option m_f_sane_control_option; f_sane_control_option m_f_sane_control_option;
f_sane_io_control m_f_sane_io_control;
SANEAPI m_saneApi; SANEAPI m_saneApi;
std::list<class HGSaneDeviceImpl*> m_listDeviceImpl; std::list<class HGSaneDeviceImpl*> m_listDeviceImpl;

View File

@ -1,6 +1,7 @@
#include "HGSaneUI.h" #include "HGSaneUI.h"
#include "dialog_device_select.hpp" #include "dialog_device_select.hpp"
#include "dialog_device_scan.hpp" #include "dialog_device_scan.hpp"
#include "hg_settingdialog.h"
#include "lang/app_language.h" #include "lang/app_language.h"
#include <QMessageBox> #include <QMessageBox>
#include <QTranslator> #include <QTranslator>
@ -53,7 +54,7 @@ int show_devlist_ui(SANEAPI* saneApi, HGWindow parent, SANE_Handle *handle, char
return 0; return 0;
} }
int show_setting_ui(SANEAPI* saneApi, SANE_Handle handle, HGWindow parent) int show_setting_ui(SANEAPI* saneApi, SANE_Handle handle, const char *scanner_name, HGWindow parent)
{ {
if (nullptr == saneApi || nullptr == handle) if (nullptr == saneApi || nullptr == handle)
return -1; return -1;
@ -77,6 +78,8 @@ int show_setting_ui(SANEAPI* saneApi, SANE_Handle handle, HGWindow parent)
translator.load(":translation/SaneUI_zh_CN.qm"); translator.load(":translation/SaneUI_zh_CN.qm");
QCoreApplication::installTranslator(&translator); QCoreApplication::installTranslator(&translator);
hg_settingdialog dlg(saneApi, handle, scanner_name, qParent);
dlg.exec();
return 0; return 0;
} }

View File

@ -7,7 +7,7 @@
typedef void (*show_scan_ui_image_callback)(const SANE_Parameters *imageFormat, const SANE_Byte *imageData, void * callbackParam); typedef void (*show_scan_ui_image_callback)(const SANE_Parameters *imageFormat, const SANE_Byte *imageData, void * callbackParam);
HGEXPORT int show_devlist_ui(SANEAPI* saneApi, HGWindow parent, SANE_Handle *handle, char *devName, unsigned int maxLen); HGEXPORT int show_devlist_ui(SANEAPI* saneApi, HGWindow parent, SANE_Handle *handle, char *devName, unsigned int maxLen);
HGEXPORT int show_setting_ui(SANEAPI* saneApi, SANE_Handle handle, HGWindow parent); HGEXPORT int show_setting_ui(SANEAPI* saneApi, SANE_Handle handle, const char *scanner_name, HGWindow parent);
HGEXPORT int show_scan_ui(SANEAPI* saneApi, SANE_Handle handle, HGWindow parent, show_scan_ui_image_callback callback, void *callbackParam); HGEXPORT int show_scan_ui(SANEAPI* saneApi, SANE_Handle handle, HGWindow parent, show_scan_ui_image_callback callback, void *callbackParam);
#endif #endif

756
modules/saneui/cfg/cJSON.c Normal file
View File

@ -0,0 +1,756 @@
/*
Copyright (c) 2009 Dave Gamble
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/* cJSON */
/* JSON parser in C. */
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <float.h>
#include <limits.h>
#include <ctype.h>
#include "cJSON.h"
static const char *ep;
const char *cJSON_GetErrorPtr(void) {return ep;}
static int cJSON_strcasecmp(const char *s1,const char *s2)
{
if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;
return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
}
static void* ask_memory(size_t bytes)
{
// printf("allocate %u bytes memory in cJSON\n", bytes);
return malloc(bytes);
}
static void *(*cJSON_malloc)(size_t sz) = ask_memory;
static void (*cJSON_free)(void *ptr) = free;
static char* cJSON_strdup(const char* str)
{
size_t len;
char* copy;
len = strlen(str) + 1;
if (!(copy = (char*)cJSON_malloc(len))) return 0;
memcpy(copy,str,len);
return copy;
}
void cJSON_InitHooks(cJSON_Hooks* hooks)
{
if (!hooks) { /* Reset hooks */
cJSON_malloc = ask_memory;
cJSON_free = free;
return;
}
cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:ask_memory;
cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
}
/* Internal constructor. */
static cJSON *cJSON_New_Item(void)
{
cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
if (node) memset(node,0,sizeof(cJSON));
return node;
}
/* Delete a cJSON structure. */
void cJSON_Delete(cJSON *c)
{
cJSON *next;
while (c)
{
next=c->next;
if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
if (!(c->type&cJSON_StringIsConst) && c->string) cJSON_free(c->string);
cJSON_free(c);
c=next;
}
}
/* Parse the input text to generate a number, and populate the result into item. */
static const char *parse_number(cJSON *item,const char *num)
{
double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
if (*num=='-') sign=-1,num++; /* Has sign? */
if (*num=='0') num++; /* is zero */
if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
if (*num=='e' || *num=='E') /* Exponent? */
{ num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
}
n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
item->valuedouble=n;
item->valueint=(int)n;
item->type=cJSON_Number;
return num;
}
static int pow2gt (int x) { --x; x|=x>>1; x|=x>>2; x|=x>>4; x|=x>>8; x|=x>>16; return x+1; }
typedef struct {char *buffer; int length; int offset; } printbuffer;
static char* ensure(printbuffer *p,int needed)
{
char *newbuffer;int newsize;
if (!p || !p->buffer) return 0;
needed+=p->offset;
if (needed<=p->length) return p->buffer+p->offset;
newsize=pow2gt(needed);
newbuffer=(char*)cJSON_malloc(newsize);
if (!newbuffer) {cJSON_free(p->buffer);p->length=0,p->buffer=0;return 0;}
if (newbuffer) memcpy(newbuffer,p->buffer,p->length);
cJSON_free(p->buffer);
p->length=newsize;
p->buffer=newbuffer;
return newbuffer+p->offset;
}
static int update(printbuffer *p)
{
char *str;
if (!p || !p->buffer) return 0;
str=p->buffer+p->offset;
return p->offset+strlen(str);
}
/* Render the number nicely from the given item into a string. */
static char *print_number(cJSON *item,printbuffer *p)
{
char *str=0;
double d=item->valuedouble;
if (d==0)
{
if (p) str=ensure(p,2);
else str=(char*)cJSON_malloc(2); /* special case for 0. */
if (str) strcpy(str,"0");
}
else if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
{
if (p) str=ensure(p,21);
else str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
if (str) sprintf(str,"%d",item->valueint);
}
else
{
if (p) str=ensure(p,64);
else str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */
if (str)
{
if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);
else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
else sprintf(str,"%f",d);
}
}
return str;
}
static unsigned parse_hex4(const char *str)
{
unsigned h=0;
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
h=h<<4;str++;
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
h=h<<4;str++;
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
h=h<<4;str++;
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
return h;
}
/* Parse the input text into an unescaped cstring, and populate item. */
static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
static const char *parse_string(cJSON *item,const char *str)
{
const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
if (*str!='\"') {ep=str;return 0;} /* not a string! */
while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
if (!out) return 0;
ptr=str+1;ptr2=out;
while (*ptr!='\"' && *ptr)
{
if (*ptr!='\\') *ptr2++=*ptr++;
else
{
ptr++;
switch (*ptr)
{
case 'b': *ptr2++='\b'; break;
case 'f': *ptr2++='\f'; break;
case 'n': *ptr2++='\n'; break;
case 'r': *ptr2++='\r'; break;
case 't': *ptr2++='\t'; break;
case 'u': /* transcode utf16 to utf8. */
uc=parse_hex4(ptr+1);ptr+=4; /* get the unicode char. */
if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */
if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */
{
if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */
uc2=parse_hex4(ptr+3);ptr+=6;
if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */
uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
}
len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
switch (len) {
case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
case 1: *--ptr2 =(uc | firstByteMark[len]);
}
ptr2+=len;
break;
default: *ptr2++=*ptr; break;
}
ptr++;
}
}
*ptr2=0;
if (*ptr=='\"') ptr++;
item->valuestring=out;
item->type=cJSON_String;
return ptr;
}
/* Render the cstring provided to an escaped version that can be printed. */
static char *print_string_ptr(const char *str,printbuffer *p)
{
const char *ptr;char *ptr2,*out;int len=0,flag=0;unsigned char token;
for (ptr=str;*ptr;ptr++) flag|=((*ptr>0 && *ptr<32)||(*ptr=='\"')||(*ptr=='\\'))?1:0;
if (!flag)
{
len=ptr-str;
if (p) out=ensure(p,len+3);
else out=(char*)cJSON_malloc(len+3);
if (!out) return 0;
ptr2=out;*ptr2++='\"';
strcpy(ptr2,str);
ptr2[len]='\"';
ptr2[len+1]=0;
return out;
}
if (!str)
{
if (p) out=ensure(p,3);
else out=(char*)cJSON_malloc(3);
if (!out) return 0;
strcpy(out,"\"\"");
return out;
}
ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
if (p) out=ensure(p,len+3);
else out=(char*)cJSON_malloc(len+3);
if (!out) return 0;
ptr2=out;ptr=str;
*ptr2++='\"';
while (*ptr)
{
if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
else
{
*ptr2++='\\';
switch (token=*ptr++)
{
case '\\': *ptr2++='\\'; break;
case '\"': *ptr2++='\"'; break;
case '\b': *ptr2++='b'; break;
case '\f': *ptr2++='f'; break;
case '\n': *ptr2++='n'; break;
case '\r': *ptr2++='r'; break;
case '\t': *ptr2++='t'; break;
default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */
}
}
}
*ptr2++='\"';*ptr2++=0;
return out;
}
/* Invote print_string_ptr (which is useful) on an item. */
static char *print_string(cJSON *item,printbuffer *p) {return print_string_ptr(item->valuestring,p);}
/* Predeclare these prototypes. */
static const char *parse_value(cJSON *item,const char *value);
static char *print_value(cJSON *item,int depth,int fmt,printbuffer *p);
static const char *parse_array(cJSON *item,const char *value);
static char *print_array(cJSON *item,int depth,int fmt,printbuffer *p);
static const char *parse_object(cJSON *item,const char *value);
static char *print_object(cJSON *item,int depth,int fmt,printbuffer *p);
/* Utility to jump whitespace and cr/lf */
static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
/* Parse an object - create a new root, and populate. */
cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
{
const char *end=0;
cJSON *c=cJSON_New_Item();
ep=0;
if (!c) return 0; /* memory fail */
end=parse_value(c,skip(value));
if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */
/* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}}
if (return_parse_end) *return_parse_end=end;
return c;
}
/* Default options for cJSON_Parse */
cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);}
/* Render a cJSON item/entity/structure to text. */
char *cJSON_Print(cJSON *item) {return print_value(item,0,1,0);}
char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0,0);}
char *cJSON_PrintBuffered(cJSON *item,int prebuffer,int fmt)
{
printbuffer p;
p.buffer=(char*)cJSON_malloc(prebuffer);
p.length=prebuffer;
p.offset=0;
return print_value(item,0,fmt,&p);
return p.buffer;
}
/* Parser core - when encountering text, process appropriately. */
static const char *parse_value(cJSON *item,const char *value)
{
if (!value) return 0; /* Fail on null. */
if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
if (*value=='\"') { return parse_string(item,value); }
if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
if (*value=='[') { return parse_array(item,value); }
if (*value=='{') { return parse_object(item,value); }
ep=value;return 0; /* failure. */
}
/* Render a value to text. */
static char *print_value(cJSON *item,int depth,int fmt,printbuffer *p)
{
char *out=0;
if (!item) return 0;
if (p)
{
switch ((item->type)&255)
{
case cJSON_NULL: {out=ensure(p,5); if (out) strcpy(out,"null"); break;}
case cJSON_False: {out=ensure(p,6); if (out) strcpy(out,"false"); break;}
case cJSON_True: {out=ensure(p,5); if (out) strcpy(out,"true"); break;}
case cJSON_Number: out=print_number(item,p);break;
case cJSON_String: out=print_string(item,p);break;
case cJSON_Array: out=print_array(item,depth,fmt,p);break;
case cJSON_Object: out=print_object(item,depth,fmt,p);break;
}
}
else
{
switch ((item->type)&255)
{
case cJSON_NULL: out=cJSON_strdup("null"); break;
case cJSON_False: out=cJSON_strdup("false");break;
case cJSON_True: out=cJSON_strdup("true"); break;
case cJSON_Number: out=print_number(item,0);break;
case cJSON_String: out=print_string(item,0);break;
case cJSON_Array: out=print_array(item,depth,fmt,0);break;
case cJSON_Object: out=print_object(item,depth,fmt,0);break;
}
}
return out;
}
/* Build an array from input text. */
static const char *parse_array(cJSON *item,const char *value)
{
cJSON *child;
if (*value!='[') {ep=value;return 0;} /* not an array! */
item->type=cJSON_Array;
value=skip(value+1);
if (*value==']') return value+1; /* empty array. */
item->child=child=cJSON_New_Item();
if (!item->child) return 0; /* memory fail */
value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
if (!value) return 0;
while (*value==',')
{
cJSON *new_item;
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
child->next=new_item;new_item->prev=child;child=new_item;
value=skip(parse_value(child,skip(value+1)));
if (!value) return 0; /* memory fail */
}
if (*value==']') return value+1; /* end of array */
ep=value;return 0; /* malformed. */
}
/* Render an array to text */
static char *print_array(cJSON *item,int depth,int fmt,printbuffer *p)
{
char **entries;
char *out=0,*ptr,*ret;int len=5;
cJSON *child=item->child;
int numentries=0,i=0,fail=0;
size_t tmplen=0;
/* How many entries in the array? */
while (child) numentries++,child=child->next;
/* Explicitly handle numentries==0 */
if (!numentries)
{
if (p) out=ensure(p,3);
else out=(char*)cJSON_malloc(3);
if (out) strcpy(out,"[]");
return out;
}
if (p)
{
/* Compose the output array. */
i=p->offset;
ptr=ensure(p,1);if (!ptr) return 0; *ptr='['; p->offset++;
child=item->child;
while (child && !fail)
{
print_value(child,depth+1,fmt,p);
p->offset=update(p);
if (child->next) {len=fmt?2:1;ptr=ensure(p,len+1);if (!ptr) return 0;*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;p->offset+=len;}
child=child->next;
}
ptr=ensure(p,2);if (!ptr) return 0; *ptr++=']';*ptr=0;
out=(p->buffer)+i;
}
else
{
/* Allocate an array to hold the values for each */
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
if (!entries) return 0;
memset(entries,0,numentries*sizeof(char*));
/* Retrieve all the results: */
child=item->child;
while (child && !fail)
{
ret=print_value(child,depth+1,fmt,0);
entries[i++]=ret;
if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
child=child->next;
}
/* If we didn't fail, try to ask_memory the output string */
if (!fail) out=(char*)cJSON_malloc(len);
/* If that fails, we fail. */
if (!out) fail=1;
/* Handle failure. */
if (fail)
{
for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
cJSON_free(entries);
return 0;
}
/* Compose the output array. */
*out='[';
ptr=out+1;*ptr=0;
for (i=0;i<numentries;i++)
{
tmplen=strlen(entries[i]);memcpy(ptr,entries[i],tmplen);ptr+=tmplen;
if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
cJSON_free(entries[i]);
}
cJSON_free(entries);
*ptr++=']';*ptr++=0;
}
return out;
}
/* Build an object from the text. */
static const char *parse_object(cJSON *item,const char *value)
{
cJSON *child;
if (*value!='{') {ep=value;return 0;} /* not an object! */
item->type=cJSON_Object;
value=skip(value+1);
if (*value=='}') return value+1; /* empty array. */
item->child=child=cJSON_New_Item();
if (!item->child) return 0;
value=skip(parse_string(child,skip(value)));
if (!value) return 0;
child->string=child->valuestring;child->valuestring=0;
if (*value!=':') {ep=value;return 0;} /* fail! */
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
if (!value) return 0;
while (*value==',')
{
cJSON *new_item;
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
child->next=new_item;new_item->prev=child;child=new_item;
value=skip(parse_string(child,skip(value+1)));
if (!value) return 0;
child->string=child->valuestring;child->valuestring=0;
if (*value!=':') {ep=value;return 0;} /* fail! */
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
if (!value) return 0;
}
if (*value=='}') return value+1; /* end of array */
ep=value;return 0; /* malformed. */
}
/* Render an object to text. */
static char *print_object(cJSON *item,int depth,int fmt,printbuffer *p)
{
char **entries=0,**names=0;
char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
cJSON *child=item->child;
int numentries=0,fail=0;
size_t tmplen=0;
/* Count the number of entries. */
while (child) numentries++,child=child->next;
/* Explicitly handle empty object case */
if (!numentries)
{
if (p) out=ensure(p,fmt?depth+4:3);
else out=(char*)cJSON_malloc(fmt?depth+4:3);
if (!out) return 0;
ptr=out;*ptr++='{';
if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';}
*ptr++='}';*ptr++=0;
return out;
}
if (p)
{
/* Compose the output: */
i=p->offset;
len=fmt?2:1; ptr=ensure(p,len+1); if (!ptr) return 0;
*ptr++='{'; if (fmt) *ptr++='\n'; *ptr=0; p->offset+=len;
child=item->child;depth++;
while (child)
{
if (fmt)
{
ptr=ensure(p,depth); if (!ptr) return 0;
for (j=0;j<depth;j++) *ptr++='\t';
p->offset+=depth;
}
print_string_ptr(child->string,p);
p->offset=update(p);
len=fmt?2:1;
ptr=ensure(p,len); if (!ptr) return 0;
*ptr++=':';if (fmt) *ptr++='\t';
p->offset+=len;
print_value(child,depth,fmt,p);
p->offset=update(p);
len=(fmt?1:0)+(child->next?1:0);
ptr=ensure(p,len+1); if (!ptr) return 0;
if (child->next) *ptr++=',';
if (fmt) *ptr++='\n';*ptr=0;
p->offset+=len;
child=child->next;
}
ptr=ensure(p,fmt?(depth+1):2); if (!ptr) return 0;
if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
*ptr++='}';*ptr=0;
out=(p->buffer)+i;
}
else
{
/* Allocate space for the names and the objects */
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
if (!entries) return 0;
names=(char**)cJSON_malloc(numentries*sizeof(char*));
if (!names) {cJSON_free(entries);return 0;}
memset(entries,0,sizeof(char*)*numentries);
memset(names,0,sizeof(char*)*numentries);
/* Collect all the results into our arrays: */
child=item->child;depth++;if (fmt) len+=depth;
while (child)
{
names[i]=str=print_string_ptr(child->string,0);
entries[i++]=ret=print_value(child,depth,fmt,0);
if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
child=child->next;
}
/* Try to allocate the output string */
if (!fail) out=(char*)cJSON_malloc(len);
if (!out) fail=1;
/* Handle failure */
if (fail)
{
for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
cJSON_free(names);cJSON_free(entries);
return 0;
}
/* Compose the output: */
*out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
for (i=0;i<numentries;i++)
{
if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
tmplen=strlen(names[i]);memcpy(ptr,names[i],tmplen);ptr+=tmplen;
*ptr++=':';if (fmt) *ptr++='\t';
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
if (i!=numentries-1) *ptr++=',';
if (fmt) *ptr++='\n';*ptr=0;
cJSON_free(names[i]);cJSON_free(entries[i]);
}
cJSON_free(names);cJSON_free(entries);
if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
*ptr++='}';*ptr++=0;
}
return out;
}
/* Get Array size/item / object item. */
int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;}
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
/* Utility for array list handling. */
static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
/* Utility for handling references. */
static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
/* Add item to array/object. */
void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
void cJSON_AddItemToObjectCS(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (!(item->type&cJSON_StringIsConst) && item->string) cJSON_free(item->string);item->string=(char*)string;item->type|=cJSON_StringIsConst;cJSON_AddItemToArray(object,item);}
void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));}
void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));}
cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
/* Replace array/object items with new ones. */
void cJSON_InsertItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) {cJSON_AddItemToArray(array,newitem);return;}
newitem->next=c;newitem->prev=c->prev;c->prev=newitem;if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;}
void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
/* Create basic types: */
cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
/* Create Arrays: */
cJSON *cJSON_CreateIntArray(const int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateFloatArray(const float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateDoubleArray(const double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
/* Duplication */
cJSON *cJSON_Duplicate(cJSON *item,int recurse)
{
cJSON *newitem,*cptr,*nptr=0,*newchild;
/* Bail on bad ptr */
if (!item) return 0;
/* Create new item */
newitem=cJSON_New_Item();
if (!newitem) return 0;
/* Copy over all vars */
newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;
if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}}
if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}}
/* If non-recursive, then we're done! */
if (!recurse) return newitem;
/* Walk the ->next chain for the child. */
cptr=item->child;
while (cptr)
{
newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */
if (!newchild) {cJSON_Delete(newitem);return 0;}
if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */
else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */
cptr=cptr->next;
}
return newitem;
}
void cJSON_Minify(char *json)
{
char *into=json;
while (*json)
{
if (*json==' ') json++;
else if (*json=='\t') json++; /* Whitespace characters. */
else if (*json=='\r') json++;
else if (*json=='\n') json++;
else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; /* double-slash comments, to end of line. */
else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} /* multiline comments. */
else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} /* string literals, which are \" sensitive. */
else *into++=*json++; /* All other characters. */
}
*into=0; /* and null-terminate. */
}

154
modules/saneui/cfg/cJSON.h Normal file
View File

@ -0,0 +1,154 @@
/*
Copyright (c) 2009 Dave Gamble
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef cJSON__h
#define cJSON__h
#include <stdlib.h>
#ifdef __cplusplus
extern "C"
{
#endif
/* cJSON Types: */
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3
#define cJSON_String 4
#define cJSON_Array 5
#define cJSON_Object 6
#define cJSON_IsReference 256
#define cJSON_StringIsConst 512
typedef void *(*malloc_fnxx)(size_t sz);
typedef void (*free_fnxx)(void *ptr);
/* The cJSON structure: */
typedef struct cJSON {
struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
int type; /* The type of the item, as above. */
char *valuestring; /* The item's string, if type==cJSON_String */
int valueint; /* The item's number, if type==cJSON_Number */
double valuedouble; /* The item's number, if type==cJSON_Number */
char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON;
typedef struct cJSON_Hooks {
malloc_fnxx malloc_fn;
free_fnxx free_fn;
} cJSON_Hooks;
/* Supply malloc, realloc and free functions to cJSON */
extern void cJSON_InitHooks(cJSON_Hooks* hooks);
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
extern cJSON *cJSON_Parse(const char *value);
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
extern char *cJSON_Print(cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
extern char *cJSON_PrintUnformatted(cJSON *item);
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
extern char *cJSON_PrintBuffered(cJSON *item,int prebuffer,int fmt);
/* Delete a cJSON entity and all subentities. */
extern void cJSON_Delete(cJSON *c);
/* Returns the number of items in an array (or object). */
extern int cJSON_GetArraySize(cJSON *array);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
/* Get item "string" from object. Case insensitive. */
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
extern const char *cJSON_GetErrorPtr(void);
/* These calls create a cJSON item of the appropriate type. */
extern cJSON *cJSON_CreateNull(void);
extern cJSON *cJSON_CreateTrue(void);
extern cJSON *cJSON_CreateFalse(void);
extern cJSON *cJSON_CreateBool(int b);
extern cJSON *cJSON_CreateNumber(double num);
extern cJSON *cJSON_CreateString(const char *string);
extern cJSON *cJSON_CreateArray(void);
extern cJSON *cJSON_CreateObject(void);
/* These utilities create an Array of count items. */
extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
/* Append item to the specified array/object. */
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
extern void cJSON_AddItemToObjectCS(cJSON *object,const char *string,cJSON *item); /* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object */
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
/* Remove/Detatch items from Arrays/Objects. */
extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
/* Update array items. */
extern void cJSON_InsertItemInArray(cJSON *array,int which,cJSON *newitem); /* Shifts pre-existing items to the right. */
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
/* Duplicate a cJSON item */
extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
need to be released. With recurse!=0, it will duplicate any children connected to the item.
The item->next and ->prev pointers are always zero on return from Duplicate. */
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);
extern void cJSON_Minify(char *json);
/* Macros for creating things quickly. */
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))
#define cJSON_SetNumberValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,233 @@
#pragma once
#if defined(WIN32) || defined(_WIN64)
#include <Windows.h>
#define PATH_SYMBOL "\\"
#else
#define PATH_SYMBOL "/"
#define NULL nullptr
#define DWORD_PTR char*
#define _countof(a) sizeof(a) / sizeof(a[0])
#endif
#include "cJSON.h"
//#include "../../code_device/hgsane/cJSON.h"
#include <vector>
#include <string>
#include <map>
#include <algorithm>
namespace gb
{
class scanner_cfg;
class refer
{
volatile long ref_;
protected:
refer();
virtual ~refer();
public:
long add_ref(void);
long release(void);
};
class json : public refer
{
cJSON *obj_;
cJSON *cur_child_;
cJSON walk_head_;
bool is_array_;
cJSON* find_sibling(cJSON* first, const char* name, cJSON*** addr);
cJSON* find_child(cJSON *parent, std::vector<std::string>& path, bool create, cJSON*** addr = NULL);
cJSON* find(const char* path, bool create = false, cJSON*** addr = NULL);
protected:
~json();
public:
json(char* json_txt = 0);
static std::string to_string(cJSON* root, bool formatted);
static std::string get_value_as_string(cJSON* root, bool integer = false);
static void free_node_data(cJSON* node);
static cJSON* create_element(bool is_array = false);
static cJSON* create_element_with_name(const char* name);
public:
bool attach_text(char* json_txt);
bool attach_cjson(cJSON* cjson);
bool create_empty(bool array = false);
void clear(void);
std::string to_string(bool formatted);
// can be path: child/value ...
bool get_value(const char* key, bool& val);
bool get_value(const char* key, int& val);
bool get_value(const char* key, double& val);
bool get_value(const char* key, std::string& val);
bool get_value(const char* key, json*& val); // caller shoud call "delete" to free the returned object !!!
bool get_value_as_string(const char* key, std::string& val, bool integer);
bool get_as_array(const char* key, std::vector<std::string>& val);
int count(void);
bool first_child(std::string& val, std::string* name = NULL);
bool next_child(std::string& val, std::string* name = NULL);
bool set_value(const char* key, bool val);
bool set_value(const char* key, int val);
bool set_value(const char* key, double val);
bool set_value(const char* key, std::string val);
bool set_value(const char* key, const char* val);
bool set_value(const char* key, json* obj);
bool change_key(const char* old_key, const char* new_key);
bool remove(const char* key);
};
class base64
{
char base64_ind_[128];
char base64_char_[80];
char padding_char_;
bool is_valid_base64_table(const char* table);
bool initialize_base64_table(const char* table);
public:
base64();
~base64();
public:
bool set_base64_table(const char* table = NULL);
std::string encode(const char* data, size_t bytes, unsigned int line_bytes = -1, bool need_padding = true);
std::string decode(const char* data, size_t bytes);
};
class sane_config_schm : public refer
{
std::string scheme_name_;
scanner_cfg *scanner_;
std::string file_;
json* jsn_;
json* bkp_;
json* def_val_;
bool in_setting_;
std::map<int, std::string> id_name_; // (id, default-val)
void clear();
std::string default_value(const char* name);
protected:
~sane_config_schm();
public:
sane_config_schm(scanner_cfg* scanner = nullptr);
static std::string opt_data_appendix_;
static bool hex(unsigned char ch, unsigned char* val);
static bool hex_char(const char* data, unsigned char* val);
static std::string to_hex_letter(const char* data, size_t bytes);
static std::string from_hex_letter(const char* data, size_t bytes);
static bool is_option_data(std::string& name); // reset baase option name into 'name' if name was option data, and return true
public:
sane_config_schm* copy(void);
bool load_from_file(const char* file);
bool load_from_mem(const char* mem, bool in_b64 = true);
bool save_to(const char* file);
void set_default_value(int sn, const char* name, const char* val, size_t bytes);
void copy_default_value(sane_config_schm* from);
bool first_config(std::string& name, std::string& val);
bool next_config(std::string& name, std::string& val);
bool get_config(const char* name, std::string& val);
void begin_setting(bool restore = false);
void config_changed(const char* name, const char* val, size_t bytes, bool extra = false);
void config_changed(int sn, const char* val, size_t bytes, bool extra = false);
void remove_config(const char* name);
void set_value(const char* name, const char* val, size_t bytes, bool extra = false);
bool has_changed(int* items = nullptr);
void end_setting(bool cancel);
int id_from_name(const char* name);
std::string to_text_stream(bool b64 = true, bool with_ver = true);
std::string get_version(void);
std::string get_scheme_name(void);
void set_scheme_name(const char* name);
void update(bool(* is_float)(int, void*), void* param, const char*(* t2n)(const char*), std::string* discard = NULL);
};
class scanner_cfg : public refer
{
// format: in base64
//
// {
// "global": {
// "ver": "4.33",
// "cur": -1
// },
// "scheme_1": sane_config_schm*,
// "scheme_2": sane_config_schm*,
// "scheme_3": sane_config_schm*,
// ...
// }
//
std::string path_;
std::string scanner_name_; // scanner type: HUAGOSCAN G100 - 0100
json *global_; // version, current scheme, ...
typedef struct _cfg_schm
{
std::string name;
sane_config_schm* schm;
bool operator==(const char* n)
{
return name == n;
}
}CFGSCHM;
std::vector<CFGSCHM> schemes_;
static std::string global_name_;
static std::string cur_sel_;
static std::string default_setting_name_;
void clear(void);
void init_version(void);
void init_select(void);
void walk_sibling_schemes(cJSON* first);
protected:
~scanner_cfg();
public:
scanner_cfg();
typedef struct _update_func
{
void(* trans_number)(const char* name, std::string& val, void* param);
const char* (* title2name)(const char* title, void* param);
std::string discard_msg; // update failed items ...
void* func_param;
}UDF, *LPUDF;
static bool update(const char* file, LPUDF func);
public:
int load_file(const char* file);
int load_mem(const char* mem);
int save(const char* file = nullptr);
void get_all_schemes(std::vector<std::string>& schemes); // return all schemes name queue, the first is always be 'Default settings'
sane_config_schm* get_scheme(const char* scheme_name = nullptr/*return current scheme if was null*/); // call sane_config_schm::release() if not use anymore
std::string get_current_scheme_name(void);
bool remove_scheme(const char* scheme_name);
void remove_all_schemes(void);
bool select_scheme(const char* scheme_name);
sane_config_schm* copy_scheme(const char* cp_from_name); // for UI setting, call release() if not use anymore
bool add_scheme(sane_config_schm* schm, const char* name = nullptr);
bool rename_scheme(const char* from, const char* to);
};
};

View File

@ -0,0 +1,464 @@
#include "cutdialog.h"
#include "ui_cutdialog.h"
#include <QDebug>
#include <QToolTip>
#include <qpainterpath.h>
#include "HGString.h"
#include "sane/sane_option_definitions.h"
cutDialog::cutDialog(QWidget *parent) :
QWidget(parent),
ui(new Ui::cutDialog)
{
ui->setupUi(this);
divisor = 8;
dpi = 1;
sizeType = 0;
paperWidth = 185;
h_w = 260.0/185.0;
sizeRate = 1;
paperHeight = paperWidth*h_w;
this->setFixedSize(paperWidth,paperHeight);
setMouseTracking(true);
m_startPoint = QPoint(10,10);
m_endPoint = QPoint(50,50);
m_mouse_down = false;
initAllCorner();
}
cutDialog::~cutDialog()
{
delete ui;
}
void cutDialog::setPaperSize(QString type, const int w)
{
paperType = type;
if (paperType == OPTION_VALUE_ZZCC_A3) h_w = 420.0 / 297.0;
else if (paperType == OPTION_VALUE_ZZCC_8K) h_w = 390.0 / 270.0;
else if (paperType == OPTION_VALUE_ZZCC_16K) h_w = 270.0 / 190.0;
else if (paperType == OPTION_VALUE_ZZCC_16KHX) h_w = 190.0 / 270.0;
else if (paperType == OPTION_VALUE_ZZCC_A4) h_w = 297.0 / 210.0;
else if (paperType == OPTION_VALUE_ZZCC_A4HX) h_w = 210.0 / 297.0;
else if (paperType == OPTION_VALUE_ZZCC_A5) h_w = 210.0 / 148.0;
else if (paperType == OPTION_VALUE_ZZCC_A5HX) h_w = 148.0 / 210.0;
else if (paperType == OPTION_VALUE_ZZCC_A6) h_w = 148.0 / 105.0;
else if (paperType == OPTION_VALUE_ZZCC_A6HX) h_w = 105.0 / 148.0;
else if (paperType == OPTION_VALUE_ZZCC_B4) h_w = 353.0 / 250.0;
else if (paperType == OPTION_VALUE_ZZCC_B5) h_w = 250.0 / 176.0;
else if (paperType == OPTION_VALUE_ZZCC_B5HX) h_w = 176.0 / 250.0;
else if (paperType == OPTION_VALUE_ZZCC_B6) h_w = 176.0 / 125.0;
else if (paperType == OPTION_VALUE_ZZCC_B6HX) h_w = 125.0 / 176.0;
else if (paperType == OPTION_VALUE_ZZCC_Letter) h_w = 279.0 / 216.0;
else if (paperType == OPTION_VALUE_ZZCC_LetterHX) h_w = 216.0 / 279.0;
else if (paperType == OPTION_VALUE_ZZCC_DoubleLetter) h_w = 559.0 / 216.0;
else if (paperType == OPTION_VALUE_ZZCC_LEGAL) h_w = 356.0 / 216.0;
else if (paperType == OPTION_VALUE_ZZCC_SLSJ) h_w = 560.0 / 270.0;
else if(paperType == OPTION_VALUE_ZZCC_ZDSMCC) h_w = 3307.0*2/2338;
else if(paperType == OPTION_VALUE_ZZCC_PPYSCC) {
if(dpi == 100.0) h_w = 1795.0/1189;
if(dpi == 150.0) h_w = 1795.0/1784;
if(dpi == 200.0) h_w = 3307.0/2338;
if(dpi == 240.0) h_w = 4308.0/2854;
if(dpi == 200.0) h_w = 5385.0/3567;
};
if(type.contains("3")) divisor = 2;
else if (type.contains("4")) divisor = 4;
else if (type.contains("5")) divisor = 6;
else if (type.contains("6")) divisor = 8;
else divisor = 4;
paperWidth = w;
if(type.contains(StdStringToUtf8("横向").c_str()))
paperWidth = paperWidth*h_w*1.5;
double realW = paperWidth;
if (paperType == OPTION_VALUE_ZZCC_A3 || paperType == OPTION_VALUE_ZZCC_A4HX) realRate = 297.0 / realW;
else if (paperType == OPTION_VALUE_ZZCC_A4 || paperType == OPTION_VALUE_ZZCC_A5HX) realRate = 210.0 / realW;
else if (paperType == OPTION_VALUE_ZZCC_A5 || paperType == OPTION_VALUE_ZZCC_A6HX) realRate = 148.0 / realW;
else if (paperType == OPTION_VALUE_ZZCC_A6) realRate = 105.0 / realW;
else if (paperType == OPTION_VALUE_ZZCC_16K) realRate = 190.0 / realW;
else if (paperType == OPTION_VALUE_ZZCC_8K || paperType == OPTION_VALUE_ZZCC_16KHX) realRate = 270.0 / realW;
else if (paperType == OPTION_VALUE_ZZCC_B4 || paperType == OPTION_VALUE_ZZCC_B5HX) realRate = 250.0 / realW;
else if (paperType == OPTION_VALUE_ZZCC_B5 || paperType == OPTION_VALUE_ZZCC_B6HX) realRate = 176.0 / realW;
else if (paperType == OPTION_VALUE_ZZCC_B6) realRate = 125.0 / realW;
else if (paperType == OPTION_VALUE_ZZCC_Letter) realRate = 216.0 / realW;
else if (paperType == OPTION_VALUE_ZZCC_LetterHX) realRate = 279.0 / realW;
else if (paperType == OPTION_VALUE_ZZCC_DoubleLetter) realRate = 216.0 / realW;
else if (paperType == OPTION_VALUE_ZZCC_LEGAL) realRate = 216.0 / realW;
else if (paperType == OPTION_VALUE_ZZCC_SLSJ) realRate = 270.0 / realW;
else if(paperType == OPTION_VALUE_ZZCC_ZDSMCC) realRate = 297.0/realW;
else if(paperType == OPTION_VALUE_ZZCC_PPYSCC) {
if(dpi == 100.0) realRate = 1189.0*0.039377/dpi/realW;
if(dpi == 150.0) realRate = 1784*0.039377/dpi/realW;
if(dpi == 200.0) realRate = 2338*0.039377/dpi/realW;
if(dpi == 240.0) realRate = 2854*0.039377/dpi/realW;
if(dpi == 200.0) realRate = 3567*0.039377/dpi/realW;
};
paperHeight = paperWidth*h_w;
this->setFixedSize(paperWidth+4,paperHeight+4);
scaleRec = QRectF(0,0,paperWidth,paperHeight+0.5);
m_rect = QRectF(m_startPoint,m_endPoint);
update();
refreshView();
}
void cutDialog::setDpiValue(const double d)
{
dpi = d;
if(sizeType == PIXEL) sizeRate = 0.03937*dpi;
update();
}
void cutDialog::setSizeType(const SIZETYPE &t)
{
sizeType = t;
switch (sizeType) {
case MILLIM:
sizeRate = 1;
break;
case INCH:
sizeRate = 0.03937;
break;
case PIXEL:
sizeRate = 0.03937*dpi;
break;
}
update();
}
void cutDialog::setCutRectWidth(double w)
{
m_endPoint.setX(m_startPoint.x()+scaleRec.width()*w/getPaperSize().width());
update();
}
void cutDialog::setCutRectHeight(double h)
{
m_endPoint.setY(m_startPoint.y()+scaleRec.height()*h/getPaperSize().height());
update();
}
void cutDialog::setCutRectStartX(double x)
{
m_startPoint.setX(scaleRec.width()*x/getPaperSize().width());
update();
}
void cutDialog::setCutRectStartY(double y)
{
m_startPoint.setY(scaleRec.height()*y/getPaperSize().height());
update();
}
QSizeF cutDialog::getPaperSize() const
{
double realW = paperWidth*realRate*sizeRate;
double realH = paperHeight*realRate*sizeRate;
return QSizeF(realW,realH);
}
QSizeF cutDialog::getCutRectSize() const
{
double realCutW = getPaperSize().width()*m_rect.width()/scaleRec.width();
double realCutH = getPaperSize().height()*m_rect.height()/scaleRec.height();
return QSizeF(realCutW,realCutH);
}
QPointF cutDialog::getCutRectStartPos() const
{
double realCutX = getPaperSize().width()*m_startPoint.x()/scaleRec.width();
double realCutY = getPaperSize().height()*m_startPoint.y()/scaleRec.height();
return QPointF(realCutX,realCutY);
}
QRectF cutDialog::getCutRectPixel() const
{
double x = 0.03937*dpi*paperWidth*realRate*m_startPoint.x()/scaleRec.width();
double y = 0.03937*dpi*paperHeight*realRate*m_startPoint.y()/scaleRec.height();
double w = 0.03937*dpi*paperWidth*realRate*m_rect.width()/scaleRec.width();
double h = 0.03937*dpi*paperHeight*realRate*m_rect.height()/scaleRec.height();
return QRectF(x,y,w,h);
}
void cutDialog::setCutRectPixel(QRectF &rect)
{
m_startPoint.setX(scaleRec.width()*rect.x()/(paperWidth*realRate*0.03937*dpi));
m_startPoint.setY(scaleRec.height()*rect.y()/(paperHeight*realRate*0.03937*dpi));
m_endPoint.setX(m_startPoint.x()+scaleRec.width()*rect.width()/(paperWidth*realRate*0.03937*dpi));
m_endPoint.setY(m_startPoint.y()+scaleRec.height()*rect.height()/(paperHeight*realRate*0.03937*dpi));
update();
}
int cutDialog::getCutRectRight() const
{
return getPaperSize().width()*m_rect.right()/scaleRec.right();
}
int cutDialog::getCutRectBottom() const
{
return getPaperSize().height()*m_rect.bottom()/scaleRec.bottom();
}
void cutDialog::mousePressEvent(QMouseEvent *event)
{
int x = event->x()/**paperWidth/width()*/;
int y = event->y()/**paperHeight/height()*/;
m_moveStart = QPoint(x,y);
m_mouse_down = event->button() == Qt::LeftButton;
update();
}
void cutDialog::mouseMoveEvent(QMouseEvent *event)
{
int x = event->x()/**paperWidth/width()*/;
int y = event->y()/**paperHeight/height()*/;
if(m_mouse_down){
int dx = m_moveStart.x() - x;
int dy = m_moveStart.y() - y;
m_moveStart = QPoint(x,y);
if(m_leftCorn){
m_startPoint.setX(x);
}else if(m_rightCorn){
m_endPoint.setX(x);
}else if(m_topCorn){
m_startPoint.setY(y);
}else if(m_bottomCorn){
m_endPoint.setY(y);
}else if(m_leftTop){
m_startPoint.setX(x);
m_startPoint.setY(y);
}else if(m_leftBottom){
m_startPoint.setX(x);
m_endPoint.setY(y);
}else if(m_rightTop){
m_startPoint.setY(y);
m_endPoint.setX(x);
}else if(m_rightBottom){
m_endPoint.setX(x);
m_endPoint.setY(y);
}
else if(!m_out){
if(m_startPoint.x() - dx < 0) dx = 0;
if(m_startPoint.y() - dy < 0) dy = 0;
if(m_endPoint.x() - dx > scaleRec.right()) dx = 0;
if(m_endPoint.y() - dy > scaleRec.bottom()) dy = 0;
m_startPoint.setX(m_rect.left()-dx);
m_startPoint.setY(m_rect.top()-dy);
m_endPoint.setX(m_rect.right()-dx);
m_endPoint.setY(m_rect.bottom()-dy);
}
if(m_startPoint.x()<=0) m_startPoint.setX(0);
if(m_startPoint.y()<=0) m_startPoint.setY(0);
if(m_endPoint.x()>=scaleRec.width()) m_endPoint.setX(scaleRec.right());
if(m_endPoint.y()>=scaleRec.height()) m_endPoint.setY(scaleRec.bottom());
if(qAbs(m_startPoint.x() - m_endPoint.x()) <= 10 || m_startPoint.x() > m_endPoint.x()){
m_startPoint.setX(m_rect.left());
m_endPoint.setX(m_rect.right());
}
if(qAbs(m_startPoint.y() - m_endPoint.y()) <= 10 || m_startPoint.y() > m_endPoint.y()){
m_startPoint.setY(m_rect.top());
m_endPoint.setY(m_rect.bottom());
}
update();
}else{
mousePosition(QPoint(x,y));
}
}
void cutDialog::mouseReleaseEvent(QMouseEvent *)
{
m_mouse_down = false;
update();
}
void cutDialog::enterEvent(QEvent *)
{
emit lineEditEnable(false);
}
void cutDialog::leaveEvent(QEvent *)
{
emit lineEditEnable(true);
}
void cutDialog::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.translate(0,0);
drawScale(painter);
drawCutRect(painter);
drawTransparentColor(painter);
if(m_mouse_down){
if(sizeType == INCH || sizeType == MILLIM){
emit cutRectX(QString::number(getCutRectStartPos().x(),'f',2).toDouble());
emit cutRectY(QString::number(getCutRectStartPos().y(),'f',2).toDouble());
emit cutRectWidth(QString::number(getCutRectSize().width(),'f',2).toDouble());
emit cutRectHeight(QString::number(getCutRectSize().height(),'f',2).toDouble());
}else{
emit cutRectX(double(int(getCutRectStartPos().x())));
emit cutRectY(double(int(getCutRectStartPos().y())));
emit cutRectWidth(double(int(getCutRectSize().width())));
emit cutRectHeight(double(int(getCutRectSize().height())));
}
}
painter.end();
}
void cutDialog::drawScale(QPainter& painter)
{
painter.setPen(QPen(Qt::black,1));
scaleRec = QRectF(0,0,paperWidth,paperHeight+0.5);
painter.drawRect(scaleRec);
for(int i = 6 ; i <= paperWidth-6; i++){
if(int(paperWidth/2) == i || int(paperWidth/4) == i || int(paperWidth*3/4) == i){
painter.setPen(QPen(Qt::gray,1));
painter.drawLine(i,0,i,paperHeight);
painter.setPen(QPen(Qt::black,1));
}
if(i%divisor == 0){
painter.drawLine(i,paperHeight-4,i,paperHeight);
painter.drawLine(i,0,i,4);
}
if(i%(divisor*5) == 0){
painter.drawLine(i,paperHeight-8,i,paperHeight);
painter.drawLine(i,0,i,8);
}
}
for(int i = 6 ; i <= paperHeight-6; i++){
if(int(paperHeight/2) == i || int(paperHeight/4) == i || int(paperHeight*3/4) == i){
painter.setPen(QPen(Qt::gray,1));
painter.drawLine(0,i,paperWidth,i);
painter.setPen(QPen(Qt::black,1));
}
if(i%divisor == 0){
painter.drawLine(0,i,4,i);
painter.drawLine(paperWidth,i,paperWidth-4,i);
}
if(i%(divisor*5) == 0){
painter.drawLine(0,i,8,i);
painter.drawLine(paperWidth,i,paperWidth-8,i);
}
}
}
void cutDialog::drawCutRect(QPainter &painter)
{
painter.setPen(QPen(Qt::green,1));
m_rect = QRectF(m_startPoint,m_endPoint);
QRectF r(m_rect);
if(r.right() + 6 > paperWidth)
r.setRight(paperWidth - 6);
if(r.bottom() + 2 > paperHeight)
r.setBottom(paperHeight - 2);
painter.drawRect(r);
painter.setPen(QPen(Qt::red,1));
painter.setBrush(Qt::red);
painter.drawEllipse(r.left()-2,(r.bottom()-r.top())/2+r.top()-2,4,4);
painter.drawEllipse(r.left()-2,r.top()-2,4,4);
painter.drawEllipse(r.left()-2,r.bottom()-2,4,4);
painter.drawEllipse(r.right()-2,r.top()-2,4,4);
painter.drawEllipse(r.right()-2,r.bottom()-2,4,4);
painter.drawEllipse(r.right()-2,(r.bottom()-r.top())/2+r.top()-2,4,4);
painter.drawEllipse((r.right()-r.left())/2+r.left()-2,r.top()-2,4,4);
painter.drawEllipse((r.right()-r.left())/2+r.left()-2,r.bottom()-2,4,4);
}
void cutDialog::drawTransparentColor(QPainter &painter)
{
QPainterPath painterPath;
QPainterPath p;
p.addRect(scaleRec);
painterPath.addRect(m_rect);
QPainterPath drawPath =p.subtracted(painterPath);
painter.setOpacity(0.7);
painter.fillPath(drawPath,QBrush(Qt::gray));
}
void cutDialog::mousePosition(const QPoint& e)
{
initAllCorner();
QRectF r = QRectF(m_rect);
int x = e.x();
int y = e.y();
m_left = qAbs(x - r.left()) < 5;
m_right = qAbs(x - r.right()) < 5;
m_bottom = qAbs(y - r.bottom()) < 5;
m_top = qAbs(y - r.top()) < 5;
m_out = r.left()-x>=5 || x-r.right()>=5 || r.top()-y>=5 || y-r.bottom()>=5;
bool lorr = m_left | m_right;
bool torb = m_top | m_bottom;
if(lorr && torb)
{
if((m_left && m_top) || (m_right && m_bottom))
setCursor(Qt::SizeFDiagCursor);
else
setCursor(Qt::SizeBDiagCursor);
}
else if(lorr)
setCursor(Qt::SizeHorCursor);
else if(torb)
setCursor(Qt::SizeVerCursor);
else if(!m_out)
{
setCursor(Qt::SizeAllCursor);
m_bottom = m_left = m_right = m_top = false;
}else if(m_out){
setCursor(Qt::ArrowCursor);
m_bottom = m_left = m_right = m_top = false;
}
if(m_left && m_top) m_leftTop = true;
else if(m_left && m_bottom) m_leftBottom = true;
else if(m_right && m_top) m_rightTop = true;
else if(m_right && m_bottom) m_rightBottom = true;
else if(m_left && !m_top && !m_bottom) m_leftCorn = true;
else if(m_right && !m_top && !m_bottom) m_rightCorn = true;
else if(m_top && !m_left && !m_right) m_topCorn = true;
else if(m_bottom && !m_left && !m_right) m_bottomCorn = true;
else initAllCorner();
}
void cutDialog::refreshView()
{
if(sizeType == INCH){
emit cutRectX(QString::number(getCutRectStartPos().x(),'f',2).toDouble());
emit cutRectY(QString::number(getCutRectStartPos().y(),'f',2).toDouble());
emit cutRectWidth(QString::number(getCutRectSize().width(),'f',2).toDouble());
emit cutRectHeight(QString::number(getCutRectSize().height(),'f',2).toDouble());
}else{
emit cutRectX(QString::number(getCutRectStartPos().x(),'f',0).toDouble());
emit cutRectY(QString::number(getCutRectStartPos().y(),'f',0).toDouble());
emit cutRectWidth(double(int(getCutRectSize().width())));
emit cutRectHeight(double(int(getCutRectSize().height())));
}
}
void cutDialog::initAllCorner()
{
m_left = false;
m_right = false;
m_bottom = false;
m_top = false;
m_leftCorn = false;
m_rightCorn = false;
m_topCorn = false;
m_bottomCorn = false;
m_leftTop = false;
m_leftBottom = false;
m_rightTop = false;
m_rightBottom = false;
}

100
modules/saneui/cutdialog.h Normal file
View File

@ -0,0 +1,100 @@
#ifndef CUTDIALOG_H
#define CUTDIALOG_H
#include <QWidget>
#include <QMouseEvent>
#include <QPainter>
#include <QCursor>
namespace Ui {
class cutDialog;
}
enum SIZETYPE{
MILLIM ,
INCH,
PIXEL
};
class cutDialog : public QWidget
{
Q_OBJECT
public:
explicit cutDialog(QWidget *parent = nullptr);
~cutDialog();
void setPaperSize(QString type = "A1", const int w = 200);
void setDpiValue(const double d);
void setSizeType(const SIZETYPE& t);
void setCutRectWidth(double w);
void setCutRectHeight(double h);
void setCutRectStartX(double x);
void setCutRectStartY(double y);
QSizeF getPaperSize()const;
QSizeF getCutRectSize()const;
QPointF getCutRectStartPos()const;
QRectF getCutRectPixel()const;
void setCutRectPixel(QRectF& rect);
int getCutRectRight()const;
int getCutRectBottom()const;
void refreshView();
signals:
void cutRectX(double x);
void cutRectY(double y);
void cutRectWidth(double w);
void cutRectHeight(double h);
void lineEditEnable(bool b);
private:
void mousePressEvent(QMouseEvent*);
void mouseMoveEvent(QMouseEvent*);
void mouseReleaseEvent(QMouseEvent*);
void enterEvent(QEvent*);
void leaveEvent(QEvent*);
//void resizeEvent(QResizeEvent*);
void paintEvent(QPaintEvent *);
void drawScale(QPainter &painter);
void drawCutRect(QPainter &painter);
void drawTransparentColor(QPainter &painter);
void drawPaperSize();
void mousePosition(const QPoint &e);
void initAllCorner();
//void mouseChangeRect(int dx,int dy);
private:
Ui::cutDialog *ui;
QPointF m_startPoint;
QPointF m_endPoint;
QPointF m_moveStart;
QRectF m_rect;
QRectF scaleRec;
QString paperType;
double paperWidth;
double paperHeight;
int divisor;
int sizeType;
double dpi;
double h_w;
double realRate;
double sizeRate;
bool m_mouse_down;
bool m_left;
bool m_right;
bool m_bottom;
bool m_top;
bool m_leftCorn;
bool m_rightCorn;
bool m_topCorn;
bool m_bottomCorn;
bool m_leftTop;
bool m_rightTop;
bool m_leftBottom;
bool m_rightBottom;
bool m_out;
};
#endif // CUTDIALOG_H

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>cutDialog</class>
<widget class="QWidget" name="cutDialog">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>321</width>
<height>342</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>2</width>
<height>0</height>
</size>
</property>
<property name="baseSize">
<size>
<width>2</width>
<height>0</height>
</size>
</property>
<property name="mouseTracking">
<bool>true</bool>
</property>
<property name="windowTitle">
<string>cutDialog</string>
</property>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,219 @@
#include "cutpapertool.h"
#include "ui_cutpapertool.h"
#include <QDebug>
#include <QValidator>
CutPaperTool::CutPaperTool(QWidget *parent) :
QDialog(parent),
ui(new Ui::CutPaperTool)
{
ui->setupUi(this);
setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
connect(ui->widget,SIGNAL(cutRectX(double)),this,SLOT(cutRectXSlot(double)));
connect(ui->widget,SIGNAL(cutRectY(double)),this,SLOT(cutRectYSlot(double)));
connect(ui->widget,SIGNAL(cutRectWidth(double)),this,SLOT(cutRectWidthSlot(double)));
connect(ui->widget,SIGNAL(cutRectHeight(double)),this,SLOT(cutRectHeightSlot(double)));
connect(ui->widget,SIGNAL(lineEditEnable(bool)),this,SLOT(lineEditEnableSlot(bool)));
//setDpi(200);
//setPaperType(200,"A4",400);
ui->widget->setSizeType(MILLIM);
setSizeLabel();
//ui->pbtn_init->setFixedWidth(160);
this->setFixedWidth(ui->widget->width()+40);
}
CutPaperTool::~CutPaperTool()
{
delete ui;
}
void CutPaperTool::paintEvent(QPaintEvent *)
{
}
void CutPaperTool::setPaperType(const int d, const QString &t, const int& w)
{
dpi = d;
ui->dpiLab->setText(QString::number(dpi));
ui->widget->setDpiValue(dpi);
paperType = t;
ui->paperLab->setText(paperType);
ui->widget->setPaperSize(paperType,w);
//ui->widget->refreshView();
setSizeLabel();
this->setFixedWidth(ui->widget->width()+40);
setSizeInit();
}
QRectF CutPaperTool::getCutRectPixel()
{
return QRectF(ui->widget->getCutRectPixel());
}
void CutPaperTool::setCutRect(QRectF &rect)
{
ui->widget->setCutRectPixel(rect);
ui->startXEdt->setText(QString::number(rect.x()/dpi/0.03937));
ui->startYEdt->setText(QString::number(rect.y()/dpi/0.03937));
ui->rectWidth->setText(QString::number(rect.width()/dpi/0.03937));
ui->rectHeight->setText(QString::number(rect.height()/dpi/0.03937));
}
void CutPaperTool::setSizeLabel()
{
QString wSize;
QString hSize;
if(ui->comboBox_2->currentIndex() == INCH){
wSize = QString::number(ui->widget->getPaperSize().width(),'f',2);
hSize = QString::number(ui->widget->getPaperSize().height(),'f',2);
}
else {
wSize = QString::number(int(ui->widget->getPaperSize().width()+0.001));
hSize = QString::number(int(ui->widget->getPaperSize().height()+0.001));
}
ui->sizeLabel->setText("("+wSize + " * " +hSize+")");
}
void CutPaperTool::setSizeInit()
{
ui->widget->setCutRectStartX(0);
ui->widget->setCutRectStartY(0);
ui->widget->setCutRectWidth(ui->widget->getPaperSize().width());
ui->widget->setCutRectHeight(ui->widget->getPaperSize().height());
ui->startXEdt->setText("0");
ui->startYEdt->setText("0");
ui->rectWidth->setText(QString::number(int(ui->widget->getPaperSize().width())));
ui->rectHeight->setText(QString::number(int(ui->widget->getPaperSize().height())));
}
void CutPaperTool::setSizeInit(QRectF& rect){
setSizeInit();
if(rect != QRectF(0,0,0,0))
setCutRect(rect);
}
void CutPaperTool::cutRectXSlot(double x)
{
ui->startXEdt->setText(QString::number(x));
}
void CutPaperTool::cutRectYSlot(double y)
{
ui->startYEdt->setText(QString::number(y));
}
void CutPaperTool::cutRectWidthSlot(double w)
{
ui->rectWidth->setText(QString::number(w));
}
void CutPaperTool::cutRectHeightSlot(double h)
{
ui->rectHeight->setText(QString::number(h));
}
void CutPaperTool::lineEditEnableSlot(bool b)
{
ui->startXEdt->setEnabled(b);
ui->startYEdt->setEnabled(b);
ui->rectWidth->setEnabled(b);
ui->rectHeight->setEnabled(b);
}
void CutPaperTool::on_startXEdt_textEdited(QString arg1)
{
double x = arg1.toDouble();
if(x >ui->widget->getCutRectRight()) {
//arg1.chop(1);
//x = arg1.toDouble();
//x = ui->widget->getCutRectRight();
return ;
}
if(type == PIXEL) x = arg1.toInt();
ui->widget->setCutRectStartX(x);
}
void CutPaperTool::on_startYEdt_textEdited(QString arg1)
{
double y = arg1.toDouble();
if(y >ui->widget->getCutRectBottom()) {
//arg1.chop(1);
//y = arg1.toDouble();
return ;
}
if(type == PIXEL) y = arg1.toInt();
ui->widget->setCutRectStartY(y);
}
void CutPaperTool::on_rectWidth_textEdited(QString arg1)
{
double v = arg1.toDouble();
if(v > ui->widget->getPaperSize().width() - ui->widget->getCutRectStartPos().x()) {
//arg1.chop(1);
//v = arg1.toDouble();
//v=ui->widget->getPaperSize().width() - ui->widget->getCutRectStartPos().x();
return ;
}
if(type == PIXEL) v = arg1.toInt();
ui->widget->setCutRectWidth(v);
}
void CutPaperTool::on_rectHeight_textEdited(QString arg1)
{
double v = arg1.toDouble();
if(v > ui->widget->getPaperSize().height() - ui->widget->getCutRectStartPos().y()) {
//arg1.chop(1);
//v = arg1.toDouble();
//v = ui->widget->getPaperSize().height() - ui->widget->getCutRectStartPos().y();
return ;
}
if(type == PIXEL) v = arg1.toInt();
ui->widget->setCutRectHeight(v);
}
void CutPaperTool::on_comboBox_2_currentIndexChanged(int index)
{
switch(index){
case 0:
ui->xLabel->setText("mm");
ui->yLabel->setText("mm");
ui->wLabel->setText("mm");
ui->hLabel->setText("mm");
ui->widget->setSizeType(MILLIM);
break;
case 1:
ui->xLabel->setText("in");
ui->yLabel->setText("in");
ui->wLabel->setText("in");
ui->hLabel->setText("in");
ui->widget->setSizeType(INCH);
break;
case 2:
ui->xLabel->setText("px");
ui->yLabel->setText("px");
ui->wLabel->setText("px");
ui->hLabel->setText("px");
ui->widget->setSizeType(PIXEL);
break;
}
update();
setSizeLabel();
ui->widget->refreshView();
}
void CutPaperTool::on_buttonBox_accepted()
{
accept();
}
void CutPaperTool::on_buttonBox_rejected()
{
reject();
}
void CutPaperTool::on_pbtn_init_clicked()
{
setSizeInit();
}

View File

@ -0,0 +1,59 @@
#ifndef CUTPAPERTOOL_H
#define CUTPAPERTOOL_H
#include <QDialog>
#include "cutdialog.h"
namespace Ui {
class CutPaperTool;
}
class CutPaperTool : public QDialog
{
Q_OBJECT
public:
explicit CutPaperTool(QWidget *parent = nullptr);
~CutPaperTool();
void setPaperType(const int dpi, const QString& t,const int& w=200);
QRectF getCutRectPixel();
void setCutRect(QRectF& rect);
void setSizeInit();
void setSizeInit(QRectF& rect);
private:
void paintEvent(QPaintEvent *);
void setSizeLabel();
private slots:
void cutRectXSlot(double x);
void cutRectYSlot(double y);
void cutRectWidthSlot(double w);
void cutRectHeightSlot(double h);
void lineEditEnableSlot(bool b);
void on_startXEdt_textEdited(QString arg1);
void on_startYEdt_textEdited(QString arg1);
void on_rectWidth_textEdited(QString arg1);
void on_rectHeight_textEdited(QString arg1);
void on_comboBox_2_currentIndexChanged(int index);
void on_buttonBox_accepted();
void on_buttonBox_rejected();
void on_pbtn_init_clicked();
private:
Ui::CutPaperTool *ui;
SIZETYPE type;
int dpi;
QString paperType;
};
#endif // CUTPAPERTOOL_H

View File

@ -0,0 +1,298 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CutPaperTool</class>
<widget class="QWidget" name="CutPaperTool">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>439</width>
<height>676</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>自定义扫描区域</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>纸张尺寸:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="paperLab">
<property name="text">
<string>A4</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="sizeLabel">
<property name="text">
<string>(210*297)</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string>DPI(像素/英寸)</string>
</property>
<property name="alignment">
<set>Qt::AlignJustify|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="dpiLab">
<property name="text">
<string>200</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>单位:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_2">
<item>
<property name="text">
<string>毫米mm</string>
</property>
</item>
<item>
<property name="text">
<string>英寸in)</string>
</property>
</item>
<item>
<property name="text">
<string>像素px</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pbtn_init">
<property name="text">
<string>初始化选择区域</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_4">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>421</width>
<height>430</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="cutDialog" name="widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>x:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="startXEdt"/>
</item>
<item>
<widget class="QLabel" name="xLabel">
<property name="text">
<string>mm</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>y:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="startYEdt"/>
</item>
<item>
<widget class="QLabel" name="yLabel">
<property name="text">
<string>mm</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="wLabel_2">
<property name="text">
<string>w:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="rectWidth"/>
</item>
<item>
<widget class="QLabel" name="wLabel">
<property name="text">
<string>mm</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>h:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="rectHeight"/>
</item>
<item>
<widget class="QLabel" name="hLabel">
<property name="text">
<string>mm</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>cutDialog</class>
<extends>QWidget</extends>
<header location="global">cutdialog.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,189 @@
#include "device_menu.h"
#define ACTION_DEVICE_NAME_PROPERTY "device_name"
device_menu::device_menu(QWidget *parent)
: QMenu(parent)
, cur_action_(nullptr), none_action_(nullptr)
{
group_action_ = new QActionGroup(this);
deviceMenuUpdate(nullptr);
connect(group_action_, SIGNAL(triggered(QAction*)), this, SLOT(on_act_triggered(QAction*)));
}
device_menu::device_menu(const QString &title, QWidget *parent)
: QMenu(title, parent)
, cur_action_(nullptr), none_action_(nullptr)
{
group_action_ = new QActionGroup(this);
deviceMenuUpdate(nullptr);
connect(group_action_, SIGNAL(triggered(QAction*)), this, SLOT(on_act_triggered(QAction*)));
}
QMenu* device_menu::find_device_menu(const QString& dev_name)
{
std::lock_guard<std::mutex> lock(mutex_);
std::vector<POPMENU>::iterator it = std::find(menus_.begin(), menus_.end(), dev_name);
if(it == menus_.end())
return nullptr;
else
return it->menu;
}
QAction* device_menu::find_device_config(const QString& dev_name, const QString& cfg_name)
{
std::lock_guard<std::mutex> lock(mutex_);
std::vector<POPMENU>::iterator it = std::find(menus_.begin(), menus_.end(), dev_name);
if(it == menus_.end())
return NULL;
for(size_t i = 0; i < it->actions.size(); ++i)
{
if(it->actions[i]->text() == cfg_name)
return it->actions[i];
}
return NULL;
}
void device_menu::connectedDevice(const QString &device)
{
QMenu* menu = find_device_menu(device);
if (menu)
menu->setEnabled(true);
}
void device_menu::disconnectedDevice(const QString &device)
{
QMenu* menu = find_device_menu(device);
if (menu)
menu->setEnabled(false);
}
void device_menu::setOptionChecked(const QString &device, const QString &opt, bool checked)
{
QAction* act = find_device_config(device, opt);
if(act)
{
act->setChecked(checked);
if(checked)
cur_action_ = act;
else
{
if(cur_action_ == act)
cur_action_ = nullptr;
}
}
else if(checked)
cur_action_ = nullptr;
}
void device_menu::get_online_devices(QList<QString>& dev_names)
{
std::lock_guard<std::mutex> lock(mutex_);
for(size_t i = 0; i < menus_.size(); ++i)
{
if(menus_[i].menu->isEnabled())
dev_names.push_back(menus_[i].menu->title());
}
}
void device_menu::deviceMenuUpdate(dev_que* que)
{
std::lock_guard<std::mutex> lock(mutex_);
cur_action_ = nullptr;
if(none_action_)
{
removeAction(none_action_);
none_action_ = nullptr;
}
for(size_t i = 0; i < menus_.size(); ++i)
menus_[i].menu->setEnabled(false);
if (!que || que->scanners() == 0)
{
if(menus_.empty())
{
none_action_ = addAction(tr("no device"));
none_action_->setEnabled(false);
}
return;
}
for (size_t i = 0; i < que->scanners(); i++)
{
SCANNER s = que->get_at(i);
std::vector<POPMENU>::iterator it = std::find(menus_.begin(), menus_.end(), QString::fromStdString((s.name)));
POPMENU pm;
std::vector<std::string> schemes;
if(it == menus_.end())
pm.menu = addMenu(QString::fromStdString(s.name));
else
{
pm = *it;
menus_.erase(it);
}
pm.menu->setEnabled(true);
pm.menu->setToolTipsVisible(true);
for(size_t j = 0; j < pm.actions.size(); ++j)
{
pm.menu->removeAction(pm.actions[j]);
group_action_->removeAction(pm.actions[j]);
}
pm.actions.clear();
s.cfg->get_all_schemes(schemes);
for (size_t j = 0; j < schemes.size(); j++)
{
QAction *child = group_action_->addAction(QString::fromStdString(schemes[j]));
child->setProperty(ACTION_DEVICE_NAME_PROPERTY, QVariant(QString::fromStdString(s.name)));
child->setCheckable(true);
if(que->opened_scanner_name() == s.name &&
schemes[j] == s.cfg->get_current_scheme_name())
{
cur_action_ = child;
child->setChecked(true);
}
pm.menu->addAction(child);
pm.actions.push_back(child);
QString tips;
if(tips.isNull())
{
tips = tr("default setting");
}
// child->setToolTip(tips);
}
menus_.push_back(pm);
s.cfg->release();
}
}
void device_menu::on_act_triggered(QAction* act)
{
QString deviceName = act->property(ACTION_DEVICE_NAME_PROPERTY).toString();
QString opt = act->text();
bool checked_now = act->isChecked();
if(cur_action_ == act)
{
checked_now = false;
act->setChecked(false);
cur_action_ = nullptr;
// emit scanOptionsChanged("", "", false);
// return;
}
else {
cur_action_ = act;
checked_now = true;
}
emit scanOptionsChanged(deviceName, opt, checked_now);
}

View File

@ -0,0 +1,494 @@
#ifndef DEVICE_MENU_H
#define DEVICE_MENU_H
#include <QMenu>
#include <mutex>
#include "sane/sane_ex.h"
#include "sane/sane_option_definitions.h"
#include "../../../sdk/include/huagao/hgscanner_error.h"
#include "cfg/gb_json.h"
#include "lang/app_language.h"
typedef struct _scanner
{
std::string name;
std::string model;
bool online;
gb::scanner_cfg *cfg;
}SCANNER;
class dev_que
{
std::vector<SCANNER> que_;
std::string root_dir_;
std::string opened_scanner_;
std::string applied_scheme_;
SANE_Handle handle_;
static void trans_number(const char* name, std::string& val, void* param)
{
if (strcmp(name, "tl-x") == 0
|| strcmp(name, "br-x") == 0
|| strcmp(name, "tl-y") == 0
|| strcmp(name, "br-y") == 0
|| strcmp(name, "gamma") == 0
|| strcmp(name, "search-hole-range-l") == 0
|| strcmp(name, "search-hole-range-r") == 0
|| strcmp(name, "search-hole-range-t") == 0
|| strcmp(name, "search-hole-range-b") == 0
|| strcmp(name, "feed-strength-value") == 0
)
{
float v = atof(val.c_str());
SANE_Fixed f = SANE_FIX(v);
val = std::string((char*)&f, sizeof(f));
}
else if (strcmp(name, "binary-threshold") == 0
|| strcmp(name, "bkg-color-range") == 0
|| strcmp(name, "noise-size") == 0
|| strcmp(name, "blank-sensitivity") == 0
|| strcmp(name, "resolution") == 0
|| strcmp(name, "brightness") == 0
|| strcmp(name, "contrast") == 0
|| strcmp(name, "threshold") == 0
|| strcmp(name, "anti-noise-level") == 0
|| strcmp(name, "margin") == 0
|| strcmp(name, "scan-count") == 0
|| strcmp(name, "askew-range") == 0
|| strcmp(name, "dog-ear-size") == 0
)
{
SANE_Int v = atoi(val.c_str());
val = std::string((char*)&v, sizeof(v));
}
else if (strcmp(val.c_str(), "true") == 0)
{
SANE_Bool b = SANE_TRUE;
val = std::string((char*)&b, sizeof(b));
}
else if (strcmp(val.c_str(), "false") == 0)
{
SANE_Bool b = SANE_FALSE;
val = std::string((char*)&b, sizeof(b));
}
}
static const char* title_2_name(const char* title, void* param)
{
struct
{
const char* name;
const char* title;
}g_opts[] = { {SANE_STD_OPT_NAME_RESTORE , OPTION_TITLE_HFMRSZ}
, {SANE_STD_OPT_NAME_HELP , OPTION_TITLE_BZ}
, {SANE_STD_OPT_NAME_IS_MULTI_OUT , OPTION_TITLE_DLSC}
, {SANE_STD_OPT_NAME_MULTI_OUT_TYPE , OPTION_TITLE_DLSCLX}
, {SANE_STD_OPT_NAME_COLOR_MODE , OPTION_TITLE_YSMS}
, {SANE_STD_OPT_NAME_BINARY_THRESHOLD , OPTION_TITLE_HBTXYZ}
, {SANE_STD_OPT_NAME_REVERSE_01 , OPTION_TITLE_HBTXFSSC}
, {SANE_STD_OPT_NAME_FILTER , OPTION_TITLE_HDHHBTX_CSYZQ}
, {SANE_STD_OPT_NAME_RID_MULTIOUT_RED , OPTION_TITLE_24WCSTX_DLSCCH}
, {SANE_STD_OPT_NAME_RID_ANSWER_SHEET_RED , OPTION_TITLE_24WCSTX_DTKCH}
, {SANE_STD_OPT_NAME_ERASE_BACKGROUND , OPTION_TITLE_BJYC}
, {SANE_STD_OPT_NAME_BKG_COLOR_RANGE , OPTION_TITLE_BJSCFDFW}
, {SANE_STD_OPT_NAME_SHARPEN , OPTION_TITLE_RHYMH}
, {SANE_STD_OPT_NAME_RID_MORR , OPTION_TITLE_QCMW}
, {SANE_STD_OPT_NAME_RID_GRID , OPTION_TITLE_CWW}
, {SANE_STD_OPT_NAME_ERROR_EXTENSION , OPTION_TITLE_CWKS}
, {SANE_STD_OPT_NAME_NOISE_OPTIMIZE , OPTION_TITLE_HBTXZDYH}
, {SANE_STD_OPT_NAME_NOISE_SIZE , OPTION_TITLE_ZDYHCC}
, {SANE_STD_OPT_NAME_PAPER , OPTION_TITLE_ZZCC}
, {SANE_STD_OPT_NAME_CUSTOM_AREA , OPTION_TITLE_ZDYSMQY}
, {SANE_STD_OPT_NAME_CUSTOM_AREA_LEFT , OPTION_TITLE_SMQYZCmm}
, {SANE_STD_OPT_NAME_CUSTOM_AREA_RIGHT , OPTION_TITLE_SMQYYCmm}
, {SANE_STD_OPT_NAME_CUSTOM_AREA_TOP , OPTION_TITLE_SMQYSCmm}
, {SANE_STD_OPT_NAME_CUSTOM_AREA_BOTTOM , OPTION_TITLE_SMQYXCmm}
, {SANE_STD_OPT_NAME_SIZE_CHECK , OPTION_TITLE_CCJC}
, {SANE_STD_OPT_NAME_PAGE , OPTION_TITLE_SMYM}
, {SANE_STD_OPT_NAME_DISCARD_BLANK_SENS , OPTION_TITLE_TGKBYLMD}
, {SANE_STD_OPT_NAME_RESOLUTION , OPTION_TITLE_FBL}
, {SANE_STD_OPT_NAME_TIME_TO_SLEEP , OPTION_TITLE_XMSJ}
, {SANE_STD_OPT_NAME_IMAGE_QUALITY , OPTION_TITLE_HZ}
, {SANE_STD_OPT_NAME_EXCHANGE ,OPTION_TITLE_JHZFM}
, {SANE_STD_OPT_NAME_SPLIT ,OPTION_TITLE_TXCF }
, {SANE_STD_OPT_NAME_ANTI_SKEW , OPTION_TITLE_ZDJP}
, {SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA , OPTION_TITLE_QYSDQX}
, {SANE_STD_OPT_NAME_GAMMA , OPTION_TITLE_JMZ}
, {SANE_STD_OPT_NAME_BRIGHTNESS , OPTION_TITLE_LDZ}
, {SANE_STD_OPT_NAME_CONTRAST , OPTION_TITLE_DBD}
, {SANE_STD_OPT_NAME_IS_PHOTO_MODE , OPTION_TITLE_ZPMS}
, {SANE_STD_OPT_NAME_ERASE_BLACK_FRAME , OPTION_TITLE_XCHK}
, {SANE_STD_OPT_NAME_DARK_SAMPLE , OPTION_TITLE_SSYZ}
, {SANE_STD_OPT_NAME_THRESHOLD , OPTION_TITLE_YZ}
, {SANE_STD_OPT_NAME_ANTI_NOISE_LEVEL , OPTION_TITLE_BJKZDJ}
, {SANE_STD_OPT_NAME_MARGIN , OPTION_TITLE_BYSJ}
, {SANE_STD_OPT_NAME_FILL_BKG_MODE , OPTION_TITLE_BJTCFS}
, {SANE_STD_OPT_NAME_IS_ANTI_PERMEATE , OPTION_TITLE_FZST}
, {SANE_STD_OPT_NAME_ANTI_PERMEATE_LEVEL , OPTION_TITLE_FZSTDJ}
, {SANE_STD_OPT_NAME_RID_HOLE_L , OPTION_TITLE_CKYCZC}
, {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_L , OPTION_TITLE_ZCCKSSFWZFMBL}
, {SANE_STD_OPT_NAME_RID_HOLE_R , OPTION_TITLE_CKYCYC}
, {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_R , OPTION_TITLE_YCCKSSFWZFMBL}
, {SANE_STD_OPT_NAME_RID_HOLE_T , OPTION_TITLE_CKYCSC}
, {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_T , OPTION_TITLE_SCCKSSFWZFMBL}
, {SANE_STD_OPT_NAME_RID_HOLE_B , OPTION_TITLE_CKYCXC}
, {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_B , OPTION_TITLE_XCCKSSFWZFMBL}
, {SANE_STD_OPT_NAME_IS_FILL_COLOR , OPTION_TITLE_SCTC}
, {SANE_STD_OPT_NAME_IS_ULTROSONIC_CHECK , OPTION_TITLE_CSBJC}
, {SANE_STD_OPT_NAME_DOUBLE_FEED_HANDLE , OPTION_TITLE_SZTPCL}
, {SANE_STD_OPT_NAME_IS_CHECK_STAPLE , OPTION_TITLE_ZDJC}
, {SANE_STD_OPT_NAME_SCAN_MODE , OPTION_TITLE_SMZS}
, {SANE_STD_OPT_NAME_SCAN_COUNT , OPTION_TITLE_SMSL}
, {SANE_STD_OPT_NAME_TEXT_DIRECTION , OPTION_TITLE_WGFX}
, {SANE_STD_OPT_NAME_IS_ROTATE_BKG_180 , OPTION_TITLE_BMXZ180}
, {SANE_STD_OPT_NAME_IS_CHECK_DOG_EAR , OPTION_TITLE_ZJJC}
, {SANE_STD_OPT_NAME_DOG_EAR_SIZE , OPTION_TITLE_ZJDX}
, {SANE_STD_OPT_NAME_IS_CHECK_ASKEW , OPTION_TITLE_WXJC}
, {SANE_STD_OPT_NAME_ASKEW_RANGE , OPTION_TITLE_WXRRD}
, {SANE_STD_OPT_NAME_FEED_STRENGTH , OPTION_TITLE_FZQD}
, {SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH , OPTION_TITLE_ZDFZQD}
, {SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE , OPTION_TITLE_JZSBL}
, {SANE_STD_OPT_NAME_WAIT_TO_SCAN , OPTION_TITLE_DZSM}
, {SANE_STD_OPT_NAME_FOLD_TYPE , OPTION_TITLE_DZMS}
},
g_discard[] = { {SANE_STD_OPT_NAME_REVERSE_01 , "\351\273\221\347\231\275\345\233\276\345\203\217\345\217\215\350\211\262\350\276\223\345\207\272\357\274\210\346\255\243\345\270\270\351\242\234\350\211\262\344\270\272\357\274\2320-\351\273\221\350\211\262\357\274\2331-\347\231\275\350\211\262\357\274\211"} // 黑白图像反色输出正常颜色为0-黑色1-白色)
, {SANE_STD_OPT_NAME_FILTER , "\347\201\260\345\272\246\346\210\226\351\273\221\347\231\275\345\233\276\345\203\217 - \351\231\244\350\211\262"} // 灰度或黑白图像 - 除色
, {SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH , "\350\207\252\345\212\250\346\220\223\347\272\270\345\274\272\345\272\246"} // 自动搓纸强度
, {SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE , "\346\220\223\347\272\270\351\230\210\345\200\274"} // " 搓纸阈值"
};
while (*title == ' ')
title++;
for (size_t i = 0; i < _countof(g_opts); ++i)
{
if (strcmp(title, g_opts[i].title) == 0)
return g_opts[i].name;
}
for (size_t i = 0; i < _countof(g_discard); ++i)
{
if (strcmp(title, g_discard[i].title) == 0)
return g_discard[i].name;
}
return title;
}
public:
dev_que() : handle_(nullptr)
{}
~dev_que()
{
close_scanner();
for(auto& v : que_)
v.cfg->release();
}
static void update_old_cfg(const char* conf)
{
gb::scanner_cfg::UDF func;
func.func_param = nullptr;
func.title2name = &dev_que::title_2_name;
func.trans_number = &dev_que::trans_number;
gb::scanner_cfg::update(conf, &func);
}
static void apply_scheme(SANEAPI* saneApi, SANE_Handle h, gb::sane_config_schm* schm)
{
SANE_Int count = 0, none = 0;
std::string name(""), val("");
none = saneApi->sane_io_control_api(h, IO_CTRL_CODE_RESTORE_SETTINGS, NULL, NULL);
if(schm && schm->id_from_name(SANE_STD_OPT_NAME_COLOR_MODE) == -1)
{
SANE_Int dev_options = 0;
saneApi->sane_control_option_api(h, 0, SANE_ACTION_GET_VALUE, &dev_options, nullptr);
for(int i = 1; i < dev_options; ++i)
{
const SANE_Option_Descriptor* opt = saneApi->sane_get_option_descriptor_api(h, i);
if(!opt)
continue;
unsigned int n = i;
if(opt->type == SANE_TYPE_BOOL)
{
SANE_Bool v = SANE_TRUE;
saneApi->sane_io_control_api(h, IO_CTRL_CODE_GET_DEFAULT_VALUE, &v, &n);
schm->set_default_value(i, opt->name, (char*)&v, sizeof(v));
}
else if (opt->type == SANE_TYPE_INT) {
SANE_Int v = 0;
saneApi->sane_io_control_api(h, IO_CTRL_CODE_GET_DEFAULT_VALUE, &v, &n);
schm->set_default_value(i, opt->name, (char*)&v, sizeof(v));
}
else if(opt->type == SANE_TYPE_FIXED)
{
SANE_Fixed v = 0;
saneApi->sane_io_control_api(h, IO_CTRL_CODE_GET_DEFAULT_VALUE, &v, &n);
schm->set_default_value(i, opt->name, (char*)&v, sizeof(v));
}
else {
char *buf = new char[opt->size + 4];
memset(buf, 0, opt->size + 4);
saneApi->sane_io_control_api(h, IO_CTRL_CODE_GET_DEFAULT_VALUE, buf, &n);
std::string langCN(to_default_language(buf, nullptr));
schm->set_default_value(i, opt->name, &langCN[0], langCN.length());
delete[] buf;
}
}
}
if(schm && schm->first_config(name, val))
{
do
{
int id = schm->id_from_name(name.c_str());
if(id == -1)
{
if(gb::sane_config_schm::is_option_data(name))
{
if(name == SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA && val.length() == sizeof(SANE_Gamma))
{
unsigned int l = val.length();
saneApi->sane_io_control_api(h, IO_CTRL_CODE_SET_CUSTOM_GAMMA, &val[0], &l);
}
}
}
else {
const SANE_Option_Descriptor* opt = reinterpret_cast<const SANE_Option_Descriptor*>(saneApi->sane_get_option_descriptor_api(h, id));
if(opt)
{
if(opt->type == SANE_TYPE_STRING)
{
char *buf = new char[opt->size + 4];
memset(buf, 0, opt->size + 4);
strcpy(buf, val.c_str());
std::string langCN(from_default_language(buf, nullptr));
saneApi->sane_control_option_api(h, id, SANE_ACTION_SET_VALUE, &langCN[0], &none);
delete[] buf;
}
else {
saneApi->sane_control_option_api(h, id, SANE_ACTION_SET_VALUE, &val[0], &none);
}
}
}
}while(schm->next_config(name, val));
}
}
public:
void set_root_dir(const char* root)
{
root_dir_ = std::string(root) + PATH_SYMBOL;
}
void add_scanner(const char* sane_name)
{
bool found = false;
for(auto& v: que_)
{
if(v.name == sane_name)
{
found = true;
break;
}
}
if(!found)
{
SCANNER s;
size_t pos = 0;
s.model = s.name = sane_name;
s.cfg = nullptr;
pos = s.model.find(" - ");
if(pos != std::string::npos)
{
pos = s.model.find(" - ", pos + 3);
if(pos != std::string::npos)
s.model.erase(pos);
}
for(auto& v: que_)
{
if(v.model == s.model)
{
s.cfg = v.cfg;
s.cfg->add_ref();
break;
}
}
if(!s.cfg)
{
s.cfg = new gb::scanner_cfg();
s.cfg->load_file((root_dir_ + s.model + ".cfg").c_str());
}
s.online = true;
que_.push_back(s);
}
}
void get_schemes(const char* scanner_name, std::vector<std::string>& schemes)
{
schemes.clear();
for(auto& v : que_)
{
if(v.name == scanner_name)
{
v.cfg->get_all_schemes(schemes);
break;
}
}
}
SANE_Handle handle(void)
{
return handle_;
}
std::string opened_scanner_name(void)
{
return opened_scanner_;
}
std::string applied_scheme(void)
{
return applied_scheme_;
}
int open_scanner(SANEAPI* saneAPI, SANE_Handle handle, const char* scanner_name, const char* scheme = nullptr)
{
handle_ = handle;
opened_scanner_ = scanner_name;
apply_scheme(saneAPI, scheme);
return SANE_STATUS_GOOD;
}
int close_scanner(void)
{
handle_ = nullptr;
opened_scanner_ = "";
applied_scheme_ = "";
return SANE_STATUS_GOOD;
}
int scanners(void)
{
return que_.size();
}
SCANNER get_at(int pos)
{
SCANNER s;
s.name = s.model = "";
s.cfg = nullptr;
if(pos >= 0 && pos < que_.size())
{
s = que_[pos];
s.cfg->add_ref();
}
return s;
}
bool is_online(const char* scanner = nullptr)
{
if(!scanner)
scanner = opened_scanner_.c_str();
for(auto& v : que_)
{
if(v.name == scanner)
return v.online;
}
return false;
}
void set_online(bool online, const char* scanner = nullptr)
{
if(!scanner)
scanner = opened_scanner_.c_str();
for(auto& v : que_)
{
if(v.name == scanner)
{
v.online = online;
break;
}
}
}
void get_scanners(std::vector<std::string>& que)
{
for(auto& v: que_)
que.push_back(v.name);
}
int apply_scheme(SANEAPI* saneApi, const char* scheme_name)
{
if(!handle_)
return SCANNER_ERR_NOT_OPEN;
for(auto& v: que_)
{
if(v.name == opened_scanner_)
{
gb::sane_config_schm* schm = v.cfg->get_scheme(scheme_name);
dev_que::apply_scheme(saneApi, handle_, schm);
if(schm)
{
v.cfg->select_scheme(schm->get_scheme_name().c_str());
schm->release();
}
else {
v.cfg->select_scheme(scheme_name);
}
applied_scheme_ = v.cfg->get_current_scheme_name();
v.cfg->save();
break;
}
}
return SCANNER_ERR_OK;
}
};
class device_menu : public QMenu
{
Q_OBJECT
typedef struct _pop_menu
{
QMenu* menu;
std::vector<QAction*> actions;
bool operator==(const QString& menu_title)
{
return menu->title() == menu_title;
}
}POPMENU;
std::vector<POPMENU> menus_;
QAction* cur_action_;
QAction* none_action_;
QActionGroup* group_action_;
std::mutex mutex_;
QMenu* find_device_menu(const QString& dev_name);
QAction* find_device_config(const QString& dev_name, const QString& cfg_name);
public:
device_menu(QWidget* parent = nullptr);
device_menu(const QString& title, QWidget* parent = nullptr);
void deviceMenuUpdate(dev_que* que);
void connectedDevice(const QString& device);
void disconnectedDevice(const QString& device);
void setOptionChecked(const QString& device, const QString& opt, bool checked);
void get_online_devices(QList<QString>& dev_names);
signals:
void scanOptionsChanged(const QString& device, const QString& opt, bool checked_now);
private slots:
void on_act_triggered(QAction* act);
};
#endif // DEVICE_MENU_H

View File

@ -1,6 +1,8 @@
#include "dialog_device_scan.hpp" #include "dialog_device_scan.hpp"
#include "ui_dialog_device_scan.h" #include "ui_dialog_device_scan.h"
#include "base/HGInc.h" #include "base/HGInc.h"
#include <QMessageBox>
#include <QCloseEvent>
Dialog_Device_Scan::Dialog_Device_Scan(SANEAPI* saneApi, SANE_Handle dev, Dialog_Device_Scan::Dialog_Device_Scan(SANEAPI* saneApi, SANE_Handle dev,
show_scan_ui_image_callback callback, void *callbackParam, QWidget *parent) : show_scan_ui_image_callback callback, void *callbackParam, QWidget *parent) :
@ -98,6 +100,16 @@ void Dialog_Device_Scan::on_pushButton_Continue_clicked()
ui->label->setText(tr("正在扫描......")); ui->label->setText(tr("正在扫描......"));
} }
void Dialog_Device_Scan::closeEvent(QCloseEvent *e)
{
if (NULL != m_thread)
{
QMessageBox::warning(this, tr("Warning"), tr("Device is Running"));
e->ignore();
return;
}
}
void HGAPI Dialog_Device_Scan::ThreadFunc(HGThread thread, HGPointer param) void HGAPI Dialog_Device_Scan::ThreadFunc(HGThread thread, HGPointer param)
{ {
Dialog_Device_Scan* p = (Dialog_Device_Scan*)param; Dialog_Device_Scan* p = (Dialog_Device_Scan*)param;

View File

@ -31,6 +31,9 @@ private slots:
void on_pushButton_Complete_clicked(); void on_pushButton_Complete_clicked();
void on_pushButton_Continue_clicked(); void on_pushButton_Continue_clicked();
protected:
virtual void closeEvent(QCloseEvent *e) override;
private: private:
static void HGAPI ThreadFunc(HGThread thread, HGPointer param); static void HGAPI ThreadFunc(HGThread thread, HGPointer param);

View File

@ -0,0 +1,65 @@
#include "dialog_input.h"
#include "ui_dialog_input.h"
#include <qmessagebox.h>
#include <QRegularExpression>
Dialog_Input::Dialog_Input(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog_Input)
{
ui->setupUi(this);
}
Dialog_Input::~Dialog_Input()
{
delete ui;
}
void Dialog_Input::on_pushButton_clicked()
{
QString text = ui->lineEdit->text();
static QRegularExpression re("\\s");
text.remove(re);//Remove space
std::string str(text.toStdString());
int pos = 0;
while(pos < str.length() && str[pos++] == ' ');
if(--pos > 0)
str.erase(0, pos);
pos = str.length() - 1;
while(pos >= 0)
{
if(str[pos] != ' ')
break;
}
str.erase(pos + 1);
if(str.empty())
{
QString title(QString::fromStdString("\351\224\231\350\257\257")),
text(QString::fromStdString("\350\276\223\345\205\245\351\235\236\346\263\225"));
QMessageBox::warning(this, title, text);
return;
}
val_ = QString::fromStdString(str);
done(1);
}
void Dialog_Input::on_pushButton_2_clicked()
{
done(0);
}
void Dialog_Input::init_value(const QString& str)
{
val_ = str;
ui->lineEdit->setText(str);
ui->lineEdit->setSelection(0, str.length());
}
QString Dialog_Input::get_inputting_value(void)
{
return val_;
}

View File

@ -0,0 +1,33 @@
#ifndef DIALOG_INPUT_H
#define DIALOG_INPUT_H
#include <QDialog>
namespace Ui {
class Dialog_Input;
}
class Dialog_Input : public QDialog
{
Q_OBJECT
QString val_;
public:
explicit Dialog_Input(QWidget *parent = nullptr);
~Dialog_Input();
public:
void init_value(const QString& str);
QString get_inputting_value(void);
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::Dialog_Input *ui;
};
#endif // DIALOG_INPUT_H

View File

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog_Input</class>
<widget class="QDialog" name="Dialog_Input">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>282</width>
<height>82</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="midLineWidth">
<number>-1</number>
</property>
<property name="text">
<string>输入:</string>
</property>
<property name="margin">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit"/>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Ok</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_2">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,54 @@
#include "gaosixy.h"
#include <QDebug>
#include <stdlib.h>
#include <math.h>
GaoSiXY::GaoSiXY()
{
}
void GaoSiXY::solve(double**a,int n,double *recv)
{
int m = 0;
int i,j;
for(j = 0; j < n; j++){
double max = 0;
double imax = 0;
for(i = j; i < n; i++){
if(imax < fabs(a[i][j])){
imax = fabs(a[i][j]);
max = a[i][j];//得到各行中所在列最大元素
m = i;
}
}
if(fabs(a[j][j]) != max) {
double b = 0;
for(int k = j;k < n + 1; k++){
b = a[j][k];
a[j][k] = a[m][k];
a[m][k] = b; }
}
for(int r = j;r < n + 1;r++){
a[j][r] = a[j][r] / max;//让该行的所在列除以所在列的第一个元素目的是让首元素为1
}
for(i = j + 1;i < n; i++){
double c = a[i][j];
if(c == 0) continue;
for(int s = j;s < n + 1;s++){
//double tempdata = a[i][s];
a[i][s] = a[i][s] - a[j][s] * c;//前后行数相减使下一行或者上一行的首元素为0
}
}
}
for(i = n - 2; i >= 0; i--){
for(j = i + 1;j < n; j++){
a[i][n] = a[i][n] - a[j][n] * a[i][j];
}
}
for(int k = 0; k < n; k++){
recv[k] = a[k][n];
}
}

17
modules/saneui/gaosixy.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef GAOSIXY_H
#define GAOSIXY_H
#include <stdio.h>
#include <stdlib.h>
class GaoSiXY
{
public:
GaoSiXY();
void solve(double **a,int n,double *recv);//用于计算曲线方程
private:
};
#endif // GAOSIXY_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,141 @@
#ifndef HG_SETTING_DIALOG_H
#define HG_SETTING_DIALOG_H
#include <QtWidgets>
#include <QSettings>
#include <algorithm>
#include "sane/sane_ex.h"
#include "cfg/gb_json.h"
#include "device_menu.h"
class hg_settingdialog : public QDialog
{
Q_OBJECT
int changed_count_;
bool save_;
bool clicked_gamma_;
dev_que dev_que_;
gb::scanner_cfg *cur_cfg_;
gb::sane_config_schm *cur_scheme_;
void refresh_control_value(int op_id);
void on_select_scheme(bool apply_to_dev = true);
QString gen_gamma_file_path(void);
QMenu *top_menu_;
QLineEdit *edit_name_;
QPushButton *rename_;
QPushButton *apply_;
QPushButton *del_this_;
QPushButton *del_all_;
QLabel *custom_area_lable_;
QPushButton *btn_cut_area_;
QPushButton *btn_gamma_;
QTextEdit *sketch_;
QLineEdit *m_lineEdit_name;
void create_scheme_management_ui(QVBoxLayout* layout);
QString find_current_scheme_menu(int *scheme_id = nullptr);
static std::string property_combox_data_type_;
enum _cbox_type
{
COMBO_VAL_STRING = 0,
COMBO_VAL_INT,
COMBO_VAL_FLOAT,
};
public:
explicit hg_settingdialog(SANEAPI* saneApi, SANE_Handle handle, const char *scanner_name, QWidget *parent = nullptr);
~hg_settingdialog();
public:
void initUi();
void updateOpt();
void createUI();
void updateUIStatus();
QVector<QWidget*> find_control(int opt_num);
void keyPressEvent(QKeyEvent *e);
int get_changed_items(void);
private:
SANEAPI m_saneAPI;
SANE_Handle m_devHandle;
private:
QString m_qstrFileName;
QSettings *m_configIniWrite;
QSettings *m_configIniRead;
private:
void iniWrite(QString title, int id, QVariant value);
void iniRead(QString title, int id, QWidget *w);
QString md5(QString key);
const void* find_option_description(int id); // return const SANE_Option_Descriptor* pointer
const void* find_option_description(const std::string& title, int* id); // return const SANE_Option_Descriptor* pointer
virtual void closeEvent(QCloseEvent* e);
bool createMsgBoxUi(bool add, std::string &name);
std::string getCurUiShemeName(std::string name);
void save_scheme(void);
void cancel_setting(void);
void getAppVersion();
void apply_current_scheme(void);
private:
QVector<QPair<QPair<int, QVariant>, QString>> m_list_IdValueTitle;
QVector<QPair<const void*, QVariant>> m_list_defaultOptions; // default values of device
QVector<QPair<QObject*, QObject*>> m_list_sliderSpinbox;
QVector<QPair<int, const void*>> m_list_getOpt;
QVector<std::string> m_list_deviceNames;
QVector<QWidget*> m_list_widgets;
private slots:
void slot_checkedClicked();
void slot_sliderClicked(int value);
void slot_spinBoxClicked(int value);
void slot_doubleSpinboxClicked(double value);
void slot_string_list_comboBoxClicked();
void slot_pushButtonClicked();
void slot_cutButtonClicked();
void slot_gammaButtonClicked();
void slot_word_list_comboBoxClicked(int value);
void slot_lineEditInput();
void slot_buttonOkClicked();
void slot_buttonCancelClicked();
void slot_pushButton_scheme_management(void);
void on_current_scheme_changed(void);
void restore_2_default_settings(void);
private:
int m_dpiId;
int m_dpiValue;
int m_paperSizeId;
QString m_paperSizeValue;
int m_cutLeftId;
int m_cutTopId;
int m_cutRightId;
int m_cutBottomId;
double m_cutWidth; // 单位是毫米
double m_cutHeight; // 单位是毫米
double m_cutLeftValue; // 单位是毫米
double m_cutTopValue; // 单位是毫米
double m_cutRightValue; // 单位是毫米
double m_cutBottomValue; // 单位是毫米
int m_colorModeId;
QString m_colorModeValue;
SANE_Gamma m_gammaData;
QComboBox *comb_;
};
#endif // HG_SETTING_DIALOG_H

View File

@ -0,0 +1,315 @@
#include "setpicclrtool.h"
#include "ui_setpicclrtool.h"
#include "widget.h"
#include <QDebug>
#include <QVariant>
setPicClrTool::setPicClrTool(QWidget *parent) :
QDialog(parent),
ui(new Ui::setPicClrTool)
{
ui->setupUi(this);
setMouseTracking(true);
ui->inputEdt->setEnabled(false);
ui->outputEdt->setEnabled(false);
ui->inputEdt->setValidator(new QIntValidator(0, 255, this));
ui->outputEdt->setValidator(new QIntValidator(0, 255, this));
ui->widget->setFocus(Qt::MouseFocusReason);
connect(ui->widget,SIGNAL(mouseCoordSig(QPoint)),this,SLOT(mouseCoordSlot(QPoint)));
connect(ui->widget,SIGNAL(dragPointChecked(bool)),this,SLOT(lineEditEnable(bool)));
connect(ui->widget,SIGNAL(lineChangeSig()),this,SLOT(lineChangeSlot()));
}
setPicClrTool::~setPicClrTool()
{
delete ui;
}
void setPicClrTool::getGrayTable(uchar *table, size_t length)
{
QVector<int> gray = getGrayALLPoint();
for (size_t i = 0; i < length; i++)
table[i] = static_cast<uchar>(gray[static_cast<int>(i)]);
}
void setPicClrTool::getRGBTable(uchar *table, size_t length)
{
if (length != 768)
throw "length is not 768.";
QVector<int> rgb = getRgbALLPoint();
QVector<int> red = getRedALLPoint();
QVector<int> green = getGreenALLPoint();
QVector<int> blue = getBlueALLPoint();
for (size_t i = 0; i < 256; i++)
{
//if (i == 255)
// int a = 0;
//table member order is B\G\R
table[i * 3 + 0] = static_cast<uchar>(blue[rgb[static_cast<int>(i)]]);
table[i * 3 + 1] = static_cast<uchar>(green[rgb[static_cast<int>(i)]]);
table[i * 3 + 2] = static_cast<uchar>(red[rgb[static_cast<int>(i)]]);
}
}
//void setPicClrTool::setGrayTable(const uchar *table, size_t length)
//{
// QVector<int> gray;
// for (size_t i = 0; i < length; i++)
// gray[static_cast<int>(i)] = int(table[i]);
// //ui->widget->setGrayALLPoint(gray);
//}
//void setPicClrTool::setRGBTable(const uchar *table, size_t length)
//{
// QVector<int> rgb;
// QVector<int> red;
// QVector<int> green;
// QVector<int> blue;
// for(int i = 0; i < 256; i++){
// rgb.append(i);
// }
// for (size_t i = 0; i < length; i++){
// red.append(int(table[i * 3 + 0]));
// green.append(int(table[i * 3 + 1]));
// blue.append(int(table[i * 3 + 2]));
// }
//}
void setPicClrTool::setColorMode(int colorMode)
{
QVariant v(6);
if(colorMode == 0)
{
ui->colorSetCmb->setItemData(1,v,Qt::UserRole - 1);
}
else
{
ui->comboBox->setItemData(2,v,Qt::UserRole - 1);
ui->colorSetCmb->setItemData(0,v,Qt::UserRole - 1);
ui->colorSetCmb->setItemData(2,v,Qt::UserRole - 1);
ui->colorSetCmb->setItemData(3,v,Qt::UserRole - 1);
ui->colorSetCmb->setItemData(4,v,Qt::UserRole - 1);
ui->colorSetCmb->setCurrentIndex(1);
}
}
QVector<QList<QPoint> > setPicClrTool::getRGBKeyTable()
{
QVector<QList<QPoint>> plv;
plv.append(getRgbKeyPoint());
plv.append(getRedKeyPoint());
plv.append(getGreenKeyPoint());
plv.append(getBlueKeyPoint());
return plv;
}
void setPicClrTool::setRGBKeyTable(QVector<QList<QPoint> > &plv)
{
setRgbKeyPoint(plv[0]);
setRedKeyPoint(plv[1]);
setGreenKeyPoint(plv[2]);
setBlueKeyPoint(plv[3]);
}
QList<QPoint> setPicClrTool::getGrayKeyTable()
{
return getGrayKeyPoint();
}
void setPicClrTool::setGrayKeyTable(QList<QPoint> &plv)
{
setGrayKeyPoint(plv);
}
QVector<int> setPicClrTool::getRgbALLPoint()
{
return ui->widget->getRgbALLPoint();
}
QList<QPoint> setPicClrTool::getRgbKeyPoint() const
{
qDebug() << "setRgb" << ui->widget->getRgbKeyPoint();
return ui->widget->getRgbKeyPoint();
}
void setPicClrTool::setRgbKeyPoint(const QList<QPoint> &pVec)
{
qDebug() << "setRgb" << pVec;
ui->widget->setRgbKeyPoint(pVec);
}
QList<QPoint> setPicClrTool::getRedKeyPoint() const
{
return ui->widget->getRedKeyPoint();
}
void setPicClrTool::setRedKeyPoint(const QList<QPoint> &pVec)
{
ui->widget->setRedKeyPoint(pVec);
}
QList<QPoint> setPicClrTool::getBlueKeyPoint() const
{
return ui->widget->getBlueKeyPoint();
}
void setPicClrTool::setBlueKeyPoint(const QList<QPoint> &pVec)
{
ui->widget->setBlueKeyPoint(pVec);
}
QList<QPoint> setPicClrTool::getGreenKeyPoint() const
{
return ui->widget->getGreenKeyPoint();
}
void setPicClrTool::setGreenKeyPoint(const QList<QPoint> &pVec)
{
ui->widget->setGreenKeyPoint(pVec);
}
QList<QPoint> setPicClrTool::getGrayKeyPoint() const
{
return ui->widget->getGrayKeyPoint();
}
void setPicClrTool::setGrayKeyPoint(const QList<QPoint> &pVec)
{
ui->widget->setGrayKeyPoint(pVec);
}
QVector<int> setPicClrTool::getRedALLPoint()
{
return ui->widget->getRedALLPoint();
}
QVector<int> setPicClrTool::getBlueALLPoint()
{
return ui->widget->getBlueALLPoint();
}
QVector<int> setPicClrTool::getGreenALLPoint()
{
return ui->widget->getGreenALLPoint();
}
QVector<int> setPicClrTool::getGrayALLPoint()
{
return ui->widget->getGrayALLPoint();
}
void setPicClrTool::mouseCoordSlot(QPoint pos)
{
ui->inputEdt->setText(QString::number(pos.x()));
ui->outputEdt->setText(QString::number(pos.y()));
}
void setPicClrTool::lineEditEnable(bool a)
{
ui->inputEdt->setEnabled(a);
ui->outputEdt->setEnabled(a);
}
void setPicClrTool::lineChangeSlot()
{
ui->comboBox->setCurrentIndex(0);
}
void setPicClrTool::on_colorSetCmb_currentIndexChanged(int index)
{
(void)index;
/* switch(index){
case RED:
ui->widget->updateCurLinePnt(RED);
break;
case GREEN:
ui->widget->updateCurLinePnt(GREEN);
break;
case BLUE:
ui->widget->updateCurLinePnt(BLUE);
break;
case RGB:
ui->widget->updateCurLinePnt(RGB);
break;
case GRAY:
ui->widget->updateCurLinePnt(GRAY);
break;
}*/
}
void setPicClrTool::on_comboBox_currentIndexChanged(int index)
{
if(index == 0){
ui->widget->initAllLstPnt();
ui->widget->updateCurLinePnt(ui->colorSetCmb->currentIndex());
return ;
}
ui->widget->initAllLstPnt();
if(index == 1){
rgbLine.clear();
rgbLine.append(QPoint(0,255));
rgbLine.append(QPoint(255,0));
ui->widget->setLstPnt_RGB(rgbLine);
}else if(index == 2){
redLine.clear();
redLine.append(QPoint(33,255));
redLine.append(QPoint(185,0));
redLine.append(QPoint(119,127));
greenLine.clear();
greenLine.append(QPoint(28,255));
greenLine.append(QPoint(132,0));
greenLine.append(QPoint(77,127));
blueLine.clear();
blueLine.append(QPoint(25,255));
blueLine.append(QPoint(108,0));
blueLine.append(QPoint(60,127));
ui->widget->setLstPnt_RED(redLine);
ui->widget->setLstPnt_GREEN(greenLine);
ui->widget->setLstPnt_BLUE(blueLine);
}else if(index == 4){
rgbLine.clear();
rgbLine.append(QPoint(0,0));
rgbLine.append(QPoint(255,255));
rgbLine.append(QPoint(103,125));
ui->widget->setLstPnt_RGB(rgbLine);
}else if(index == 3){
rgbLine.clear();
rgbLine.append(QPoint(0,0));
rgbLine.append(QPoint(255,255));
rgbLine.append(QPoint(130,101));
ui->widget->setLstPnt_RGB(rgbLine);
}
ui->widget->updateCurLinePnt(ui->colorSetCmb->currentIndex());
}
void setPicClrTool::on_inputEdt_textChanged(const QString &arg1)
{
ui->widget->setXCoorVal(arg1.toInt());
}
void setPicClrTool::on_outputEdt_textChanged(const QString &arg1)
{
ui->widget->setYCoorVal(arg1.toInt());
}
void setPicClrTool::on_pushButton_clicked()
{
ui->widget->initSelectColLine(ui->colorSetCmb->currentIndex());
}
void setPicClrTool::on_buttonBox_accepted()
{
//close();
accept();
}
void setPicClrTool::on_buttonBox_rejected()
{
ui->widget->initAllLstPnt();
//close();
reject();
}

View File

@ -0,0 +1,82 @@
#ifndef SETPICCLRTOOL_H
#define SETPICCLRTOOL_H
//#include "colorlinesetdef.h"
#include <QDialog>
namespace Ui {
class setPicClrTool;
}
class setPicClrTool : public QDialog
{
Q_OBJECT
public:
explicit setPicClrTool(QWidget *parent = nullptr);
~setPicClrTool();
void getGrayTable(uchar* table, size_t length = 256);
void getRGBTable(uchar* table, size_t length = 768);
// void setGrayTable(const uchar* table, size_t length = 256);
// void setRGBTable(const uchar* table, size_t length = 768);
void setColorMode(int colorMode);
QVector<QList<QPoint>> getRGBKeyTable();
void setRGBKeyTable(QVector<QList<QPoint>>& plv);
QList<QPoint> getGrayKeyTable();
void setGrayKeyTable(QList<QPoint> &plv);
private:
QVector<int> getRgbALLPoint();
QVector<int> getRedALLPoint();
QVector<int> getBlueALLPoint();
QVector<int> getGreenALLPoint();
QVector<int> getGrayALLPoint();
QList<QPoint> getRgbKeyPoint()const;
void setRgbKeyPoint(const QList<QPoint>& pVec);
QList<QPoint> getRedKeyPoint()const;
void setRedKeyPoint(const QList<QPoint>& pVec);
QList<QPoint> getBlueKeyPoint()const;
void setBlueKeyPoint(const QList<QPoint>& pVec);
QList<QPoint> getGreenKeyPoint()const;
void setGreenKeyPoint(const QList<QPoint>& pVec);
QList<QPoint> getGrayKeyPoint()const;
void setGrayKeyPoint(const QList<QPoint>& pVec);
private slots:
void mouseCoordSlot(QPoint);//set QLineEdit value by QPoint setting
void lineEditEnable(bool);//set 2 LineEdit enable status
void lineChangeSlot();
void on_colorSetCmb_currentIndexChanged(int index);
void on_comboBox_currentIndexChanged(int index);
void on_inputEdt_textChanged(const QString &arg1);
void on_outputEdt_textChanged(const QString &arg1);
void on_pushButton_clicked();
void on_buttonBox_accepted();
void on_buttonBox_rejected();
private:
Ui::setPicClrTool *ui;
QList<QPoint> linePoint;
QList<QPoint> greenLine;
QList<QPoint> redLine;
QList<QPoint> blueLine;
QList<QPoint> rgbLine;
QList<QPoint> grayLine;
};
#endif // SETPICCLRTOOL_H

View File

@ -0,0 +1,167 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>setPicClrTool</class>
<widget class="QWidget" name="setPicClrTool">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>259</width>
<height>341</height>
</rect>
</property>
<property name="windowTitle">
<string>自定义色调曲线</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,1,0,0">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QComboBox" name="comboBox">
<item>
<property name="text">
<string>自定义</string>
</property>
</item>
<item>
<property name="text">
<string>负片RGB</string>
</property>
</item>
<item>
<property name="text">
<string>彩色负片RGB</string>
</property>
</item>
<item>
<property name="text">
<string>较暗RGB</string>
</property>
</item>
<item>
<property name="text">
<string>较亮RGB</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="4,2,1">
<item>
<widget class="QComboBox" name="colorSetCmb">
<property name="mouseTracking">
<bool>false</bool>
</property>
<item>
<property name="text">
<string>RGB</string>
</property>
</item>
<item>
<property name="text">
<string>灰</string>
</property>
</item>
<item>
<property name="text">
<string>红</string>
</property>
</item>
<item>
<property name="text">
<string>蓝</string>
</property>
</item>
<item>
<property name="text">
<string>绿</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>初始化</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="Widget" name="widget" native="true">
<property name="mouseTracking">
<bool>true</bool>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>输入:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="inputEdt">
<property name="enabled">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>输出:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="outputEdt">
<property name="enabled">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Widget</class>
<extends>QWidget</extends>
<header location="global">widget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

855
modules/saneui/widget.cpp Normal file
View File

@ -0,0 +1,855 @@
#include "widget.h"
#include "ui_widget.h"
#include "gaosixy.h"
#include <iostream>
#include <QPainter>
#include <QVector>
#include <QDebug>
using namespace std;
enum COLOR_TPYE
{
RGB,
GRAY,
RED,
BLUE,
GREEN
};
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
setWindowTitle(tr("zuobiaozhou")); //设置标题栏标题
//resize(300,300); //设置窗口初始大小
//ui->table->setWindowFlags(Qt::WindowStaysOnTopHint);
initAllLstPnt();
initInterface();
}
Widget::~Widget()
{
delete ui;
}
void Widget::setLstPnt_RGB(const QList<QPoint> &plst)
{
rgbLine = QList<QPoint>(plst);
}
QList<QPoint> Widget::getLstPnt_RGB() const
{
return rgbLine;
}
void Widget::setLstPnt_RED(const QList<QPoint> &plst)
{
redLine = QList<QPoint>(plst);
}
void Widget::setLstPnt_BLUE(const QList<QPoint> &plst)
{
blueLine = QList<QPoint>(plst);
}
QList<QPoint> Widget::getLstPnt_BLUE() const
{
return blueLine;
}
void Widget::setLstPnt_GREEN(const QList<QPoint> &plst)
{
greenLine = QList<QPoint>(plst);
}
QList<QPoint> Widget::getLstPnt_GREEN() const
{
return greenLine;
}
void Widget::setLstPnt_GRAY(const QList<QPoint> &plst)
{
grayLine = QList<QPoint>(plst);
}
QList<QPoint> Widget::getLstPnt_GRAY() const
{
return grayLine;
}
QVector<int> Widget::getRgbALLPoint()
{
return rgbALLPoint;
}
QList<QPoint> Widget::getRgbKeyPoint() const
{
return rgbLine;
}
void Widget::setRgbKeyPoint(const QList<QPoint> &pLst)
{
if(pLst.size() > 4) return;
rgbLine = QList<QPoint>(pLst);
pointLst.clear();
pointLst = QList<QPoint>(rgbLine);
drawLineFromPoint(rgbLine, RGB);
update();
}
QVector<int> Widget::getRedALLPoint()
{
return redALLPoint;
}
QList<QPoint> Widget::getRedKeyPoint() const
{
return redLine;
}
void Widget::setRedKeyPoint(const QList<QPoint> &pLst)
{
if(pLst.size() > 4) return;
redLine = QList<QPoint>(pLst);
drawLineFromPoint(redLine, RED);
update();
}
QVector<int> Widget::getBlueALLPoint()
{
return blueALLPoint;
}
QList<QPoint> Widget::getBlueKeyPoint() const
{
return blueLine;
}
void Widget::setBlueKeyPoint(const QList<QPoint> &pLst)
{
if(pLst.size() > 4) return;
blueLine = QList<QPoint>(pLst);
drawLineFromPoint(blueLine, BLUE);
update();
}
QVector<int> Widget::getGreenALLPoint()
{
return greenALLPoint;
}
QList<QPoint> Widget::getGreenKeyPoint() const
{
return greenLine;
}
void Widget::setGreenKeyPoint(const QList<QPoint> &pLst)
{
if(pLst.size() > 4) return;
greenLine = QList<QPoint>(pLst);
drawLineFromPoint(greenLine, GREEN);
update();
}
QVector<int> Widget::getGrayALLPoint()
{
return grayALLPoint;
}
QList<QPoint> Widget::getGrayKeyPoint() const
{
return grayLine;
}
void Widget::setGrayKeyPoint(const QList<QPoint> &pLst)
{
if(pLst.size() > 4) return;
grayLine = QList<QPoint>(pLst);
pointLst.clear();
pointLst = QList<QPoint>(grayLine);
drawLineFromPoint(grayLine, GRAY);
update();
}
void Widget::initAllLstPnt()
{
pointLst.clear();
pointLst.append(QPoint(0,0));
pointLst.append(QPoint(255,255));
redLine.clear();
redLine.append(QPoint(0,0));
redLine.append(QPoint(255,255));
blueLine.clear();
blueLine.append(QPoint(0,0));
blueLine.append(QPoint(255,255));
greenLine.clear();
greenLine.append(QPoint(0,0));
greenLine.append(QPoint(255,255));
rgbLine.clear();
rgbLine.append(QPoint(0,0));
rgbLine.append(QPoint(255,255));
grayLine.clear();
grayLine.append(QPoint(0,0));
grayLine.append(QPoint(255,255));
drawLineFromPoint(redLine, RED);
drawLineFromPoint(rgbLine, RGB);
drawLineFromPoint(greenLine, GREEN);
drawLineFromPoint(blueLine, BLUE);
drawLineFromPoint(grayLine, GRAY);
}
void Widget::initInterface()
{
color = Qt::gray;
selectCol = RGB;
leftMouseMv = false;
newPoint = false;
clickLine = false;
dragPoint = -1;
setMouseTracking(true);
ui->widget_2->setStyleSheet("QWidget{background-color:qlineargradient("
"spread:pad, x1:0, y1:0, x2:1, y2:0, "
"stop:0 rgba(0, 0, 0, 255), stop:1 rgba(255, 255, 255, 255))}");
ui->widget->setStyleSheet("QWidget{background-color:qlineargradient("
"spread:pad, x1:0, y1:1, x2:0, y2:0, "
"stop:0 rgba(0, 0, 0, 255), stop:1 rgba(255, 255, 255, 255))}");
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing,true); //开启抗锯齿
painter.translate(ui->widget->width(),ui->widget->height()); //坐标系统平移变换,把原点平移
painter.scale(ui->table->width() / 258.0,ui->table->height() / 258.0); //坐标系统比例变换,使绘制的图形随窗口的放大而放大
painter.scale(1,-1);
drawCoordinate(painter);
drawBackColorBySlc(painter);
drawCoorScale(painter);
drawCurveByColor(painter);
drawAllPoint(painter);
if(dragPoint < 0){
setMouseTracking(true);
emit dragPointChecked(false);
}
painter.end();
}
void Widget::mousePressEvent(QMouseEvent *event)
{
int x = (event->x() - ui->widget->width())*258/ui->table->width();
int y = (height() - event->y()-ui->widget_2->height())*258/ui->table->height();
//qDebug() << x << y;
if(event->button() == Qt::LeftButton){
newPoint = false;
dragPoint = -1;
clickLine = false;
for(int i = 0; i < linePoint.size();i++){
int px = linePoint.at(i).x();
int py = linePoint.at(i).y();
if(qAbs(x-px) <= 6 && qAbs(y-py) <= 6)
{
newPoint = true;
for(int j = 0; j < pointLst.size(); j++){
int lx = pointLst.at(j).x();
int ly = pointLst.at(j).y();
if(qAbs(x-lx) <= 6 && qAbs(y-ly) <= 6){
dragPoint = j;
clickLine = true;
leftMouseMv = true;
newPoint = false;
emit dragPointChecked(true);
setMouseTracking(false);
update();
break;
}
}
if(newPoint && pointLst.size() < 4 && x > pointLst.at(0).x() && x < pointLst.at(1).x()){
pointLst.append(QPoint(x,y));
dragPoint = pointLst.size()-1;
leftMouseMv = true;
clickLine = true;
emit dragPointChecked(true);
setMouseTracking(false);
update();
}
}
}
}
else if(event->button() == Qt::RightButton){
for(int j = 0; j < pointLst.size(); j++){
int lx = pointLst.at(j).x();
int ly = pointLst.at(j).y();
if(qAbs(x-lx) <= 7 && qAbs(y-ly) <= 5){
if(j > 1)
pointLst.removeAt(j);
if(j == dragPoint){
dragPoint = -1;
emit dragPointChecked(false);
}else if(j > dragPoint){
dragPoint = dragPoint;
}else {
dragPoint = dragPoint-1;
}
update();
break;
}
}
}
if(!clickLine){
dragPoint = -1;
emit dragPointChecked(false);
setMouseTracking(true);
update();
}
emit mouseCoordSig(QPoint(x,y));
}
void Widget::mouseMoveEvent(QMouseEvent *event)
{
int x = (event->x() - ui->widget->width())*258/ui->table->width();
int y = (height() - event->y()-ui->widget_2->height())*258/ui->table->height();
if(x < 0) x = 0;
if(y < 0) y = 0;
if(x >= 255) x = 255;
if(y >= 255) y = 255;
//qDebug() << x << y;
if(leftMouseMv && dragPoint >= 0)
{
if(pointLst[dragPoint] != pointLst.at(0) && pointLst[dragPoint] != pointLst.at(1)){
if(x <= pointLst.at(0).x()) x = pointLst.at(0).x() + 1;
if(x >= pointLst.at(1).x()) x = pointLst.at(1).x() - 1;
if(pointLst.size() == 4){
if(dragPoint == 2){
if(pointLst[2].x() > pointLst[3].x() && x <= pointLst[3].x())
x = pointLst[3].x() + 1;
if(pointLst[2].x() < pointLst[3].x() && x >= pointLst[3].x())
x = pointLst[3].x() - 1;
}
else if(dragPoint == 3){
if(pointLst[2].x() < pointLst[3].x() && x <= pointLst[2].x())
x = pointLst[2].x() + 1;
if(pointLst[2].x() > pointLst[3].x() && x >= pointLst[2].x())
x = pointLst[2].x() - 1;
}
}
}
else if(pointLst[dragPoint] == pointLst.at(0)){
int min = 999;
for(int i = 1; i < pointLst.size(); i++){
if(min > pointLst[i].x()) min = pointLst[i].x();
}
if(x >= min) x = min-1;
}
else if(pointLst[dragPoint] == pointLst.at(1)){
if(pointLst.size() > 2){
int max = 0;
for(int i = 2; i < pointLst.size(); i++){
if(max < pointLst[i].x()) max = pointLst[i].x();
}
if(x <= max) x = max+1;
}
else if(pointLst.size() <= 2)
if(x <= pointLst.at(0).x()) x = pointLst.at(0).x()+1;
}
pointLst[dragPoint].setX(x);
pointLst[dragPoint].setY(y);
emit lineChangeSig();
update();
}
emit mouseCoordSig(QPoint(x,y));
}
void Widget::mouseReleaseEvent(QMouseEvent *)
{
leftMouseMv = false;
}
void Widget::enterEvent(QEvent *)
{
setFocus(Qt::MouseFocusReason);
}
void Widget::leaveEvent(QEvent *)
{
if(dragPoint < 0)
emit mouseLeaveSig();
}
void Widget::setHist_RGB(const QVector<int> &hist)
{
rgbBackColor = QVector<int>(hist);
}
QVector<int> Widget::getHist_RED() const
{
return redBackColor;
}
void Widget::setHist_RED(const QVector<int> &hist)
{
redBackColor = QVector<int>(hist);
}
QVector<int> Widget::getHist_RGB() const
{
return rgbBackColor;
}
void Widget::setHist_GREEN(const QVector<int> &hist)
{
greenBackColor = QVector<int>(hist);
}
QVector<int> Widget::getHist_GREEN() const
{
return greenBackColor;
}
void Widget::setHist_BLUE(const QVector<int> &hist)
{
blueBackColor = QVector<int>(hist);
}
QVector<int> Widget::getHist_BLUE() const
{
return blueBackColor;
}
void Widget::setHist_GRAY(const QVector<int> &hist)
{
grayBackColor = QVector<int>(hist);
}
QVector<int> Widget::getHist_GRAY() const
{
return grayBackColor;
}
void Widget::drawCoordinate(QPainter &painter)
{
painter.setBrush(QColor(79,79,79));
painter.drawRect(0, 0, 260, 260);
painter.drawLine(-2000,0,2000,0);
painter.drawLine(0,1500,0,-1500);
}
void Widget::drawBackgroudColor(QPainter &painter,QVector<int> &curCol)
{
painter.setPen(QPen(color,1));
painter.setBrush(color);
int max = 0;
for(int i = 0; i < curCol.size(); i++)
{
if(curCol.at(i) > max)
{
max = curCol.at(i);
}
}
for(int i = 0; i < curCol.size(); i++)
{
painter.drawRect(i, 0, 1, curCol.at(i)*255/max);
}
}
void Widget::drawBackColorBySlc(QPainter &painter)
{
switch(selectCol){
case RGB:
drawBackgroudColor(painter,rgbBackColor);
break;
case GREEN:
drawBackgroudColor(painter,greenBackColor);
break;
case BLUE:
drawBackgroudColor(painter,blueBackColor);
break;
case RED:
drawBackgroudColor(painter,redBackColor);
break;
case GRAY:
drawBackgroudColor(painter,grayBackColor);
break;
}
}
void Widget::drawCoorScale(QPainter &painter)
{
painter.setPen(QPen(Qt::gray,1));
for(int i = 0; i < 260 ; i+=50)
{
if(i%50 == 0 && i >=50)
{
QVector<qreal> dashes;
qreal space = 3;
dashes << 5 << space << 5 <<space;
QPen pen;
pen.setDashPattern(dashes);
pen.setWidth(1);
painter.setPen(pen);
painter.drawLine(i,300,i,0);
painter.drawLine(0,i,300,i);
}
}
QLine line(0,0,255,255);
painter.drawLine(line);
}
void Widget::drawLineFromPoint(QList<QPoint> &plst, const int& col)
{
double **a;
int len = plst.size();
a = new double *[len];
for(int i = 0; i < len; i++){
a[i] = new double[len+1];
}
/*******通过pointLst的所有点给二维数组赋值生成行列式*******/
for(int i = 0; i < len; i++){
for(int j = 0;j < len + 1; j++){
if(j < len)
a[i][j] = caculateAllMi(plst.at(i).x(),len-j-1);
if(j == len)
a[i][j] = plst.at(i).y();
}
}
/*******调用高斯消元法计算曲线方程的系数值********/
GaoSiXY gaoSi;
double *result = new double[len] ;
gaoSi.solve(a,len,result);
/********保存曲线方程 x 的系数(a,b,c,d....)********/
QList<double> xiNum;
for(int i = 0; i < len; i++){
xiNum.append(*(result+i));
}
linePoint.clear();
linePoints.clear();
for(int i = 0; i < 256; i++){
int x = i;
double yVal = 0;
for(int j = 0; j < len; j++){
yVal += xiNum.at(j)*caculateAllMi(x,len-j-1);
}
int y = (int)yVal;
if(y > 255) y = 255;
if(y < 0) y = 0;
if(x < plst.at(0).x()) y = plst.at(0).y();
if(x > plst.at(1).x()) y = plst.at(1).y();
allLinePoints[x] = y;
linePoints.append(y);
linePoint.append(QPoint(x,y));
}
if(col == RED){
redALLPoint.clear();
for(int i = 0; i < linePoint.size(); i++)
redALLPoint.append(linePoint.at(i).y());
}
if(col == GREEN){
greenALLPoint.clear();
for(int i = 0; i < linePoint.size(); i++)
greenALLPoint.append(linePoint.at(i).y());
}
if(col == BLUE){
blueALLPoint.clear();
for(int i = 0; i < linePoint.size(); i++)
blueALLPoint.append(linePoint.at(i).y());
}
if(col == GRAY){
grayALLPoint.clear();
for(int i = 0; i < linePoint.size(); i++)
grayALLPoint.append(linePoint.at(i).y());
}
if(col == RGB){
rgbALLPoint.clear();
for(int i = 0; i < linePoint.size(); i++)
{
rgbALLPoint.append(linePoint.at(i).y());
}
}
for(int i = 0;i < len; i++){
delete[] a[i];
}
delete []a;
}
void Widget::drawAllPoint(QPainter &painter)
{
if(pointLst.size() > 0)
{
painter.setPen(QPen(Qt::white,1));
painter.setBrush(Qt::white);
for(int i = 0; i < pointLst.size(); i++){
painter.drawEllipse(pointLst.at(i),3,3);
}
if(dragPoint >= 0){
painter.setPen(QPen(QColor(0, 245, 255),2));
painter.drawEllipse(pointLst[dragPoint],4,4);
}
}
if(selectCol == GREEN){
greenLine.clear();
greenLine = QList<QPoint>(pointLst);
}
else if(selectCol == RED){
redLine.clear();
redLine = QList<QPoint>(pointLst);
}else if(selectCol == BLUE){
blueLine.clear();
blueLine = QList<QPoint>(pointLst);
}else if(selectCol == RGB){
rgbLine.clear();
rgbLine = QList<QPoint>(pointLst);
}else if(selectCol == GRAY){
grayLine.clear();
grayLine = QList<QPoint>(pointLst);
}
}
void Widget::drawCurveByColor(QPainter &painter)
{
qDebug() << selectCol;
switch (selectCol) {
case RGB:
painter.setPen(QPen(Qt::white,1));
drawLineFromPoint(rgbLine, RGB);
drawLineByVector(painter,rgbALLPoint);
if(redLine.size()>2 || redLine.at(0)!= QPoint(0,0) || redLine.at(1)!= QPoint(255,255)){
painter.setPen(QPen(Qt::red,1));
drawLineFromPoint(redLine,RED);
drawLineByVector(painter,redALLPoint);
}
if(blueLine.size()>2 || blueLine.at(0)!= QPoint(0,0) || blueLine.at(1)!= QPoint(255,255)){
painter.setPen(QPen(Qt::blue,1));
drawLineFromPoint(blueLine, BLUE);
drawLineByVector(painter,blueALLPoint);
}
if(greenLine.size()>2 || greenLine.at(0)!= QPoint(0,0) || greenLine.at(1)!= QPoint(255,255)){
painter.setPen(QPen(Qt::green,1));
drawLineFromPoint(greenLine, BLUE);
drawLineByVector(painter,greenALLPoint);
}
break;
case RED:
painter.setPen(QPen(Qt::red,1));
drawLineFromPoint(redLine,RED);
drawLineByVector(painter,redALLPoint);
break;
case BLUE:
painter.setPen(QPen(Qt::blue,1));
drawLineFromPoint(blueLine, BLUE);
drawLineByVector(painter,blueALLPoint);
break;
case GREEN:
painter.setPen(QPen(Qt::green,1));
drawLineFromPoint(greenLine, GREEN);
drawLineByVector(painter,greenALLPoint);
break;
case GRAY:
painter.setPen(QPen(Qt::white,1));
drawLineFromPoint(grayLine, GRAY);
drawLineByVector(painter,grayALLPoint);
break;
default:
break;
}
drawLineFromPoint(pointLst, -1);
}
void Widget::drawLineByVector(QPainter &painter,QVector<int> &pVec)
{
for(int i = 0; i < pVec.size()-1; i++){
painter.drawLine(QPoint(i,pVec.at(i)),QPoint(i+1,pVec.at(i+1)));
}
update();
}
int Widget::caculateAllMi(int num, int n)
{
int val = 1;
if(n == 0) return 1;
for(int i = 0; i < n; i++){
val *= num;
}
return val;
}
void Widget::getCurLineLUT(uchar *table, size_t length)
{
for(size_t i = 0; i < length; i++)
{
table[i] = allLinePoints[i];
}
}
QVector<unsigned char> Widget::getCurLinePntVec()
{
return linePoints;
}
void Widget::updateCurLinePnt(const int& colType)
{
dragPoint = -1;
selectCol = colType;
if(selectCol == GREEN){
color = QColor(202, 255, 112);
pointLst.clear();
pointLst = QList<QPoint>(greenLine);
ui->widget_2->setStyleSheet("QWidget{background-color:qlineargradient("
"spread:pad, x1:0, y1:0, x2:1, y2:0, "
"stop:0 rgba(0, 0, 0, 255), stop:1 rgba(0, 255, 0, 255))}");
ui->widget->setStyleSheet("QWidget{background-color:qlineargradient("
"spread:pad, x1:0, y1:1, x2:0, y2:0, "
"stop:0 rgba(0, 0, 0, 255), stop:1 rgba(0, 255, 0, 255))}");
}else if(selectCol == BLUE){
color = QColor(131, 111, 255);
pointLst.clear();
pointLst = QList<QPoint>(blueLine);
ui->widget_2->setStyleSheet("QWidget{background-color:qlineargradient("
"spread:pad, x1:0, y1:0, x2:1, y2:0, "
"stop:0 rgba(0, 0, 0, 255), stop:1 rgba(0, 0, 255, 255))}");
ui->widget->setStyleSheet("QWidget{background-color:qlineargradient("
"spread:pad, x1:0, y1:1, x2:0, y2:0, "
"stop:0 rgba(0, 0, 0, 255), stop:1 rgba(0, 0, 255, 255))}");
}else if(selectCol == RED){
color = QColor(255, 160, 122);
pointLst.clear();
pointLst = QList<QPoint>(redLine);
ui->widget_2->setStyleSheet("QWidget{background-color:qlineargradient("
"spread:pad, x1:0, y1:0, x2:1, y2:0, "
"stop:0 rgba(0, 0, 0, 255), stop:1 rgba(255, 0, 0, 255))}");
ui->widget->setStyleSheet("QWidget{background-color:qlineargradient("
"spread:pad, x1:0, y1:1, x2:0, y2:0, "
"stop:0 rgba(0, 0, 0, 255), stop:1 rgba(255, 0, 0, 255))}");
}else if(selectCol == GRAY){
color = Qt::gray;
pointLst.clear();
pointLst = QList<QPoint>(grayLine);
ui->widget_2->setStyleSheet("QWidget{background-color:qlineargradient("
"spread:pad, x1:0, y1:0, x2:1, y2:0, "
"stop:0 rgba(0, 0, 0, 255), stop:1 rgba(255, 255, 255, 255))}");
ui->widget->setStyleSheet("QWidget{background-color:qlineargradient("
"spread:pad, x1:0, y1:1, x2:0, y2:0, "
"stop:0 rgba(0, 0, 0, 255), stop:1 rgba(255, 255, 255, 255))}");
}else if(selectCol == RGB){
color = Qt::gray;
pointLst.clear();
pointLst = QList<QPoint>(rgbLine);
ui->widget_2->setStyleSheet("QWidget{background-color:qlineargradient("
"spread:pad, x1:0, y1:0, x2:1, y2:0, "
"stop:0 rgba(0, 0, 0, 255), stop:1 rgba(255, 255, 255, 255))}");
ui->widget->setStyleSheet("QWidget{background-color:qlineargradient("
"spread:pad, x1:0, y1:1, x2:0, y2:0, "
"stop:0 rgba(0, 0, 0, 255), stop:1 rgba(255, 255, 255, 255))}");
}
update();
}
void Widget::setXCoorVal(const int &xVal)
{
if(dragPoint >= 0){
int x = xVal;
if(pointLst[dragPoint] != pointLst.at(0) && pointLst[dragPoint] != pointLst.at(1)){
if(pointLst.size() == 3 && x > pointLst.at(0).x() && x < pointLst.at(1).x())
pointLst[dragPoint].setX(x);
if(pointLst.size() == 4){
if(dragPoint == 2){
if(pointLst[2].x() > pointLst[3].x() && x > pointLst[3].x() && x < pointLst[1].x())
pointLst[dragPoint].setX(x);
if(pointLst[2].x() < pointLst[3].x() && x < pointLst[3].x() && x > pointLst[0].x())
pointLst[dragPoint].setX(x);
}
else if(dragPoint == 3){
if(pointLst[2].x() < pointLst[3].x() && x > pointLst[2].x() && x < pointLst[1].x())
pointLst[dragPoint].setX(x);
if(pointLst[2].x() > pointLst[3].x() && x < pointLst[2].x() && x > pointLst[0].x())
pointLst[dragPoint].setX(x);
}
}
}
else if(pointLst[dragPoint] == pointLst.at(0)){
int min = 999;
for(int i = 1; i < pointLst.size(); i++){
if(min > pointLst[i].x()) min = pointLst[i].x();
}
if(x < min) pointLst[dragPoint].setX(x);
}
else if(pointLst[dragPoint] == pointLst.at(1)){
if(pointLst.size() > 2){
int max = 0;
for(int i = 2; i < pointLst.size(); i++){
if(max < pointLst[i].x()) max = pointLst[i].x();
}
if(x > max) pointLst[dragPoint].setX(x);
}
else if(pointLst.size() <= 2)
if(x > pointLst.at(0).x()) pointLst[dragPoint].setX(x);
}
update();
}
}
void Widget::setYCoorVal(const int &yVal)
{
if(dragPoint >= 0){
pointLst[dragPoint].setY(yVal);
update();
}
}
void Widget::initSelectColLine(const int& colType)
{
pointLst.clear();
pointLst.append(QPoint(0,0));
pointLst.append(QPoint(255,255));
switch(colType){
case RED:
redLine.clear();
redLine.append(QPoint(0,0));
redLine.append(QPoint(255,255));
break;
case BLUE:
blueLine.clear();
blueLine.append(QPoint(0,0));
blueLine.append(QPoint(255,255));
break;
case GREEN:
greenLine.clear();
greenLine.append(QPoint(0,0));
greenLine.append(QPoint(255,255));
break;
case GRAY:
grayLine.clear();
grayLine.append(QPoint(0,0));
grayLine.append(QPoint(255,255));
break;
case RGB:
initAllLstPnt();
break;
}
dragPoint = -1;
leftMouseMv = false;
newPoint = false;
clickLine = false;
setMouseTracking(true);
qDebug() << "init";
updateCurLinePnt(colType);
}
void Widget::SetAllLinePnt(QVector<int> &all)
{
allLinePntSet = QVector<int>(all);
}

132
modules/saneui/widget.h Normal file
View File

@ -0,0 +1,132 @@
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QMouseEvent>
//#include "colorlinesetdef.h"
namespace Ui {
class Widget;
}
//
//enum COLOR_TPYE
//{
// RGB,
// GRAY,
// RED,
// BLUE,
// GREEN
//};
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
void initAllLstPnt(); //初始化所有颜色曲线
void setLstPnt_RGB(const QList<QPoint>& plst); //设置生成RGB曲线的关键点<=4)
QList<QPoint> getLstPnt_RGB()const; //获取生成RGB曲线的关键点
void setLstPnt_RED(const QList<QPoint>& plst);
QList<QPoint> getLstPnt_RED()const;
void setLstPnt_BLUE(const QList<QPoint>& plst);
QList<QPoint> getLstPnt_BLUE()const;
void setLstPnt_GREEN(const QList<QPoint>& plst);
QList<QPoint> getLstPnt_GREEN()const;
void setLstPnt_GRAY(const QList<QPoint>& plst);
QList<QPoint> getLstPnt_GRAY()const;
QVector<int> getRgbALLPoint();
QList<QPoint> getRgbKeyPoint()const;
void setRgbKeyPoint(const QList<QPoint>& pVec);
QVector<int> getRedALLPoint();
QList<QPoint> getRedKeyPoint()const;
void setRedKeyPoint(const QList<QPoint>& pVec);
QVector<int> getBlueALLPoint();
QList<QPoint> getBlueKeyPoint()const;
void setBlueKeyPoint(const QList<QPoint>& pVec);
QVector<int> getGreenALLPoint();
QList<QPoint> getGreenKeyPoint()const;
void setGreenKeyPoint(const QList<QPoint>& pVec);
QVector<int> getGrayALLPoint();
QList<QPoint> getGrayKeyPoint()const;
void setGrayKeyPoint(const QList<QPoint>& pVec);
void setHist_RGB(const QVector<int>& hist);//设置RGB的背景直方图
QVector<int> getHist_RGB()const;//获取RGB的背景直方图
void setHist_RED(const QVector<int>& hist);
QVector<int> getHist_RED()const;
void setHist_BLUE(const QVector<int>& hist);
QVector<int> getHist_BLUE()const;
void setHist_GREEN(const QVector<int>& hist);
QVector<int> getHist_GREEN()const;
void setHist_GRAY(const QVector<int>& hist);
QVector<int> getHist_GRAY()const;
void getCurLineLUT(uchar* table, size_t length = 256);//获取当前曲线上的所有点并存入table
QVector<unsigned char> getCurLinePntVec();//获取当前曲线上的所有点
void setXCoorVal(const int &xVal);//设置被选中的点的X坐标
void setYCoorVal(const int &yVal);//设置被选中的点的Y坐标
void updateCurLinePnt(const int& colType);//根据当前所选颜色colType重绘界面
void initSelectColLine(const int& colType);//初始化当前所选颜色colType界面的曲线
void SetAllLinePnt(QVector<int>& all);//设置自定义曲线的所有点
signals:
void dragPointChecked(bool);//曲线上的点被选中的信号
void mouseLeaveSig();//鼠标离开控件的信号
void mouseCoordSig(QPoint pos);//鼠标的坐标信号
void lineChangeSig();
private:
void initInterface();//初始化界面
void paintEvent(QPaintEvent *);
void mousePressEvent(QMouseEvent*);
void mouseMoveEvent(QMouseEvent*);
void mouseReleaseEvent(QMouseEvent*);
void enterEvent(QEvent*);
void leaveEvent(QEvent*);
void drawCoordinate(QPainter&);//画直角坐标
void drawBackgroudColor(QPainter&,QVector<int>&);//画背景直方图
void drawBackColorBySlc(QPainter&);//画不同的背景直方图
void drawCoorScale(QPainter&);//画虚线刻度
void drawLineFromPoint(QList<QPoint> &plst, const int &col);//根据多点求出曲线方程,并画出曲线
void drawAllPoint(QPainter&);//画出生成曲线的关键点
void drawCurveByColor(QPainter&);//画不同的颜色曲线
void drawLineByVector(QPainter&,QVector<int>&);//将数组的所有点连接绘制曲线
int caculateAllMi(int num,int n);//计算num的n次方的值
private:
Ui::Widget *ui;
QVector<int> rgbBackColor;
QVector<int> redBackColor;
QVector<int> blueBackColor;
QVector<int> greenBackColor;
QVector<int> grayBackColor;
QVector<int> rgbALLPoint;
QVector<int> redALLPoint;
QVector<int> blueALLPoint;
QVector<int> greenALLPoint;
QVector<int> grayALLPoint;
QVector<int> allLinePntSet;
QVector<unsigned char> linePoints;
//QList<QPoint> points;
QList<QPoint> pointLst;
QList<QPoint> linePoint;
QList<QPoint> greenLine;
QList<QPoint> redLine;
QList<QPoint> blueLine;
QList<QPoint> rgbLine;
QList<QPoint> grayLine;
QColor color;
unsigned char allLinePoints[256];
bool leftMouseMv;
bool newPoint;
bool clickLine;
int dragPoint;
int selectCol;
};
#endif // WIDGET_H

91
modules/saneui/widget.ui Normal file
View File

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>556</width>
<height>484</height>
</rect>
</property>
<property name="windowTitle">
<string>Widget</string>
</property>
<layout class="QGridLayout" name="gridLayout" rowstretch="50,1" columnstretch="1,50">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QWidget" name="widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="mouseTracking">
<bool>true</bool>
</property>
<property name="focusPolicy">
<enum>Qt::WheelFocus</enum>
</property>
<property name="styleSheet">
<string notr="true">QWidget{background-color:qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgba(0, 0, 0, 255), stop:1 rgba(255, 255, 255, 255))}</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QWidget" name="table" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="mouseTracking">
<bool>true</bool>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QWidget" name="widget_2" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QWidget{background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 0, 0, 255), stop:1 rgba(255, 255, 255, 255))}</string>
</property>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>