~ubuntu-branches/ubuntu/precise/uim/precise

« back to all changes in this revision

Viewing changes to .pc/fix_segv_uim_toolbar_qt4_with_mozc.patch/qt4/toolbar/common-uimstateindicator.cpp

  • Committer: Package Import Robot
  • Author(s): Ilya Barygin
  • Date: 2011-12-18 16:35:38 UTC
  • mfrom: (1.1.13) (15.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20111218163538-8ktir39z2mjpii8z
Tags: 1:1.7.1-3ubuntu1
* Merge from Debian testing (LP: #818199).
* Remaining changes:
  - debian/uim-qt.install: Fix plugin path for multiarch location.
* Dropped changes:
  - uim-applet-gnome removal (GNOME 3 applet is available)
  - 19_as-needed_compile_fix.dpatch (accepted into Debian package)
* translations.patch: add several files to POTFILE.in to prevent
  intltool-update failure.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
 Copyright (c) 2003-2011 uim Project http://code.google.com/p/uim/
 
4
 
 
5
 All rights reserved.
 
6
 
 
7
 Redistribution and use in source and binary forms, with or without
 
8
 modification, are permitted provided that the following conditions
 
9
 are met:
 
10
 
 
11
 1. Redistributions of source code must retain the above copyright
 
12
    notice, this list of conditions and the following disclaimer.
 
13
 2. Redistributions in binary form must reproduce the above copyright
 
14
    notice, this list of conditions and the following disclaimer in the
 
15
    documentation and/or other materials provided with the distribution.
 
16
 3. Neither the name of authors nor the names of its contributors
 
17
    may be used to endorse or promote products derived from this software
 
18
    without specific prior written permission.
 
19
 
 
20
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
 
21
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
22
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
23
 ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
 
24
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
25
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
26
 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
27
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
28
 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
29
 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
30
 SUCH DAMAGE.
 
31
 
 
32
*/
 
33
#include <config.h>
 
34
 
 
35
#include "common-uimstateindicator.h"
 
36
#include <uim/uim-scm.h>
 
37
 
 
38
#include <QtCore/QSocketNotifier>
 
39
#include <QtCore/QString>
 
40
#include <QtCore/QStringList>
 
41
#include <QtCore/QTextCodec>
 
42
#include <QtGui/QHBoxLayout>
 
43
#include <QtGui/QMouseEvent>
 
44
#include <QtGui/QPixmap>
 
45
 
 
46
#include <cstring>
 
47
#include <cstdlib>
 
48
#include <sys/stat.h>
 
49
 
 
50
#include "qtgettext.h"
 
51
 
 
52
static const QString ICONDIR = UIM_PIXMAPSDIR;
 
53
static int uim_fd;
 
54
static QHelperToolbarButton *fallbackButton = 0;
 
55
static QSocketNotifier *notifier = 0;
 
56
 
 
57
static inline QString qstring_(const QString &string)
 
58
{
 
59
#if ENABLE_NLS
 
60
    return mygettext(string.toUtf8().data());
 
61
#else
 
62
    return string;
 
63
#endif
 
64
}
 
65
 
 
66
UimStateIndicator::UimStateIndicator( QWidget *parent )
 
67
        : QFrame( parent )
 
68
{
 
69
    m_layout = new QHBoxLayout;
 
70
    m_layout->setMargin( 0 );
 
71
    m_layout->setSpacing( 0 );
 
72
 
 
73
    if ( !fallbackButton )
 
74
    {
 
75
        fallbackButton = new QHelperToolbarButton( this );
 
76
        m_layout->addWidget( fallbackButton );
 
77
        QPixmap icon = QPixmap( ICONDIR + '/' + "uim-icon.png" );
 
78
        if ( !icon.isNull() ) {
 
79
            QPixmap scaledIcon = icon.scaled( ICON_SIZE, ICON_SIZE,
 
80
                    Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
 
81
            fallbackButton->setIcon( QIcon( scaledIcon ) );
 
82
        } else {
 
83
            fallbackButton->setText( "?" );
 
84
        }
 
85
        fallbackButton->show();
 
86
    }
 
87
 
 
88
    clearButtons();
 
89
 
 
90
    uim_fd = -1;
 
91
    checkHelperConnection();
 
92
    uim_helper_client_get_prop_list();
 
93
    popupMenuShowing = false;
 
94
 
 
95
    setLayout( m_layout );
 
96
}
 
97
 
 
98
 
 
99
UimStateIndicator::~UimStateIndicator()
 
100
{
 
101
    delete notifier;
 
102
    notifier = 0;
 
103
 
 
104
    clearButtons();
 
105
}
 
106
 
 
107
int UimStateIndicator::getNumButtons()
 
108
{
 
109
    return buttons.count();
 
110
}
 
111
 
 
112
void UimStateIndicator::checkHelperConnection()
 
113
{
 
114
    if ( uim_fd < 0 )
 
115
    {
 
116
        uim_fd = uim_helper_init_client_fd( helper_disconnect_cb );
 
117
        if ( uim_fd > 0 )
 
118
        {
 
119
            if ( notifier )
 
120
                delete notifier;
 
121
            notifier = new QSocketNotifier( uim_fd, QSocketNotifier::Read );
 
122
            connect( notifier, SIGNAL( activated( int ) ),
 
123
                              this, SLOT( slotStdinActivated() ) );
 
124
        }
 
125
    }
 
126
}
 
127
void UimStateIndicator::parseHelperStr( const QString& str )
 
128
{
 
129
    const QStringList lines = str.split( '\n', QString::SkipEmptyParts );
 
130
    if ( !lines.isEmpty() && !lines[ 0 ].isEmpty() )
 
131
    {
 
132
        if ( lines[ 0 ] == "prop_list_update" )
 
133
            propListUpdate( lines );
 
134
        else if (lines[0] == "custom_reload_notify" )
 
135
            uim_prop_reload_configs();
 
136
    }
 
137
}
 
138
 
 
139
void UimStateIndicator::propListUpdate( const QStringList& lines )
 
140
{
 
141
    if (popupMenuShowing)
 
142
        return;
 
143
 
 
144
    QHelperPopupMenu *popupMenu = 0;
 
145
#ifdef PLASMA_APPLET_UIM
 
146
    int prevCount = m_layout->count();
 
147
#endif
 
148
    foreach ( QHelperToolbarButton *button, buttons )
 
149
    {
 
150
        if ( m_layout->indexOf( button ) >= 0 )
 
151
            m_layout->removeWidget( button );
 
152
        if ( buttons.contains( button ) )
 
153
        {
 
154
            buttons.removeAll( button );
 
155
            delete button;
 
156
        }
 
157
    }
 
158
 
 
159
    foreach ( const QString &line, lines )
 
160
    {
 
161
        const QStringList fields = line.split( '\t', QString::SkipEmptyParts );
 
162
 
 
163
        if ( !fields.isEmpty() && !fields[ 0 ].isEmpty() )
 
164
        {
 
165
            if ( fields[ 0 ].startsWith( QLatin1String( "branch" ) ) )
 
166
            {
 
167
                if ( fallbackButton )
 
168
                {
 
169
                    m_layout->removeWidget( fallbackButton );
 
170
                    delete fallbackButton;
 
171
                    fallbackButton = 0;
 
172
                }
 
173
                // create button
 
174
                QHelperToolbarButton *button = new QHelperToolbarButton;
 
175
                m_layout->addWidget( button );
 
176
                buttons.append( button );
 
177
 
 
178
                uim_bool isDarkBg =
 
179
                    uim_scm_symbol_value_bool("toolbar-icon-for-dark-background?");
 
180
                const QString append = isDarkBg ? "_dark_background" : "";
 
181
                QString fileName = ICONDIR + '/' + fields[1] + append + ".png";
 
182
                struct stat st;
 
183
                if ( isDarkBg && stat( fileName.toUtf8().data(), &st ) == -1 )
 
184
                {
 
185
                  fileName = ICONDIR + '/' + fields[1] + ".png";
 
186
                }
 
187
                QPixmap icon = QPixmap( fileName );
 
188
                if (!icon.isNull()) {
 
189
                    QPixmap scaledIcon = icon.scaled( ICON_SIZE, ICON_SIZE,
 
190
                            Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
 
191
                    button->setIcon( QIcon( scaledIcon ) );
 
192
                } else {
 
193
                    button->setText( fields[ 2 ] );
 
194
                }
 
195
                button->setToolTip( fields[ 3 ] );
 
196
 
 
197
                // create popup
 
198
#ifdef PLASMA_APPLET_UIM
 
199
                popupMenu = new QHelperPopupMenu( 0 );
 
200
#else
 
201
                popupMenu = new QHelperPopupMenu( button );
 
202
#endif
 
203
                connect( popupMenu, SIGNAL( aboutToShow() ),
 
204
                    this, SLOT( slotPopupMenuAboutToShow() ) );
 
205
                connect( popupMenu, SIGNAL( aboutToHide() ),
 
206
                    this, SLOT( slotPopupMenuAboutToHide() ) );
 
207
                connect( button, SIGNAL( menuRequested( QMenu* ) ),
 
208
                    this, SIGNAL( menuRequested( QMenu* ) ) );
 
209
                button->setMenu( popupMenu );
 
210
                button->setPopupMode( QToolButton::InstantPopup );
 
211
 
 
212
                button->show();
 
213
            }
 
214
            else if ( fields[ 0 ].startsWith( QLatin1String( "leaf" ) ) )
 
215
            {
 
216
                if ( popupMenu
 
217
                        && !fields[ 1 ].isEmpty()
 
218
                        && !fields[ 3 ].isEmpty()
 
219
                        && !fields[ 4 ].isEmpty()
 
220
                        && !fields[ 5 ].isEmpty() )
 
221
                {
 
222
                    QAction *action = popupMenu->insertHelperItem(
 
223
                        fields[1], qstring_( fields[ 3 ] ),
 
224
                        fields[ 4 ], fields[ 5 ] );
 
225
                    // check the item which is now used
 
226
                    if ( fields.count() > 6 && fields[ 6 ] == "*" )
 
227
                        action->setChecked( true );
 
228
                }
 
229
            }
 
230
        }
 
231
    }
 
232
 
 
233
#ifdef PLASMA_APPLET_UIM
 
234
    if ( m_layout->count() != prevCount )
 
235
#endif
 
236
        emit indicatorResized();
 
237
}
 
238
 
 
239
void UimStateIndicator::helper_disconnect_cb()
 
240
{
 
241
    uim_fd = -1;
 
242
    disconnect( notifier, SIGNAL( activated( int ) ), 0, 0 );
 
243
}
 
244
 
 
245
void UimStateIndicator::slotStdinActivated()
 
246
{
 
247
    uim_helper_read_proc( uim_fd );
 
248
 
 
249
    QString tmp;
 
250
    char *s;
 
251
    while ( ( s = uim_helper_get_message() ) )
 
252
    {
 
253
        const QStringList lines = QString( s ).split( '\n',
 
254
            QString::SkipEmptyParts );
 
255
        if ( lines.count() > 1
 
256
            && lines[ 1 ].startsWith( QLatin1String( "charset" ) ) )
 
257
        {
 
258
            /* get charset */
 
259
            QString charset = lines[ 1 ].split( '=',
 
260
                QString::SkipEmptyParts ) [ 1 ];
 
261
 
 
262
            /* convert to unicode */
 
263
            QTextCodec *codec
 
264
                = QTextCodec::codecForName( QByteArray( charset.toAscii() ) );
 
265
            tmp = codec->toUnicode( s );
 
266
        }
 
267
        else
 
268
        {
 
269
            /* no charset */
 
270
            tmp = s;
 
271
        }
 
272
 
 
273
        parseHelperStr( tmp );
 
274
        free( s );
 
275
    }
 
276
}
 
277
 
 
278
void UimStateIndicator::slotPopupMenuAboutToShow()
 
279
{
 
280
    popupMenuShowing = true;
 
281
}
 
282
 
 
283
void UimStateIndicator::slotPopupMenuAboutToHide()
 
284
{
 
285
    popupMenuShowing = false;
 
286
}
 
287
 
 
288
void UimStateIndicator::clearButtons()
 
289
{
 
290
    while ( !buttons.isEmpty() ) {
 
291
        QHelperToolbarButton *button = buttons.takeFirst();
 
292
        m_layout->removeWidget( button );
 
293
        delete button;
 
294
    }
 
295
}
 
296
 
 
297
/**/
 
298
QHelperToolbarButton::QHelperToolbarButton( QWidget *parent )
 
299
    : QToolButton( parent )
 
300
{
 
301
    setAutoRaise( true );
 
302
}
 
303
 
 
304
QSize QHelperToolbarButton::sizeHint() const
 
305
{
 
306
    return QSize( BUTTON_SIZE, BUTTON_SIZE );
 
307
}
 
308
 
 
309
void QHelperToolbarButton::mousePressEvent( QMouseEvent *event )
 
310
{
 
311
#ifdef PLASMA_APPLET_UIM
 
312
    QMenu *popupMenu = menu();
 
313
    if ( event->button() == Qt::LeftButton && popupMenu ) {
 
314
        emit menuRequested( popupMenu );
 
315
        return;
 
316
    }
 
317
#endif
 
318
    QToolButton::mousePressEvent( event );
 
319
}
 
320
 
 
321
/**/
 
322
 
 
323
QHelperPopupMenu::QHelperPopupMenu( QWidget *parent )
 
324
    : QMenu( parent )
 
325
{
 
326
    msgDict.clear(); 
 
327
    connect( this, SIGNAL( triggered( QAction * ) ),
 
328
        this, SLOT( slotMenuActivated( QAction * ) ) );
 
329
}
 
330
 
 
331
QHelperPopupMenu::~QHelperPopupMenu()
 
332
{
 
333
    msgDict.clear();
 
334
}
 
335
 
 
336
QAction *QHelperPopupMenu::insertHelperItem( const QString &indicationIdStr,
 
337
                                        const QString &menulabelStr,
 
338
                                        const QString &menutooltipStr,
 
339
                                        const QString &menucommandStr )
 
340
{
 
341
    QAction *action;
 
342
    uim_bool isDarkBg =
 
343
            uim_scm_symbol_value_bool("toolbar-icon-for-dark-background?");
 
344
    const QString append = isDarkBg ? "_dark_background" : "";
 
345
    QString fileName = ICONDIR + '/' + indicationIdStr + append + ".png";
 
346
    struct stat st;
 
347
    if ( isDarkBg && stat( fileName.toUtf8().data(), &st ) == -1 )
 
348
    {
 
349
        fileName = ICONDIR + '/' + indicationIdStr + ".png";
 
350
    }
 
351
    QPixmap icon = QPixmap ( fileName );
 
352
 
 
353
    if (!icon.isNull()) {
 
354
        QPixmap scaledIcon = icon.scaled( ICON_SIZE, ICON_SIZE,
 
355
                Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
 
356
        action = addAction( scaledIcon, menulabelStr );
 
357
    } else {
 
358
        action = addAction( menulabelStr );
 
359
    }
 
360
 
 
361
    action->setCheckable( true );
 
362
    action->setWhatsThis( menutooltipStr );
 
363
    msgDict.insert( action, menucommandStr );
 
364
 
 
365
    return action;
 
366
}
 
367
 
 
368
void QHelperPopupMenu::slotMenuActivated( QAction *action )
 
369
{
 
370
    QString msg = msgDict.find( action ).value();
 
371
    msg.prepend( "prop_activate\n" );
 
372
    msg.append( "\n" );
 
373
    uim_helper_send_message( uim_fd, msg.toAscii().constData() );
 
374
}