File indexing completed on 2024-04-28 15:14:00

0001 /***************************************************************************
0002     File                 : GuiTools.cpp
0003     Project              : LabPlot
0004     --------------------------------------------------------------------
0005     Copyright            : (C) 2011-2013 Alexander Semke (alexander.semke*web.de)
0006                            (replace * with @ in the email addresses)
0007     Description          :  contains several static functions which are used on frequently throughout the kde frontend.
0008 
0009  ***************************************************************************/
0010 
0011 /***************************************************************************
0012  *                                                                         *
0013  *  This program is free software; you can redistribute it and/or modify   *
0014  *  it under the terms of the GNU General Public License as published by   *
0015  *  the Free Software Foundation; either version 2 of the License, or      *
0016  *  (at your option) any later version.                                    *
0017  *                                                                         *
0018  *  This program is distributed in the hope that it will be useful,        *
0019  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
0020  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
0021  *  GNU General Public License for more details.                           *
0022  *                                                                         *
0023  *   You should have received a copy of the GNU General Public License     *
0024  *   along with this program; if not, write to the Free Software           *
0025  *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
0026  *   Boston, MA  02110-1301  USA                                           *
0027  *                                                                         *
0028  ***************************************************************************/
0029 
0030 #include "GuiTools.h"
0031 #include <KI18n/KLocalizedString>
0032 
0033 #include <array>
0034 #include <QApplication>
0035 #include <QComboBox>
0036 #include <QLineEdit>
0037 #include <QMenu>
0038 #include <QColor>
0039 #include <QPainter>
0040 
0041 static const int colorsCount = 26;
0042 static std::array<QColor, colorsCount> colors = {QColor(255,255,255), QColor(0,0,0),
0043                             QColor(192,0,0), QColor(255,0,0), QColor(255,192,192), //red
0044                             QColor(0,192,0), QColor(0,255,0), QColor(192,255,192), //green
0045                             QColor(0,0,192), QColor(0,0,255), QColor(192,192,255), //blue
0046                             QColor(192,192,0), QColor(255,255,0), QColor(255,255,192), //yellow
0047                             QColor(0,192,192), QColor(0,255,255), QColor(192,255,255), //cyan
0048                             QColor(192,0,192), QColor(255,0,255), QColor(255,192,255), //magenta
0049                             QColor(192,88,0), QColor(255,128,0), QColor(255,168,88), //orange
0050                             QColor(128,128,128), QColor(160,160,160), QColor(195,195,195) //grey
0051                             };
0052 
0053 /*!
0054     fills the ComboBox \c combobox with the six possible Qt::PenStyles, the color \c color is used.
0055 */
0056 void GuiTools::updatePenStyles(QComboBox* comboBox, const QColor& color) {
0057     int index = comboBox->currentIndex();
0058     comboBox->clear();
0059 
0060     QPainter pa;
0061     int offset = 2;
0062     int w = 50;
0063     int h = 10;
0064     QPixmap pm(w, h);
0065     comboBox->setIconSize(QSize(w,h));
0066 
0067     //loop over six possible Qt-PenStyles, draw on the pixmap and insert it
0068     //TODO: avoid copy-paste in all finctions!
0069     static std::array<QString, 6> list = { i18n("No Line"), i18n("Solid Line"), i18n("Dash Line"),
0070                                i18n("Dot Line"), i18n("Dash-dot Line"), i18n("Dash-dot-dot Line") };
0071     for (int i = 0; i < 6; i++) {
0072         pm.fill(Qt::transparent);
0073         pa.begin(&pm);
0074         pa.setPen( QPen(color, 1, (Qt::PenStyle)i) );
0075         pa.drawLine(offset, h/2, w-offset, h/2);
0076         pa.end();
0077         comboBox->addItem( QIcon(pm), list[i] );
0078     }
0079     comboBox->setCurrentIndex(index);
0080 }
0081 
0082 /*!
0083     fills the QMenu \c menu with the six possible Qt::PenStyles, the color \c color is used.
0084     QActions are created with \c actionGroup as the parent, if not available.
0085     If already available, onle the color in the QAction's icons is updated.
0086 */
0087 void GuiTools::updatePenStyles(QMenu* menu, QActionGroup* actionGroup, const QColor& color) {
0088     QPainter pa;
0089     int offset = 2;
0090     int w = 50;
0091     int h = 10;
0092     QPixmap pm(w, h);
0093 
0094     //loop over six possible Qt-PenStyles, draw on the pixmap and insert it
0095     static std::array<QString, 6> list = { i18n("No Line"), i18n("Solid Line"), i18n("Dash Line"),
0096                                i18n("Dot Line"), i18n("Dash-dot Line"), i18n("Dash-dot-dot Line") };
0097 
0098     QAction* action;
0099     if (actionGroup->actions().isEmpty()) {
0100         //TODO setting of the icon size doesn't work here
0101         menu->setStyleSheet( "QMenu::icon { width:50px; height:10px; }" );
0102 
0103         for (int i = 0; i < 6; i++) {
0104             pm.fill(Qt::transparent);
0105             pa.begin(&pm);
0106             pa.setPen( QPen( color, 1, (Qt::PenStyle)i ) );
0107             pa.drawLine(offset, h/2, w-offset, h/2);
0108             pa.end();
0109             action = new QAction( QIcon(pm), list[i], actionGroup );
0110             action->setCheckable(true);
0111             menu->addAction( action );
0112         }
0113     } else {
0114         for (int i = 0; i < 6; i++) {
0115             pm.fill(Qt::transparent);
0116             pa.begin( &pm );
0117             pa.setPen( QPen( color, 1, (Qt::PenStyle)i ) );
0118             pa.drawLine(offset, h/2, w-offset, h/2);
0119             pa.end();
0120             action = actionGroup->actions().at(i);
0121             action->setIcon( QIcon(pm) );
0122         }
0123     }
0124 }
0125 
0126 void GuiTools::selectPenStyleAction(QActionGroup* actionGroup, Qt::PenStyle style) {
0127     int index = (int)style;
0128     Q_ASSERT(index < actionGroup->actions().size());
0129     actionGroup->actions().at(index)->setChecked(true);
0130 }
0131 
0132 Qt::PenStyle GuiTools::penStyleFromAction(QActionGroup* actionGroup, QAction* action) {
0133     int index = actionGroup->actions().indexOf(action);
0134     return Qt::PenStyle(index);
0135 }
0136 
0137 /*!
0138     fills the ComboBox for the symbol filling patterns with the 14 possible Qt::BrushStyles.
0139 */
0140 void GuiTools::updateBrushStyles(QComboBox* comboBox, const QColor& color) {
0141     int index = comboBox->currentIndex();
0142     comboBox->clear();
0143 
0144     QPainter pa;
0145     int offset = 2;
0146     int w = 50;
0147     int h = 20;
0148     QPixmap pm(w, h);
0149     comboBox->setIconSize(QSize(w, h));
0150 
0151     QPen pen(Qt::SolidPattern, 1);
0152     pa.setPen(pen);
0153 
0154     static std::array<QString, 15> list = { i18n("None"), i18n("Uniform"), i18n("Extremely Dense"),
0155                                 i18n("Very Dense"), i18n("Somewhat Dense"), i18n("Half Dense"),
0156                                 i18n("Somewhat Sparse"), i18n("Very Sparse"), i18n("Extremely Sparse"),
0157                                 i18n("Horiz. Lines"), i18n("Vert. Lines"), i18n("Crossing Lines"),
0158                                 i18n("Backward Diag. Lines"), i18n("Forward Diag. Lines"), i18n("Crossing Diag. Lines") };
0159     const QColor& borderColor = (qApp->palette().color(QPalette::Base).lightness() < 128) ? Qt::white : Qt::black;
0160     for (int i = 0; i < 15; i++) {
0161         pm.fill(Qt::transparent);
0162         pa.begin(&pm);
0163         pa.setPen(borderColor);
0164         pa.setRenderHint(QPainter::Antialiasing);
0165         pa.setBrush( QBrush(color, (Qt::BrushStyle)i) );
0166         pa.drawRect(offset, offset, w - 2*offset, h - 2*offset);
0167         pa.end();
0168         comboBox->addItem(QIcon(pm), list[i]);
0169     }
0170 
0171     comboBox->setCurrentIndex(index);
0172 }
0173 
0174 void GuiTools::fillColorMenu(QMenu* menu, QActionGroup* actionGroup) {
0175     static const std::array<QString, colorsCount> colorNames = {i18n("White"), i18n("Black"),
0176                             i18n("Dark Red"), i18n("Red"), i18n("Light Red"),
0177                             i18n("Dark Green"), i18n("Green"), i18n("Light Green"),
0178                             i18n("Dark Blue"), i18n("Blue"), i18n("Light Blue"),
0179                             i18n("Dark Yellow"), i18n("Yellow"), i18n("Light Yellow"),
0180                             i18n("Dark Cyan"), i18n("Cyan"), i18n("Light Cyan"),
0181                             i18n("Dark Magenta"), i18n("Magenta"), i18n("Light Magenta"),
0182                             i18n("Dark Orange"), i18n("Orange"), i18n("Light Orange"),
0183                             i18n("Dark Grey"), i18n("Grey"), i18n("Light Grey")
0184                             };
0185 
0186     QPixmap pix(16, 16);
0187     QPainter p(&pix);
0188     for (int i = 0; i < colorsCount; ++i) {
0189         p.fillRect(pix.rect(), colors[i]);
0190         QAction* action = new QAction(QIcon(pix), colorNames[i], actionGroup);
0191         action->setCheckable(true);
0192         menu->addAction(action);
0193     }
0194 }
0195 
0196 /*!
0197  * Selects (checks) the action in the group \c actionGroup hat corresponds to the color \c color.
0198  * Unchecks the previously checked action if the color
0199  * was not found in the list of predefined colors.
0200  */
0201 void GuiTools::selectColorAction(QActionGroup* actionGroup, const QColor& color) {
0202     int index;
0203     for (index = 0; index < colorsCount; ++index) {
0204         if (color == colors[index]) {
0205             actionGroup->actions().at(index)->setChecked(true);
0206             break;
0207         }
0208     }
0209 
0210     if (index == colorsCount) {
0211         //the color was not found in the list of predefined colors
0212         // -> uncheck the previously checked action
0213         QAction* checkedAction = actionGroup->checkedAction();
0214         if (checkedAction)
0215             checkedAction->setChecked(false);
0216     }
0217 }
0218 
0219 QColor& GuiTools::colorFromAction(QActionGroup* actionGroup, QAction* action) {
0220     int index = actionGroup->actions().indexOf(action);
0221     if (index == -1 || index >= colorsCount)
0222         index = 0;
0223 
0224     return colors[index];
0225 }
0226 
0227 // ComboBox with colors
0228 //  QImage img(16,16,QImage::Format_RGB32);
0229 //  QPainter p(&img);
0230 //  QRect rect = img.rect().adjusted(1,1,-1,-1);
0231 //  p.fillRect(rect, Qt::red);
0232 //  comboBox->setItemData(0, QPixmap::fromImage(img), Qt::DecorationRole);
0233 
0234 void GuiTools::highlight(QLineEdit* le, bool invalid) {
0235     if (invalid)
0236         le->setStyleSheet(QStringLiteral("QLineEdit{color:red;}"));
0237     else
0238         le->setStyleSheet(QString());
0239 }