kexi

kexirecordmarker.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2002 Lucijan Busch <lucijan@gmx.at>
00003    Copyright (C) 2002 Till Busch <till@bux.at>
00004    Copyright (C) 2002 Daniel Molkentin <molkentin@kde.org>
00005    Copyright (C) 2003-2006 Jaroslaw Staniek <js@iidea.pl>
00006 
00007    This program is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Library General Public
00009    License as published by the Free Software Foundation; either
00010    version 2 of the License, or (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Library General Public License for more details.
00016 
00017    You should have received a copy of the GNU Library General Public License
00018    along with this program; see the file COPYING.  If not, write to
00019    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020  * Boston, MA 02110-1301, USA.
00021 */
00022 
00023 #include "kexirecordmarker.h"
00024 
00025 #include <qcolor.h>
00026 #include <qstyle.h>
00027 #include <qpixmap.h>
00028 #include <qpainter.h>
00029 #include <qimage.h>
00030 #include <qapplication.h>
00031 
00032 #include <kdebug.h>
00033 #include <kstaticdeleter.h>
00034 
00035 #include <kexiutils/utils.h>
00036 
00037 static KStaticDeleter<QImage> KexiRecordMarker_pen_deleter, KexiRecordMarker_plus_deleter;
00038 QImage* KexiRecordMarker_pen = 0, *KexiRecordMarker_plus = 0;
00039 
00040 static const unsigned char img_pen_data[] = {
00041     0x00,0x00,0x03,0x30,0x78,0x9c,0xfb,0xff,0xff,0x3f,0xc3,0x7f,0x32,0x30,
00042     0x10,0x80,0x88,0xff,0xe4,0xe8,0x85,0xe9,0xc7,0xc6,0x26,0x55,0x3f,0x3a,
00043     0x4d,0x8e,0x7e,0x72,0xfc,0x32,0xd2,0xf5,0xa3,0xeb,0xa5,0xb5,0x7e,0x5c,
00044     0xe9,0x85,0x54,0xfb,0xb1,0xa5,0x1b,0x52,0xdc,0x0e,0x00,0xf2,0xea,0x0a,
00045     0x13
00046 };
00047 static const unsigned char img_plus_data[] = {
00048     0x00,0x00,0x01,0x90,0x78,0x9c,0xfb,0xff,0xff,0x3f,0xc3,0x7f,0x28,0x86,
00049     0x82,0xff,0x50,0x0c,0x17,0x47,0xc7,0xd4,0x50,0x87,0x05,0xc0,0xd5,0xe1,
00050     0x10,0xa7,0x16,0x26,0xca,0x5e,0x7c,0xfe,0x20,0x47,0x1d,0xb2,0x5a,0x5c,
00051     0xea,0x40,0x72,0x00,0x03,0x6e,0x74,0x8c
00052 };
00053 
00054 static struct EmbedImage {
00055     int width, height, depth;
00056     const unsigned char *data;
00057     ulong compressed;
00058     int numColors;
00059     const QRgb *colorTable;
00060     bool alpha;
00061     const char *name;
00062 } embed_image[] = {
00063     { 17, 12, 32, (const unsigned char*)img_pen_data, 57, 0, 0, true, "tableview_pen.png" },
00064     { 10, 10, 32, (const unsigned char*)img_pen_data, 50, 0, 0, true, "tableview_plus.png" }
00065 };
00066 
00067 QImage* getImg(const unsigned char* data, int id)
00068 {
00069     QByteArray baunzip;
00070     baunzip = qUncompress( data, embed_image[id].compressed );
00071     QImage *img = new QImage( QImage((uchar*)baunzip.data(),
00072             embed_image[id].width, embed_image[id].height,
00073             embed_image[id].depth, (QRgb*)embed_image[id].colorTable,
00074             embed_image[id].numColors, QImage::BigEndian
00075     ).copy() );
00076     if ( embed_image[id].alpha )
00077         img->setAlphaBuffer(true);
00078     return img;
00079 }
00080 
00081 static void initRecordMarkerImages()
00082 {
00083     if (!KexiRecordMarker_pen) {
00085         KexiRecordMarker_pen_deleter.setObject( KexiRecordMarker_pen, getImg(img_pen_data, 0) );
00086         KexiRecordMarker_plus_deleter.setObject( KexiRecordMarker_plus, getImg(img_plus_data, 1) );
00087     }
00088 }
00089 
00090 //----------------------------------------------------------------
00091 
00093 class KexiRecordMarker::Private
00094 {
00095 public:
00096     Private()
00097      : rowHeight(1)
00098      , offset(0)
00099      , currentRow(-1)
00100      , highlightedRow(-1)
00101      , editRow(-1)
00102      , rows(0)
00103      , selectionBackgroundColor(qApp->palette().active().highlight())
00104      , showInsertRow(true)
00105     {
00106     }
00107     int rowHeight;
00108     int offset;
00109     int currentRow;
00110     int highlightedRow;
00111     int editRow;
00112     int rows;
00113     QColor selectionBackgroundColor;
00114     bool showInsertRow : 1;
00115 };
00116 
00117 //----------------------------------------------------------------
00118 
00119 KexiRecordMarker::KexiRecordMarker(QWidget *parent, const char* name)
00120  : QWidget(parent, name)
00121  , d( new Private() )
00122 {
00123     initRecordMarkerImages();
00124 }
00125 
00126 KexiRecordMarker::~KexiRecordMarker()
00127 {
00128     delete d;
00129 }
00130 
00131 QImage* KexiRecordMarker::penImage()
00132 {
00133     initRecordMarkerImages();
00134     return KexiRecordMarker_pen;
00135 }
00136 
00137 QImage* KexiRecordMarker::plusImage()
00138 {
00139     initRecordMarkerImages();
00140     return KexiRecordMarker_plus;
00141 }
00142 
00143 void KexiRecordMarker::addLabel(bool upd)
00144 {
00145     d->rows++;
00146     if (upd)
00147         update();
00148 }
00149 
00150 void KexiRecordMarker::removeLabel(bool upd)
00151 {
00152     if (d->rows > 0) {
00153         d->rows--;
00154         if (upd)
00155             update();
00156     }
00157 }
00158 
00159 void KexiRecordMarker::addLabels(int num, bool upd)
00160 {
00161     d->rows += num;
00162     if (upd)
00163         update();
00164 }
00165 
00166 void KexiRecordMarker::clear(bool upd)
00167 {
00168     d->rows=0;
00169     if (upd)
00170         update();
00171 }
00172 
00173 int KexiRecordMarker::rows() const
00174 {
00175     if (d->showInsertRow)
00176         return d->rows +1;
00177     else
00178         return d->rows;
00179 }
00180 
00181 void KexiRecordMarker::paintEvent(QPaintEvent *e)
00182 {
00183     QPainter p(this);
00184     QRect r(e->rect());
00185 
00186     int first = (r.top()    + d->offset) / d->rowHeight;
00187     int last  = (r.bottom() + d->offset) / d->rowHeight;
00188     if(last > (d->rows-1+(d->showInsertRow?1:0)))
00189         last = d->rows-1+(d->showInsertRow?1:0);
00190 
00191     QColorGroup selectedColorGroup(colorGroup());
00192     selectedColorGroup.setColor( QColorGroup::Button, 
00193         KexiUtils::blendedColors( selectedColorGroup.color(QColorGroup::Background), 
00194             d->selectionBackgroundColor, 2, 1) );
00195     selectedColorGroup.setColor( QColorGroup::Background, 
00196         selectedColorGroup.color(QColorGroup::Button) ); //set background color as well (e.g. for thinkeramik)
00197     QColorGroup highlightedColorGroup(colorGroup());
00198     highlightedColorGroup.setColor( QColorGroup::Button, 
00199         KexiUtils::blendedColors( highlightedColorGroup.color(QColorGroup::Background), 
00200             d->selectionBackgroundColor, 4, 1) );
00201     highlightedColorGroup.setColor( QColorGroup::Background, 
00202         highlightedColorGroup.color(QColorGroup::Button) ); //set background color as well (e.g. for thinkeramik)
00203     for(int i=first; i <= last; i++)
00204     {
00205         int y = ((d->rowHeight * i)-d->offset);
00206         QRect r(0, y, width(), d->rowHeight);
00207         p.drawRect(r);
00208         style().drawPrimitive( QStyle::PE_HeaderSection, &p, r,
00209             (d->currentRow == i) ? selectedColorGroup : (d->highlightedRow == i ? highlightedColorGroup : colorGroup()), 
00210             QStyle::Style_Raised | (isEnabled() ? QStyle::Style_Enabled : 0));
00211     }
00212     if (d->editRow!=-1 && d->editRow >= first && d->editRow <= (last/*+1 for insert row*/)) {
00213         //show pen when editing
00214         int ofs = d->rowHeight / 4;
00215         int pos = ((d->rowHeight*(d->currentRow>=0?d->currentRow:0))-d->offset)-ofs/2+1;
00216         p.drawImage((d->rowHeight-KexiRecordMarker_pen->width())/2,
00217             (d->rowHeight-KexiRecordMarker_pen->height())/2+pos,*KexiRecordMarker_pen);
00218     }
00219     else if (d->currentRow >= first && d->currentRow <= last 
00220         && (!d->showInsertRow || (d->showInsertRow && d->currentRow < last)))/*don't display marker for 'insert' row*/ 
00221     {
00222         //show marker
00223         p.setBrush(colorGroup().foreground());
00224         p.setPen(QPen(Qt::NoPen));
00225         QPointArray points(3);
00226         int ofs = d->rowHeight / 4;
00227         int ofs2 = (width() - ofs) / 2 -1;
00228         int pos = ((d->rowHeight*d->currentRow)-d->offset)-ofs/2+2;
00229         points.putPoints(0, 3, ofs2, pos+ofs, ofs2 + ofs, pos+ofs*2, 
00230             ofs2,pos+ofs*3);
00231         p.drawPolygon(points);
00232 //      kdDebug() <<"KexiRecordMarker::paintEvent(): POLYGON" << endl;
00233 /*      int half = d->rowHeight / 2;
00234         points.setPoints(3, 2, pos + 2, width() - 5, pos + half, 2, pos + (2 * half) - 2);*/
00235     }
00236     if (d->showInsertRow && d->editRow < last
00237         && last == (d->rows-1+(d->showInsertRow?1:0)) ) {
00238         //show plus sign
00239         int pos = ((d->rowHeight*last)-d->offset)+(d->rowHeight-KexiRecordMarker_plus->height())/2;
00240 //      p.drawImage((width()-d->plusImg.width())/2-1, pos, d->plusImg);
00241         p.drawImage((width()-KexiRecordMarker_plus->width())/2, pos, *KexiRecordMarker_plus);
00242     }
00243 }
00244 
00245 void KexiRecordMarker::setCurrentRow(int row)
00246 {
00247     if (row == d->currentRow)
00248         return;
00249     int oldRow = d->currentRow;
00250     d->currentRow=row;
00251     
00252     if (oldRow != -1)
00253         update(0,(d->rowHeight*(oldRow))-d->offset-1, width()+2, d->rowHeight+2);
00254     if (d->currentRow != -1)
00255         update(0,(d->rowHeight*d->currentRow)-d->offset-1, width()+2, d->rowHeight+2);
00256 }
00257 
00258 void KexiRecordMarker::setHighlightedRow(int row)
00259 {
00260     if (row == d->highlightedRow)
00261         return;
00262     int oldRow = d->highlightedRow;
00263     d->highlightedRow = row;
00264 
00265     if (oldRow != -1)
00266         update(0,(d->rowHeight*(oldRow))-d->offset-1, width()+2, d->rowHeight+2);
00267     if (d->currentRow != -1)
00268         update(0,(d->rowHeight*d->highlightedRow)-d->offset-1, width()+2, d->rowHeight+2);
00269 }
00270 
00271 void KexiRecordMarker::setOffset(int offset)
00272 {
00273     int oldOff = d->offset;
00274     d->offset = offset;
00275     scroll(0,oldOff-offset);
00276 }
00277 
00278 void KexiRecordMarker::setCellHeight(int cellHeight)
00279 {
00280     d->rowHeight = cellHeight;
00281 }
00282 
00283 void KexiRecordMarker::setEditRow(int row)
00284 {
00285     d->editRow = row;
00286 //TODO: update only needed area!
00287     update();
00288 }
00289 
00290 void KexiRecordMarker::showInsertRow(bool show)
00291 {
00292     d->showInsertRow = show;
00293 //TODO: update only needed area!
00294     update();
00295 }
00296 
00297 void KexiRecordMarker::setSelectionBackgroundColor(const QColor &color)
00298 {
00299     d->selectionBackgroundColor = color;
00300 }
00301 
00302 QColor KexiRecordMarker::selectionBackgroundColor() const
00303 {
00304     return d->selectionBackgroundColor;
00305 }
00306 
00307 #include "kexirecordmarker.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys