logplus/qtpropertybrowser/qtColorSchemeComboBox.cpp

565 lines
17 KiB
C++

/*
* QtColorSchemeComboBox.cpp
*
* Created on: 2013-5-27
* Author: long
*/
#include <QPainter>
#include <stdio.h>
#include <QDir>
#include <QSettings>
#include <QCoreApplication>
#include "qtColorSchemeComboBox.h"
QtColorSchemeComboBox::QtColorSchemeComboBox(QWidget *parent):QtComboBox(parent), m_isShowText(true)
{
m_colorSchemeList.clear();
}
QtColorSchemeComboBox::~QtColorSchemeComboBox()
{
freeColorScheme();
}
void QtColorSchemeComboBox::ShowText(bool showText)
{
m_isShowText = showText;
if(m_isShowText)
{
setMinimumWidth(140);
}
else
{
setMinimumWidth(40);
setMaximumWidth(44);
}
}
void QtColorSchemeComboBox::setSchemeColor(const QList<QtSchemeColor > &schemeList)
{
freeColorScheme();
for(int i=0;i<schemeList.count();i++)
{
m_colorSchemeList.push_back(schemeList[i]);
}
clear();
for(int i=0;i<m_colorSchemeList.count();i++)
{
QPixmap pixmap=getColorLabelPixmap(m_colorSchemeList[i].colorList,m_colorSchemeList[i].colorList.count());
QString name;
if(m_isShowText)
{
name = m_colorSchemeList[i].schemeName;
}
addItem(QIcon(pixmap),name);
}
}
QPixmap QtColorSchemeComboBox::getColorLabelPixmap(const QVector<QtColorItem> &colorList,int colorNumber)
{
int w=64,h=32;
QPixmap pixmap(w,h);
QBrush brush(QColor(255,0,0));
pixmap.fill(QColor(255,0,0));
//QVector<QtColorItem> newColorList=paiInpolation(colorList,colorNumber);
QPainter painter;
painter.begin(&pixmap);
float colorStep = colorNumber * 1. / w;
QPen Pen;
for (int x = 0; x < w; x++)
{
// 色标位置
int clrIndex = (int) ((x) * colorStep);
if(colorList.size()<=x) break;
Pen.setColor(QColor(colorList[clrIndex].color));
painter.setPen(Pen);
painter.drawLine(x, 0, x, h-1);
}
painter.end();
return pixmap;
}
void QtColorSchemeComboBox::freeColorScheme()
{
m_colorSchemeList.clear();
}
QVector<QtColorItem> paiInpolation(const QVector<QtColorItem> &colorList,int totalColorNum)
{
QVector<QtColorItem> newColorList;
if (totalColorNum <= 1)
totalColorNum = 2;
// 填充新的颜色项目
for(int i=0;i<totalColorNum;i++)
newColorList.push_back(QtColorItem());
float gap=(colorList.count()-1)*1.0/(totalColorNum-1);
for(int i=0;i<totalColorNum;i++)
{
float pos=i*gap;
int index1=pos;
if(::fabs(pos-index1)<1.0e-10)
{
newColorList[i]=colorList[index1];
}
else
{
int index2=index1+1;
if(index2>=colorList.size()) index2=colorList.size()-1;
float flgap1=pos-index1;
float flgap2=index2-pos;
int r=colorList[index1].color.red()*flgap2+colorList[index2].color.red()*flgap1;
int g=colorList[index1].color.green()*flgap2+colorList[index2].color.green()*flgap1;
int b=colorList[index1].color.blue()*flgap2+colorList[index2].color.blue()*flgap1;
newColorList[i]=QtColorItem(QColor(r,g,b));
}
}
return newColorList;
}
bool readColorPaletteSetting(QList<QtSchemeColor > &schemeList,const QString &orignaName,const QString &moduleName)
{
schemeList.clear();
// 读取颜色设置
QString orgName=orignaName;
if(orgName.isEmpty())
{
orgName=gOrignizationName;
}
QString softName=moduleName;
if(softName.isEmpty())
softName="General Color Schema";
QSettings settings(orgName, softName);
QString aa=settings.fileName();
// 读取自定义的颜色方案
QVariant v = settings.value(gSchemeNumKey);
int schemeNum=0;
if(!v.isValid())
{
return false;
}
schemeNum=v.toUInt();
// 循环读取颜色方案
QVector<QtColorItem> colorLis;
for(int i=0;i<schemeNum;i++)
{
// 读取颜色方案名称
char szIndex[12];
sprintf(szIndex,"%02d",(i+1));
QString customName=gOneSchemeNameKey+szIndex;
settings.beginGroup(customName);
// 读取控制颜色数目
v =settings.value(gOneSchemeControlColorNumKey);
if(!v.isValid())
{
settings.endGroup();
continue;
}
int controlNum=v.toUInt();;
// 读取每个颜色的序号
colorLis.clear();
QtColorItem item;
for(int i=0;i<controlNum;i++)
{
QString name=gOneSchemeColorKey + QString::number(i);
QVariantList list = settings.value(name).toList();
if(list.size()!=2)
{
printf("too bad not valid\n");
settings.endGroup();
continue;
}
item.color=list[0].value<QColor>();
item.strComments=list[1].toString();
colorLis.push_back(item);
}
QtSchemeColor schemeItem;
schemeItem.schemeName=customName;
schemeItem.isCustom=true;
schemeItem.isDirty=false;
schemeItem.colorList=colorLis;
schemeItem.currentIndex=0;
schemeList.push_back(schemeItem);
settings.endGroup();
}
return true;
}
int getPaiSystemColorNumber(QStringList &names)
{
QString strImagePath;
QString strPathTmp = QCoreApplication::applicationDirPath() + QDir::separator();
strImagePath = QDir::toNativeSeparators( strPathTmp );
QString filecfg=strImagePath+"image"+QDir::separator()+"colortable"+QDir::separator()+"colortable.cfg";
FILE *fp1=fopen(filecfg.toStdString().c_str(),"rt");
if(!fp1) return -1;
char buf[100];
QString str;
int i=0;
while(!feof(fp1)) {
fscanf(fp1,"%s",buf);
str=buf;
if(str.indexOf("custom",Qt::CaseInsensitive)>=0) continue;
names.push_back(str);
i++;
}
fclose(fp1);
return i;
}
int getPaiSystemColor(int nIndex,QVector<QtColorItem> &colorList,bool inpolation)
{
colorList.clear();
QtColorItem itemColor;
QString strImagePath;
QString strPathTmp = QCoreApplication::applicationDirPath() + QDir::separator();
strImagePath = QDir::toNativeSeparators( strPathTmp );
QString filecfg=strImagePath+"image"+QDir::separator()+"colortable"+QDir::separator()+"colortable.cfg";
FILE *fp1=fopen(filecfg.toStdString().c_str(),"rt");
if(!fp1) return -1;
char buf[100];
QString str;
int i=0;
while(!feof(fp1)) {
fscanf(fp1,"%s",buf);
if(i>=nIndex) {
str=buf;
break;
}
i++;
}
fclose(fp1);
if(str.isEmpty()) return -1;
QString filename=strImagePath+"image"+QDir::separator()+"colortable"+QDir::separator()+str;
FILE *fp=fopen(filename.toStdString().c_str(),"rt");
if(!fp) return -1;
float r,g,b;
QStringList strs;
int colornum=0;
while(!feof(fp)) {
char *ret=fgets(buf,100,fp);
if(!ret) break;
str=buf;
str.replace("\r","");
str.replace("\n","");
str.replace("\t"," ");
if(str.indexOf("#")>-1) continue;
if(str.indexOf("=")>-1) continue;
if(str.indexOf("R",Qt::CaseInsensitive)>-1) continue;
if(str.indexOf("G",Qt::CaseInsensitive)>-1) continue;
if(str.indexOf("B",Qt::CaseInsensitive)>-1) continue;
strs=str.split(" ");
strs.removeAll("");
if(strs.size()!=3) continue;
r=strs[0].toFloat();
g=strs[1].toFloat();
b=strs[2].toFloat();
if(g<=1||b<=1) if(r>0&&r<=1) r*=255;
if(r<=1||b<=1) if(g>0&&g<=1) g*=255;
if(r<=1||g<=1) if(b>0&&b<=1) b*=255;
int rr=r,gg=g,bb=b;
colorList.push_back(QtColorItem(QColor(rr,gg,bb)));
colornum++;
}
fclose(fp);
if(colornum<PAITOTALCOLOR_MIN) colornum=PAITOTALCOLOR_MIN; // 最小总颜色数目
if(colornum>PAITOTALCOLOR_MAX) colornum=PAITOTALCOLOR_MAX; // 最大总颜色数目
if(inpolation)
{
colorList=paiInpolation(colorList,colornum);//SYSTEM_INPOLATION);
}
return colorList.count();
}
QtColorTableData *QtColorTableData::getInstance()
{
static QtColorTableData ref("Color Scheme", true);
return &ref;
}
bool QtColorTableData::LoadScheme(bool IsReLoad)
{
if(!IsReLoad&&m_SharedMemory.isAttached()) {
if(m_SharedMemory.key()!=m_modulName) {
m_SharedMemory.detach();
m_SharedMemory.setKey(m_modulName);
m_SharedMemory.attach();
}
int s=m_SharedMemory.size();
if(m_SharedMemory.isAttached()&&s) {
m_colorSchemeList.clear();
char *buffer=(char*)m_SharedMemory.data();
int size=*(int*)buffer;
for(int i=0;i<size;i++) {
QtSchemeColor cl;
QtScheme_Color sc;
memmove(&sc,&buffer[4]+i*sizeof(QtScheme_Color),sizeof(QtScheme_Color));
cl.isCustom=sc.isCustom;
cl.isDirty=sc.isDirty;
cl.currentIndex=sc.currentIndex;
cl.isCustom=sc.isCustom;
cl.schemeName=sc.schemeName;
for(int j=0;j<sc.size;j++) {
QtColorItem item;
item.color=sc.colorList[j].color;
item.fromValue=sc.colorList[j].fromValue;
item.toValue=sc.colorList[j].toValue;
item.strComments=sc.colorList[j].strComments;
cl.colorList.push_back(item);
}
m_colorSchemeList.push_back(cl);
}
m_systemShcemeNum=size;
return true;
}
}
if(m_isSettingSysColor)
{
m_colorSchemeList.clear();
m_colorSchemeList=m_systemSchemeList;
}
else
{
FreeColorScheme();
// 首先加载系统颜色方案
QStringList names;
m_systemShcemeNum=getPaiSystemColorNumber(names);
int k=0;
for(int i=0;i<m_systemShcemeNum;i++)
{
//char szIndex[12];
//sprintf(szIndex,"%02d",(i+1));
QString name=names[i];//QObject::tr("System ")+" "+szIndex;
int pos=name.lastIndexOf("\\");
name=name.mid(pos+1);
pos=name.lastIndexOf(".rgb",-1,Qt::CaseInsensitive);
if(pos>-1)name=name.mid(0,pos);
QVector<QtColorItem> colorList;
int ret=getPaiSystemColor(i,colorList,m_polatationSystemColor);
if(ret<=0) continue;
k++;
// 构建颜色方案表
QtSchemeColor schemeItem;
schemeItem.schemeName=name;
schemeItem.colorList=colorList;
schemeItem.isDirty=false;
schemeItem.isCustom=false;
schemeItem.currentIndex=0;
m_colorSchemeList.push_back(schemeItem);
// 对于系统颜色方案,单独生成备份
m_systemSchemeList.push_back(schemeItem);
}
m_systemShcemeNum=k;
}
// 读取定制的颜色方案
ReadSettings();
if(m_currentSchemIndex<0 || m_currentSchemIndex>=m_colorSchemeList.count())
{
m_currentSchemIndex=0;
}
for(int i=0;i<m_colorSchemeList.count();i++)
{
ChangeDataRange(&m_colorSchemeList[i]);
}
if(m_SharedMemory.key()!=m_modulName)
{
m_SharedMemory.setKey(m_modulName);
}
{
if(m_SharedMemory.isAttached()) m_SharedMemory.detach();
m_SharedMemory.create(sizeof(QtScheme_Color)*m_colorSchemeList.size()+sizeof(int));
if(!m_SharedMemory.isAttached()) m_SharedMemory.attach();
char *buffer=(char*)m_SharedMemory.data();
*(int *)buffer=m_colorSchemeList.size();
int size=m_colorSchemeList.size();
for(int i=0;i<size;i++) {
QtScheme_Color sc;
memset(&sc,0,sizeof(QtScheme_Color));
sc.isCustom=m_colorSchemeList[i].isCustom;
sc.isDirty=m_colorSchemeList[i].isDirty;
sc.currentIndex=m_colorSchemeList[i].currentIndex;
sc.isCustom=m_colorSchemeList[i].isCustom;
strcpy(sc.schemeName,m_colorSchemeList[i].schemeName.toStdString().c_str());
sc.size=m_colorSchemeList[i].colorList.size();
for(int j=0;j<m_colorSchemeList[i].colorList.size();j++) {
sc.colorList[j].color=m_colorSchemeList[i].colorList[j].color.rgb();
sc.colorList[j].fromValue=m_colorSchemeList[i].colorList[j].fromValue;
sc.colorList[j].toValue=m_colorSchemeList[i].colorList[j].toValue;
strcpy(sc.colorList[j].strComments,m_colorSchemeList[i].colorList[j].strComments.toStdString().c_str());
}
memmove(&buffer[4]+i*sizeof(QtScheme_Color),&sc,sizeof(QtScheme_Color));
}
}
return false;
}
bool QtColorTableData::ChangeColorNum(int colorNum)
{
QtSchemeColor* scheme=CurrentScheme();
if(!scheme || colorNum==scheme->colorList.count())
return false;
// 完成颜色插值
QVector<QtColorItem> newColorList=
paiInpolation(scheme->colorList,colorNum);
scheme->colorList=newColorList;
if(scheme->currentIndex>=scheme->colorList.count())
scheme->currentIndex=0;
ChangeDataRange(scheme);
scheme->isDirty=true;
return true;
}
QList<QRgb> QtColorTableData::GetRgb(int colornum) const
{
const QtSchemeColor* scheme=&m_colorSchemeList[m_currentSchemIndex];
QList<QRgb> rgbList;
if(colornum<=0)
colornum=scheme->colorList.count();
else if(colornum>SECTIONVIEW_NUM)
colornum=SECTIONVIEW_NUM;
QVector<QtColorItem> newColorList;
if(colornum!=scheme->colorList.count())
newColorList=paiInpolation(scheme->colorList,colornum);
else
newColorList=scheme->colorList;
for(int i=0;i<newColorList.count();i++)
{
QtColorItem item=newColorList[i];
rgbList.push_back(qRgb(item.color.red(),item.color.green(),item.color.blue()));
}
return rgbList;
}
void QtColorTableData::ChangeDataRange(QtSchemeColor *scheme)
{
int colorNum=scheme->colorList.count();
float flGap=(m_flMaxVal-m_flMinVal)/(colorNum);
for(int row=0;row<colorNum;row++)
{
if(row==0)
{
scheme->colorList[row].toValue=m_flMinVal+flGap;
}
else
{
scheme->colorList[row].fromValue=m_flMinVal+(row)*flGap;
scheme->colorList[row].toValue=m_flMinVal+(row+1)*flGap;
}
}
}
void QtColorTableData::ReadSettings()
{
QList<QtSchemeColor > shcemeLis;
QtColorItem itemColor;
QString strImagePath;
QString strPathTmp = QCoreApplication::applicationDirPath() + QDir::separator();
strImagePath = QDir::toNativeSeparators( strPathTmp );
QString filecfg=strImagePath+"image"+QDir::separator()+"colortable"+QDir::separator()+"colortable.cfg";
FILE *fp1=fopen(filecfg.toStdString().c_str(),"rt");
if(!fp1) return;
char buf[100];
QString str,name;
int i=0;
while(!feof(fp1)) {
fscanf(fp1,"%s",buf);
name=buf;
if(name.indexOf("custom",Qt::CaseInsensitive)>=0) {
QString filename=strImagePath+"image"+QDir::separator()+"colortable"+QDir::separator()+name;
FILE *fp=fopen(filename.toStdString().c_str(),"rt");
if(!fp) return;
QVector<QtColorItem> colorList;
float r,g,b;
QStringList strs;
while(!feof(fp)) {
char *ret=fgets(buf,100,fp);
if(!ret) break;
str=buf;
str.replace("\r","");
str.replace("\n","");
if(str.indexOf("#")>-1) continue;
if(str.indexOf("=")>-1) continue;
if(str.indexOf("R",Qt::CaseInsensitive)>-1) continue;
if(str.indexOf("G",Qt::CaseInsensitive)>-1) continue;
if(str.indexOf("B",Qt::CaseInsensitive)>-1) continue;
strs=str.split(" ");
strs.removeAll("");
if(strs.size()!=3) continue;
r=strs[0].toFloat();
g=strs[1].toFloat();
b=strs[2].toFloat();
if((r>0&&r<=1)||(g>0&&g<=1)||(b>0&&b<=1)) {
r*=255;
g*=255;
b*=255;
}
int rr=r,gg=g,bb=b;
colorList.push_back(QtColorItem(QColor(rr,gg,bb)));
}
fclose(fp);
QtSchemeColor schemeItem;
name=name.mid(name.lastIndexOf("\\")+1);
if(name.lastIndexOf(".rgb",-1,Qt::CaseInsensitive)>-1)name=name.mid(0,name.lastIndexOf(".rgb",-1,Qt::CaseInsensitive));
schemeItem.schemeName=name;
schemeItem.colorList=colorList;
schemeItem.isDirty=false;
schemeItem.isCustom=true;
schemeItem.currentIndex=0;
m_colorSchemeList.push_back(schemeItem);
}
}
fclose(fp1);
return;
// 读取
bool readOk=readColorPaletteSetting(shcemeLis,gOrignizationName, m_modulName);
if(!readOk || shcemeLis.count()==0)
return;
for(int i=0;i<shcemeLis.count();i++)
{
m_colorSchemeList.push_back(shcemeLis[i]);
}
shcemeLis.clear();
}
void QtColorTableData::SetCurrentSchemeIndex(int nIndex)
{
if(nIndex<0 || nIndex>=m_colorSchemeList.count())
return;
m_currentSchemIndex=nIndex;
}
void QtColorTableData::FreeColorScheme()
{
m_colorSchemeList.clear();
m_systemSchemeList.clear();
m_SharedMemory.detach();
}