KDEUI
kcodecaction.cpp
Go to the documentation of this file.
00001 /* 00002 kcodecaction.cpp 00003 00004 Copyright (c) 2003 Jason Keirstead <jason@keirstead.org> 00005 Copyrigth (c) 2006 Michel Hermier <michel.hermier@gmail.com> 00006 Copyright (c) 2007 Nick Shaforostoff <shafff@ukr.net> 00007 00008 ******************************************************************** 00009 * * 00010 * This library is free software; you can redistribute it and/or * 00011 * modify it under the terms of the GNU Lesser General Public * 00012 * License as published by the Free Software Foundation; either * 00013 * version 2 of the License, or (at your option) any later version. * 00014 * * 00015 * This library is distributed in the hope that it will be useful, * 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00018 * GNU Lesser General Public License for more details. * 00019 * * 00020 * You should have received a copy of the GNU Lesser General Public * 00021 * License along with this library; if not, write to the * 00022 * Free Software Foundation, Inc., 51 Franklin Street, * 00023 * Fifth Floor, Boston, MA 02110-1301 USA * 00024 * * 00025 ******************************************************************** 00026 */ 00027 00028 #include "kcodecaction.h" 00029 00030 #include <kcharsets.h> 00031 #include <kdebug.h> 00032 #include <klocale.h> 00033 #include <kglobal.h> 00034 00035 #include <QMenu> 00036 #include <QVariant> 00037 #include <QtCore/QTextCodec> 00038 00039 // Acording to http://www.iana.org/assignments/ianacharset-mib 00040 // the default/unknown mib value is 2. 00041 #define MIB_DEFAULT 2 00042 00043 class KCodecAction::Private 00044 { 00045 public: 00046 Private(KCodecAction *parent) 00047 : q(parent), 00048 defaultAction(0), 00049 currentSubAction(0) 00050 { 00051 } 00052 00053 void init(bool); 00054 00055 void _k_subActionTriggered(QAction*); 00056 00057 KCodecAction *q; 00058 QAction *defaultAction; 00059 QAction *currentSubAction; 00060 }; 00061 00062 KCodecAction::KCodecAction(QObject *parent,bool showAutoOptions) 00063 : KSelectAction(parent) 00064 , d(new Private(this)) 00065 { 00066 d->init(showAutoOptions); 00067 } 00068 00069 KCodecAction::KCodecAction(const QString &text, QObject *parent,bool showAutoOptions) 00070 : KSelectAction(text, parent) 00071 , d(new Private(this)) 00072 { 00073 d->init(showAutoOptions); 00074 } 00075 00076 KCodecAction::KCodecAction(const KIcon &icon, const QString &text, QObject *parent,bool showAutoOptions) 00077 : KSelectAction(icon, text, parent) 00078 , d(new Private(this)) 00079 { 00080 d->init(showAutoOptions); 00081 } 00082 00083 KCodecAction::~KCodecAction() 00084 { 00085 delete d; 00086 } 00087 00088 void KCodecAction::Private::init(bool showAutoOptions) 00089 { 00090 q->setToolBarMode(MenuMode); 00091 defaultAction = q->addAction(i18nc("Encodings menu", "Default")); 00092 00093 int i; 00094 foreach(const QStringList &encodingsForScript, KGlobal::charsets()->encodingsByScript()) 00095 { 00096 KSelectAction* tmp = new KSelectAction(encodingsForScript.at(0),q); 00097 if (showAutoOptions) 00098 { 00099 KEncodingDetector::AutoDetectScript scri=KEncodingDetector::scriptForName(encodingsForScript.at(0)); 00100 if (KEncodingDetector::hasAutoDetectionForScript(scri)) 00101 { 00102 tmp->addAction(i18nc("Encodings menu","Autodetect"))->setData(QVariant((uint)scri)); 00103 tmp->menu()->addSeparator(); 00104 } 00105 } 00106 for (i=1; i<encodingsForScript.size(); ++i) 00107 { 00108 tmp->addAction(encodingsForScript.at(i)); 00109 } 00110 q->connect(tmp,SIGNAL(triggered(QAction*)),q,SLOT(_k_subActionTriggered(QAction*))); 00111 tmp->setCheckable(true); 00112 q->addAction(tmp); 00113 } 00114 q->setCurrentItem(0); 00115 } 00116 00117 int KCodecAction::mibForName(const QString &codecName, bool *ok) const 00118 { 00119 // FIXME logic is good but code is ugly 00120 00121 bool success = false; 00122 int mib = MIB_DEFAULT; 00123 KCharsets *charsets = KGlobal::charsets(); 00124 00125 if (codecName == d->defaultAction->text()) 00126 success = true; 00127 else 00128 { 00129 QTextCodec *codec = charsets->codecForName(codecName, success); 00130 if (!success) 00131 { 00132 // Maybe we got a description name instead 00133 codec = charsets->codecForName(charsets->encodingForName(codecName), success); 00134 } 00135 00136 if (codec) 00137 mib = codec->mibEnum(); 00138 } 00139 00140 if (ok) 00141 *ok = success; 00142 00143 if (success) 00144 return mib; 00145 00146 kWarning() << "Invalid codec name: " << codecName; 00147 return MIB_DEFAULT; 00148 } 00149 00150 QTextCodec *KCodecAction::codecForMib(int mib) const 00151 { 00152 if (mib == MIB_DEFAULT) 00153 { 00154 // FIXME offer to change the default codec 00155 return QTextCodec::codecForLocale(); 00156 } 00157 else 00158 return QTextCodec::codecForMib(mib); 00159 } 00160 00161 void KCodecAction::actionTriggered(QAction *action) 00162 { 00163 //we don't want to emit any signals from top-level items 00164 //except for the default one 00165 if (action==d->defaultAction) 00166 { 00167 emit triggered(KEncodingDetector::SemiautomaticDetection); 00168 emit defaultItemTriggered(); 00169 } 00170 } 00171 00172 void KCodecAction::Private::_k_subActionTriggered(QAction *action) 00173 { 00174 if (currentSubAction==action) 00175 return; 00176 currentSubAction=action; 00177 bool ok = false; 00178 int mib = q->mibForName(action->text(), &ok); 00179 if (ok) 00180 { 00181 emit q->triggered(action->text()); 00182 emit q->triggered(q->codecForMib(mib)); 00183 } 00184 else 00185 { 00186 if (!action->data().isNull()) 00187 emit q->triggered((KEncodingDetector::AutoDetectScript) action->data().toUInt()); 00188 } 00189 } 00190 00191 QTextCodec *KCodecAction::currentCodec() const 00192 { 00193 return codecForMib(currentCodecMib()); 00194 } 00195 00196 bool KCodecAction::setCurrentCodec( QTextCodec *codec ) 00197 { 00198 if (!codec) 00199 return false; 00200 00201 int i,j; 00202 for (i=0;i<actions().size();++i) 00203 { 00204 if (actions().at(i)->menu()) 00205 { 00206 for (j=0;j<actions().at(i)->menu()->actions().size();++j) 00207 { 00208 if (!j && !actions().at(i)->menu()->actions().at(j)->data().isNull()) 00209 continue; 00210 if (codec==KGlobal::charsets()->codecForName(actions().at(i)->menu()->actions().at(j)->text())) 00211 { 00212 d->currentSubAction=actions().at(i)->menu()->actions().at(j); 00213 d->currentSubAction->trigger(); 00214 return true; 00215 } 00216 } 00217 } 00218 } 00219 return false; 00220 00221 } 00222 00223 QString KCodecAction::currentCodecName() const 00224 { 00225 return d->currentSubAction->text(); 00226 } 00227 00228 bool KCodecAction::setCurrentCodec( const QString &codecName ) 00229 { 00230 return setCurrentCodec(KGlobal::charsets()->codecForName(codecName)); 00231 } 00232 00233 int KCodecAction::currentCodecMib() const 00234 { 00235 return mibForName(currentCodecName()); 00236 } 00237 00238 bool KCodecAction::setCurrentCodec( int mib ) 00239 { 00240 if (mib == MIB_DEFAULT) 00241 return setCurrentAction(d->defaultAction); 00242 else 00243 return setCurrentCodec(codecForMib(mib)); 00244 } 00245 00246 KEncodingDetector::AutoDetectScript KCodecAction::currentAutoDetectScript() const 00247 { 00248 return d->currentSubAction->data().isNull()? 00249 KEncodingDetector::None : 00250 (KEncodingDetector::AutoDetectScript)d->currentSubAction->data().toUInt(); 00251 } 00252 00253 bool KCodecAction::setCurrentAutoDetectScript(KEncodingDetector::AutoDetectScript scri) 00254 { 00255 if (scri==KEncodingDetector::SemiautomaticDetection) 00256 { 00257 d->currentSubAction=d->defaultAction; 00258 d->currentSubAction->trigger(); 00259 return true; 00260 } 00261 00262 int i; 00263 for (i=0;i<actions().size();++i) 00264 { 00265 if (actions().at(i)->menu()) 00266 { 00267 if (!actions().at(i)->menu()->actions().isEmpty() 00268 &&!actions().at(i)->menu()->actions().at(0)->data().isNull() 00269 &&actions().at(i)->menu()->actions().at(0)->data().toUInt()==(uint)scri 00270 ) 00271 { 00272 d->currentSubAction=actions().at(i)->menu()->actions().at(0); 00273 d->currentSubAction->trigger(); 00274 return true; 00275 } 00276 } 00277 } 00278 return false; 00279 } 00280 00281 #include "kcodecaction.moc"
KDE 4.6 API Reference