00001 #include "MenuLauncher.h"
00002 extern QWidget* g_Widget;
00003
00004 MenuLauncher::MenuLauncher(const QString& kind) : m_kind(kind)
00005 {
00006 qDebug("MenuLauncher::MenuLauncher()");
00007 m_pMenu = m_pTopMenu = NULL;
00008
00009 m_isShowing = false;
00010 m_id = -1;
00011
00012 m_pTimer = new QTimer(this);
00013 connect(m_pTimer, SIGNAL(timeout()),
00014 this, SLOT(select()));
00015
00016 init();
00017 }
00018
00019 MenuLauncher::~MenuLauncher()
00020 {
00021 qDebug("MenuLauncher::~MenuLauncher()");
00022 delete m_pTopMenu;
00023 delete m_pTimer;
00024 }
00025
00026 void MenuLauncher::init()
00027 {
00028 buildMenu();
00029 }
00030
00031 QPopupMenu* MenuLauncher::initMenu(QWidget* parent, const QString& name)
00032 {
00033 QPopupMenu* pMenu;
00034 pMenu = new QPopupMenuEx(parent, name);
00035 pMenu->installEventFilter(this);
00036 connect(pMenu, SIGNAL(activated(int)), this, SLOT(select(int)));
00037 connect(pMenu, SIGNAL(highlighted(int)), this, SLOT(highlight(int)));
00038
00039 return(pMenu);
00040 }
00041
00042 bool MenuLauncher::onKeyPress(int )
00043 {
00044 if(m_isShowing){
00045 qDebug("showing ...");
00046 } else if(m_pMenu->isVisible()){
00047 next();
00048 } else {
00049 ConfigEx& cfg = ConfigEx::getInstance("keyhelper");
00050 cfg.setGroup("Global");
00051 int delay = cfg.readNumEntry("DelayPopup", 5);
00052 QTimer::singleShot(delay, this, SLOT(show()));
00053 m_isShowing = true;
00054 }
00055 return true;
00056 }
00057
00058 bool MenuLauncher::onModRelease(int )
00059 {
00060 if(m_pMenu->isVisible()){
00061 QTimer::singleShot(0, this, SLOT(select()));
00062 return(true);
00063 } else {
00064 return(false);
00065 }
00066 }
00067
00068 QString MenuLauncher::getMenuText(const QString& key, const QString& name)
00069 {
00070 QRegExp rx("^[0-9]+_");
00071 QString text;
00072 QString ackey;
00073 int len;
00074 if(rx.match(key, 0, &len) == 0){
00075 ackey = key.mid(len);
00076 } else {
00077 ackey = key;
00078 }
00079 if(ackey.length() == 1){
00080 text = name;
00081 text.append("(&");
00082 text.append(ackey);
00083 text.append(")");
00084 } else {
00085 text = ackey;
00086 }
00087 return(text);
00088 }
00089
00090 int MenuLauncher::buildMenu(const QString& section,
00091 QPopupMenu* pMenu, int& id)
00092 {
00093 ConfigEx& cfg = ConfigEx::getInstance("keyhelper");
00094
00095 if(m_oMenuList.contains(pMenu)){
00096
00097 return(0);
00098 }
00099 m_oMenuList.append(pMenu);
00100
00101 QString oldgroup = cfg.getGroup();
00102
00103 QString group = section;
00104 group[0] = group[0].upper();
00105
00106 cfg.setGroup(group);
00107
00108 QStringList apps = cfg.getKeys();
00109 int cnt = 0;
00110 if(apps.isEmpty() == false){
00111 for(QStringList::Iterator it=apps.begin();
00112 it!=apps.end(); ++it){
00113 QStringList args = cfg.readListEntry(*it, '\t');
00114 LnkWrapper lnk(args);
00115 if(lnk.isValid()){
00116 cnt++;
00117 QString text = getMenuText(*it, lnk.instance().name());
00118 if(args[0] == "@menu"){
00119 QPopupMenu* pSubMenu = initMenu(m_pTopMenu, args[1]);
00120 pMenu->insertItem(lnk.instance().pixmap(), text,
00121 pSubMenu, id);
00122 m_oItemList.append(ItemInfo(section));
00123 id++;
00124 buildMenu(args[1], pSubMenu, id);
00125 } else {
00126 pMenu->insertItem(lnk.instance().pixmap(), text, id);
00127 m_oItemList.append(ItemInfo(section, *it));
00128 id++;
00129 }
00130 }
00131 }
00132 }
00133 cfg.setGroup(oldgroup);
00134 return(cnt);
00135 }
00136
00137 void MenuLauncher::clearSubMenu()
00138 {
00139 for(QValueList<QPopupMenu*>::Iterator it=m_oMenuList.begin();
00140 it!=m_oMenuList.end(); ++it){
00141 if(*it != m_pTopMenu){
00142 delete *it;
00143 }
00144 }
00145 m_oMenuList.clear();
00146 m_oItemList.clear();
00147 }
00148
00149 int MenuLauncher::buildMenu(bool force)
00150 {
00151 ConfigEx& cfg = ConfigEx::getInstance("keyhelper");
00152 if(!force && m_lastmodify == cfg.lastRead()){
00153 return(m_pTopMenu->count());
00154 }
00155 qDebug("buildMenu");
00156
00157 QString oldgroup = cfg.getGroup();
00158
00159 cfg.setGroup("Global");
00160 m_submenuTimeout = cfg.readNumEntry("SubMenuTimeout", 500);
00161
00162 if(m_pTopMenu){
00163 delete m_pTopMenu;
00164 }
00165 m_pMenu = m_pTopMenu = initMenu(g_Widget, kind());
00166 m_oLastId.clear();
00167 m_oMenuList.clear();
00168 m_oItemList.clear();
00169
00170 MenuTitle* pTitle = new MenuTitle("MenuLauncher",
00171 m_pTopMenu->font(), kind());
00172 m_pTopMenu->insertItem(pTitle);
00173
00174 int id = 0;
00175 int cnt = buildMenu(kind(), m_pTopMenu, id);
00176 if(cnt > 0){
00177 m_lastmodify = cfg.lastRead();
00178 }
00179
00180 cfg.setGroup(oldgroup);
00181 return(cnt);
00182 }
00183
00184 void MenuLauncher::show()
00185 {
00186 m_enablePopup = false;
00187 int cnt = buildMenu();
00188 if(cnt > 0){
00189 m_pMenu = m_pTopMenu;
00190 ConfigEx& cfg = ConfigEx::getInstance("keyhelper");
00191 cfg.setGroup("Style");
00192 int x,y;
00193 QString key = "Position_" + kind();
00194 if(cfg.hasKey(key)){
00195 const QStringList& list = cfg.readListEntry(key, ',');
00196 x = list[0].toInt();
00197 y = list[1].toInt();
00198 } else {
00199 x = (qt_screen->width() - m_pTopMenu->sizeHint().width()) / 2;
00200 y = (qt_screen->height() - m_pTopMenu->sizeHint().height()) / 2;
00201 }
00202 QPoint pos(x, y);
00203 m_pTopMenu->popup(pos);
00204 m_pTopMenu->setActiveItem(1);
00205 }
00206 m_isShowing = false;
00207 }
00208
00209 void MenuLauncher::next()
00210 {
00211 int index = m_pMenu->indexOf(m_id);
00212 index++;
00213 if(index >= (signed int)m_pMenu->count()){
00214 if(m_pMenu == m_pTopMenu){
00215 index = 1;
00216 } else {
00217 index = 0;
00218 }
00219 }
00220 m_pMenu->setActiveItem(index);
00221 m_id = m_pMenu->idAt(index);
00222 }
00223
00224 void MenuLauncher::select()
00225 {
00226 if(m_pMenu->isVisible()){
00227 QMenuItem* item = m_pMenu->findItem(m_id);
00228 int index = m_pMenu->indexOf(m_id);
00229 QPopupMenu* p = m_pMenu;
00230
00231 if(item && item->popup()){
00232 m_pMenu = item->popup();
00233 }
00234 p->activateItemAt(index);
00235 }
00236 }
00237
00238 void MenuLauncher::select(int id)
00239 {
00240 if(id >= 0 && m_oItemList[id].entry != QString::null){
00241 ConfigEx& cfg = ConfigEx::getInstance("keyhelper");
00242
00243 cfg.setGroup("Global");
00244 int delay = cfg.readNumEntry("DelayExec", 100);
00245
00246 QString group = m_oItemList[id].group;
00247 group[0] = group[0].upper();
00248 cfg.setGroup(group);
00249
00250
00251 m_args = cfg.readListEntry(m_oItemList[id].entry, '\t');
00252
00253 #if 0
00254 LnkWrapper lnk(args);
00255 if(lnk.isValid()){
00256 lnk.instance().execute();
00257 }
00258 #else
00259 QTimer::singleShot(delay, this, SLOT(execute()));
00260 #endif
00261 }
00262 m_pMenu = m_pTopMenu;
00263 m_id = -1;
00264 }
00265
00266 void MenuLauncher::execute()
00267 {
00268 LnkWrapper lnk(m_args);
00269 if(lnk.isValid()){
00270 lnk.instance().execute();
00271 }
00272 m_args.clear();
00273 }
00274
00275 void MenuLauncher::highlight(int id)
00276 {
00277 if(m_pMenu && m_pMenu->isVisible()){
00278 m_id = id;
00279 if(m_enablePopup){
00280 QMenuItem* item = m_pMenu->findItem(m_id);
00281 if(item && item->popup()){
00282 if(m_submenuTimeout > 0){
00283 m_pTimer->start(m_submenuTimeout, true);
00284 }
00285 } else {
00286 m_pTimer->stop();
00287 }
00288 } else {
00289
00290 m_enablePopup = true;
00291 }
00292 }
00293 }
00294
00295 bool MenuLauncher::eventFilter(QObject* o, QEvent* e)
00296 {
00297 if(m_pTopMenu->isVisible()){
00298 QKeyEvent* ke = (QKeyEvent*)e;
00299 switch(e->type()){
00300 case QEvent::Accel:
00301 if(ke->key() == Qt::Key_Space
00302 && ke->isAutoRepeat() == false){
00303 select();
00304 }
00305 break;
00306 case QEvent::FocusIn:
00307
00308 m_pMenu = (QPopupMenu*)o;
00309 if(m_oLastId.contains(o)){
00310 m_id = m_oLastId[o];
00311 }
00312 m_pMenu->updateItem(m_id);
00313 break;
00314 case QEvent::FocusOut:
00315
00316 m_oLastId[o] = m_id;
00317 break;
00318 default:
00319
00320 break;
00321 }
00322 }
00323 return QObject::eventFilter(o, e);
00324 }