1 /****************************************************************************
2 **
3 ** This file is part of the LibreCAD project, a 2D CAD program
4 **
5 ** Copyright (C) 2010-2011 R. van Twisk (librecad@rvt.dds.nl)
6 ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
7 **
8 **
9 ** This file may be distributed and/or modified under the terms of the
10 ** GNU General Public License version 2 as published by the Free Software
11 ** Foundation and appearing in the file gpl-2.0.txt included in the
12 ** packaging of this file.
13 **
14 ** This program is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ** GNU General Public License for more details.
18 **
19 ** You should have received a copy of the GNU General Public License
20 ** along with this program; if not, write to the Free Software
21 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 **
23 ** This copyright notice MUST APPEAR in all copies of the script!
24 **
25 **********************************************************************/
26 
27 #include "qg_colorbox.h"
28 
29 #include <QColorDialog>
30 #include <QPainter>
31 #include <QPixmap>
32 #include "rs_color.h"
33 
34 /**
35  * Default Constructor. You must call init manually if you choose
36  * to use this constructor.
37  */
QG_ColorBox(QWidget * parent,const char * name)38 QG_ColorBox::QG_ColorBox(QWidget* parent, const char* name)
39     :QComboBox(parent)
40     ,currentColor(new RS_Color())
41 ,showByLayer(false)
42 ,showUnchanged(false)
43 ,unchanged(false)
44 {
45     setObjectName(name);
46     setEditable ( false );
47 }
48 
~QG_ColorBox()49 QG_ColorBox::~QG_ColorBox(){}
50 
51 /**
52  * Constructor that calls init and provides a fully functional
53  * combobox for choosing colors.
54  *
55  * @param showByLayer true: Show attribute ByLayer, ByBlock.
56  */
QG_ColorBox(bool showByLayer,bool showUnchanged,QWidget * parent,const char * name)57 QG_ColorBox::QG_ColorBox(bool showByLayer, bool showUnchanged,
58                          QWidget* parent, const char* name)
59     : QComboBox(parent)
60     ,currentColor(new RS_Color())
61     ,unchanged(false)
62 {
63 
64     setObjectName(name);
65     setEditable ( false );
66     init(showByLayer, showUnchanged);
67 }
68 
69 /**
70  * Initialisation (called from constructor or manually but only
71  * once).
72  *
73  * @param showByLayer true: Show attribute ByLayer, ByBlock.
74  */
init(bool showByLayer,bool showUnchanged)75 void QG_ColorBox::init(bool showByLayer, bool showUnchanged) {
76     this->showByLayer = showByLayer;
77     this->showUnchanged = showUnchanged;
78 
79     if (showUnchanged) {
80         addItem(QIcon(":/ui/color00.png"), tr("Unchanged"));
81     }
82     if (showByLayer) {
83         addItem(QIcon(":/ui/color00.png"), tr("By Layer"));
84         addItem(QIcon(":/ui/color00.png"), tr("By Block"));
85     }
86 
87     addItem(QIcon(":/ui/colorxx.png"), tr("Custom"));
88 
89 //static colors starts here
90     //addColor(QIcon(":/ui/color01.png"), red,Qt::red);
91     QString red(tr("Red"));
92     addColor(Qt::red,red);
93     colorIndexStart=findText(red); // keep the starting point of static colors
94     addColor(Qt::darkRed,tr("Dark Red"));
95     addColor(Qt::yellow,tr("Yellow"));
96     addColor(Qt::darkYellow,tr("Dark Yellow"));
97     addColor(Qt::green,tr("Green"));
98     addColor(Qt::darkGreen,tr("Dark Green"));
99     addColor(Qt::cyan,tr("Cyan"));
100     addColor(Qt::darkCyan,tr("Dark Cyan"));
101     addColor(Qt::blue,tr("Blue"));
102     addColor(Qt::darkBlue,tr("Dark Blue"));
103     addColor(Qt::magenta,tr("Magenta"));
104     addColor(Qt::darkMagenta,tr("Dark Magenta"));
105     addItem(QIcon(":/ui/color07.png"), tr("Black / White"),QColor(Qt::black));
106     //colorIndexBlack=findData(QColor(Qt::black)); //record the number for special color black/white
107     //std::cout<<"colorIndexBlack="<<colorIndexBlack<<std::endl;
108     addColor(Qt::gray,tr("Gray"));
109     addColor(Qt::darkGray,tr("Dark Gray"));
110     addColor(Qt::lightGray,tr("Light Gray"));
111 //static colors ends here
112 
113     connect(this, SIGNAL(activated(int)),
114             this, SLOT(slotColorChanged(int)));
115 
116     if (showUnchanged || showByLayer ) {
117         setCurrentIndex(0);
118     } else {
119         setCurrentIndex(findData(QColor(Qt::black))); //default to Qt::black
120     }
121 
122     slotColorChanged(currentIndex());
123 }
124 
125 /**
126  * Sets the color shown in the combobox to the given color.
127  */
setColor(const RS_Color & color)128 void QG_ColorBox::setColor(const RS_Color& color) {
129     *currentColor = color;
130 //std::cout<<"initial color: "<<color<<std::endl;
131     int cIndex;
132 
133     if (color.isByLayer() && showByLayer) {
134         cIndex=0;
135     } else if (color.isByBlock() && showByLayer) {
136         cIndex=1;
137     } else {
138         for(cIndex=colorIndexStart;cIndex< count() - 1;cIndex++) {
139 	//searching for the color, allowing difference up to 2
140 		QColor q(itemData(cIndex).value<QColor>());
141 		if( abs(q.red() - color.red())
142 		   +abs(q.green() - color.green())
143 		   +abs(q.blue() - color.blue()) <= 3
144 		) {
145 			break;
146           }
147         }
148         /*color not found, default to "others...*/
149 /*        if(cIndex == count() - 1) {
150        	    cIndex=findData(QColor(Qt::black)); //default to Qt::black
151         }*/
152     }
153     setCurrentIndex(cIndex);
154 //std::cout<<"Default color for choosing: cIndex="<<cIndex<<" "<<RS_Color(itemData(cIndex).value<QColor>())<<std::endl;
155 
156     if (currentIndex()!= count() -1 ) {
157         slotColorChanged(currentIndex());
158     }
159 }
160 
161 /**
162  * generate icon from color, then add to color box
163  */
addColor(Qt::GlobalColor color,QString text)164 void QG_ColorBox::addColor(Qt::GlobalColor color, QString text)
165 {
166     QPixmap pixmap(":/ui/color00.png");
167     int w = pixmap.width();
168     int h = pixmap.height();
169     QPainter painter(&pixmap);
170     painter.fillRect(1, 1, w-2, h-2, color);
171     addItem(QIcon(pixmap),text,QColor(color));
172 }
173 
174 /**
175  * Sets the color of the pixmap next to the "By Layer" item
176  * to the given color.
177  */
setLayerColor(const RS_Color & color)178 void QG_ColorBox::setLayerColor(const RS_Color& color) {
179     if (! showByLayer ) return;
180     QPixmap pixmap;
181     pixmap = QPixmap(":/ui/color00.png");
182     int w = pixmap.width();
183     int h = pixmap.height();
184     QPainter painter(&pixmap);
185     painter.fillRect(1, 1, w-2, h-2, color);
186     painter.end();
187 
188     setItemIcon(0, QIcon(pixmap));
189     setItemText(0, tr("By Layer"));
190 
191     // needed for the first time a layer is added:
192     if (currentIndex()!= count() -1 ) {
193         slotColorChanged(currentIndex());
194     }
195 }
196 
197 
198 
199 /**
200  * Called when the color has changed. This method
201  * sets the current color to the value chosen or even
202  * offers a dialog to the user that allows him/ her to
203  * choose an individual color.
204  */
slotColorChanged(int index)205 void QG_ColorBox::slotColorChanged(int index) {
206     currentColor->resetFlags();
207     if (showUnchanged) {
208         if (index==0) {
209             unchanged = true;
210         }
211         else {
212             unchanged = false;
213         }
214     }
215 
216     if (showByLayer) {
217         switch (index-(int)showUnchanged) {
218         case 0:
219             *currentColor = RS_Color(RS2::FlagByLayer);
220             break;
221         case 1:
222             *currentColor = RS_Color(RS2::FlagByBlock);
223             break;
224         default:
225             break;
226         }
227     }
228 
229     if (itemText(index) == tr("Custom"))
230     {
231        RS_Color selectedColor = QColorDialog::getColor(*currentColor, this);
232        if (selectedColor.isValid())
233             *currentColor = selectedColor;
234     }
235     else if (index >= colorIndexStart)
236     {
237         if(index < count() )
238         {
239             QVariant q0=itemData(index);
240             if(q0 != QVariant::Invalid )
241             {
242                 *currentColor=itemData(index).value<QColor>();
243             }
244             else
245             {
246                 *currentColor=Qt::black; //default to black color
247             }
248         }
249     }
250 
251     emit colorChanged(*currentColor);
252 }
253 
getColor() const254 RS_Color QG_ColorBox::getColor() const{
255     return *currentColor;
256 }
257 
isUnchanged() const258 bool QG_ColorBox::isUnchanged() const{
259     return unchanged;
260 }
261 
262 
263