From 2bda8f7717adf28da4af0d34fb82f63d2868c31d Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeutils@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- charselectapplet/charselectapplet.cpp | 366 ++++++++++++++++++++++++++++++++++ 1 file changed, 366 insertions(+) create mode 100644 charselectapplet/charselectapplet.cpp (limited to 'charselectapplet/charselectapplet.cpp') diff --git a/charselectapplet/charselectapplet.cpp b/charselectapplet/charselectapplet.cpp new file mode 100644 index 0000000..f2fccbc --- /dev/null +++ b/charselectapplet/charselectapplet.cpp @@ -0,0 +1,366 @@ +/***************************************************************** + +Copyright (c) 2001 Matthias Elter + +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 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. + +******************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "charselectapplet.h" +#include "charselectapplet.moc" + +extern "C" +{ + KDE_EXPORT KPanelApplet* init(QWidget *parent, const QString& configFile) + { + KGlobal::locale()->insertCatalogue("kcharselectapplet"); + return new CharSelectApplet(configFile, KPanelApplet::Normal, + KPanelApplet::About | KPanelApplet::Preferences, + parent, "kcharselectapplet"); + } +} + +static int cell_width = 16; +static int cell_height = 16; +static int char_count = 0; + +CharSelectApplet::CharSelectApplet(const QString& configFile, Type type, int actions, + QWidget *parent, const char *name) + : KPanelApplet(configFile, type, actions, parent, name), + _aboutData(0), _configDialog(0) +{ + // read configuration + KConfig *c = config(); + c->setGroup("General"); + cell_width = c->readNumEntry("CellWidth", cell_width); + cell_height = c->readNumEntry("CellHeight", cell_height); + QString characters = c->readEntry("Characters", "ÄäÖöÜüß©®§"); + + // setup layout + QHBoxLayout *_layout = new QHBoxLayout(this); + _layout->setAutoAdd(true); + + // setup table view + _table = new CharTable(this); + + // insert chars + _table->setCharacters(characters); +} + +int CharSelectApplet::widthForHeight(int height) const +{ + // number of rows depends on panel size + int rows = (height - (lineWidth() * 2))/ cell_height; + if(rows <= 0) rows = 1; + + // calculate number of columns + float c = (float) char_count / rows; + int columns = (int) ceil(c); + if(columns <= 0) columns = 1; + + _table->setRowsAndColumns(rows, columns); + + // tell kicker how much space we need + return columns * cell_width + lineWidth() * 2; +} + +int CharSelectApplet::heightForWidth(int width) const +{ + // number of columns depends on panel size + int columns = (width - (lineWidth() * 2))/ cell_width; + if(columns <= 0) columns = 1; + + // calculate number of rows we need + float r = (float) char_count / columns; + int rows = (int) ceil(r); + if(rows <= 0) rows = 1; + + _table->setRowsAndColumns(rows, columns); + + return rows * cell_height + lineWidth() *2; +} + +void CharSelectApplet::preferences() +{ + if(!_configDialog) + _configDialog = new ConfigDialog(this); + + _configDialog->setCharacters(_table->characters()); + _configDialog->setCellWidth(cell_width); + _configDialog->setCellHeight(cell_height); + _configDialog->setInitialSize(QSize(300, 100)); + _configDialog->exec(); + + cell_width = _configDialog->cellWidth(); + cell_height = _configDialog->cellHeight(); + _table->setCharacters(_configDialog->characters()); + + emit updateLayout(); + + // write configuration + KConfig *c = config(); + c->setGroup("General"); + c->writeEntry("CellWidth", cell_width); + c->writeEntry("CellHeight", cell_height); + c->writeEntry("Characters", _configDialog->characters()); + c->sync(); +} + +void CharSelectApplet::about() +{ + if(!_aboutData) { + _aboutData = new KAboutData("kcharselectapplet", I18N_NOOP("KCharSelectApplet"), "1.0", + I18N_NOOP("A character picker applet.\n" + "Used to copy single characters to the X11 clipboard.\n" + "You can paste them to an application with the middle mouse button."), + KAboutData::License_BSD, "(c) 2001, Matthias Elter"); + _aboutData->addAuthor("Matthias Elter", 0, "elter@kde.org"); + } + + KAboutApplication dialog(_aboutData); + dialog.exec(); +} + +CharTable::CharTable(QWidget* parent, const char* name) + : QFrame(parent, name), _rows(2), _cols(2), + _activeRow(-1), _activeCol(-1), + _cWidth(cell_width), _cHeight(cell_height) +{ + setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); + setFocusPolicy(QWidget::NoFocus); + setBackgroundMode(QWidget::NoBackground); +} + +void CharTable::setRowsAndColumns(int r, int c) +{ + _rows = r; + _cols = c; +} + +void CharTable::insertChar(QChar c) +{ + _map.insert(char_count++, c); +} + +void CharTable::insertString(QString s) +{ + for (unsigned int i = 0; i < s.length(); i++) + insertChar(s[i]); +} + +void CharTable::setCharacters(const QString& characters) +{ + _map.clear(); + char_count = 0; + insertString(characters); +} + +QString CharTable::characters() +{ + QString characters; + for (int r = 0; r <_rows; r++) + for (int c = 0; c <_cols; c++) + characters += _map[c + r * _cols]; + + return characters; +} + +int CharTable::findRow(int y) +{ + return y / _cHeight; +} + +int CharTable::findCol(int x) +{ + return x / _cWidth; +} + +void CharTable::resizeEvent(QResizeEvent*) +{ + _cWidth = contentsRect().width() / _cols; + _cHeight = contentsRect().height() / _rows; +} + +void CharTable::paintEvent(QPaintEvent* e) +{ + QPainter p(this); + + int xoffset = contentsRect().x(); + int yoffset = contentsRect().y(); + + for (int r = 0; r <_rows; r++) { + for (int c = 0; c <_cols; c++) { + p.setViewport(xoffset + c * _cWidth, yoffset + r * _cHeight, _cWidth, _cHeight); + p.setWindow(0, 0, _cWidth, _cHeight); + paintCell(&p, r, c); + } + } + QFrame::paintEvent(e); +} + +void CharTable::repaintCell(int r, int c) +{ + QPainter p(this); + + int xoffset = contentsRect().x(); + int yoffset = contentsRect().y(); + + p.setViewport(xoffset + c * _cWidth, yoffset + r * _cHeight, _cWidth, _cHeight); + p.setWindow(0, 0, _cWidth, _cHeight); + paintCell(&p, r, c); +} + +void CharTable::paintCell(QPainter* p, int row, int col) +{ + int w = _cWidth; + int h = _cHeight; + int x2 = w - 1; + int y2 = h - 1; + + bool active = (row == _activeRow) && (col == _activeCol); + + // draw background + if (active) { + p->setBrush(QBrush(colorGroup().highlight())); + p->setPen(NoPen); + p->drawRect(0, 0, w, h); + p->setPen(colorGroup().highlightedText()); + } + else { + p->setBrush(QBrush(colorGroup().base())); + p->setPen(NoPen); + p->drawRect(0, 0, w, h); + p->setPen(colorGroup().text()); + } + + // set font + QFont f = font(); + f.setPixelSize(10); + p->setFont(f); + + // draw char + p->drawText(0, 0, x2, y2, AlignHCenter | AlignVCenter, QString(_map[col + row * _cols])); +} + +void CharTable::mousePressEvent(QMouseEvent *e) +{ + int row = findRow(e->y()); + if (row == -1) return; + + int col = findCol(e->x()); + if (col == -1) return; + + selectCell(row, col); +} + +void CharTable::mouseMoveEvent(QMouseEvent *e) +{ + if(!(e->state() & (LeftButton | RightButton | MidButton))) return; + + int row = findRow(e->y()); + if (row == -1) return; + + int col = findCol(e->x()); + if (col == -1) return; + + selectCell(row, col); +} + +void CharTable::selectCell(int row, int col) +{ + if (row >= _rows || row < 0) return; + if (col >= _cols || col < 0) return; + + int oldRow = _activeRow; + int oldCol = _activeCol; + + _activeRow = row; + _activeCol = col; + + repaintCell(oldRow, oldCol); + repaintCell(_activeRow, _activeCol); + + QClipboard *cb = QApplication::clipboard(); + QObject::disconnect( cb, SIGNAL(dataChanged()), this, SLOT(clearCell()) ); + QString text = QString(_map[col + row * _cols]); + bool oldMode = cb->selectionModeEnabled(); + cb->setSelectionMode( true ); + cb->setText( text ); + cb->setSelectionMode( false ); + cb->setText( text ); + cb->setSelectionMode( oldMode ); + QObject::connect( cb, SIGNAL(dataChanged()), this, SLOT(clearCell()) ); +} + +void CharTable::clearCell() +{ + int oldRow = _activeRow; + int oldCol = _activeCol; + + _activeRow = -1; + _activeCol = -1; + + repaintCell(oldRow, oldCol); + + QObject::disconnect( QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(clearCell()) ); +} + + +ConfigDialog::ConfigDialog(QWidget* parent, const char* name) + : KDialogBase(parent, name, true, i18n("Configuration"), + Ok | Cancel, Ok, true) +{ + QVBox *page = makeVBoxMainWidget(); + + QHBox *whbox = new QHBox(page); + QHBox *hhbox = new QHBox(page); + QHBox *chbox = new QHBox(page); + + QLabel *wlabel = new QLabel(i18n("Cell width:"), whbox); + QLabel *hlabel = new QLabel(i18n("Cell height:"), hhbox); + (void) new QLabel(i18n("Characters:"), chbox); + + _widthSpinBox = new QSpinBox(whbox); + _widthSpinBox->setMinValue(1); + _heightSpinBox = new QSpinBox(hhbox); + _heightSpinBox->setMinValue(1); + _characterInput = new KLineEdit(chbox); + + whbox->setSpacing(KDialog::spacingHint()); + hhbox->setSpacing(KDialog::spacingHint()); + chbox->setSpacing(KDialog::spacingHint()); + + whbox->setStretchFactor(wlabel, 2); + hhbox->setStretchFactor(hlabel, 2); + chbox->setStretchFactor(_characterInput, 2); +} -- cgit v1.2.1