DlgKeyboardImp.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2005 Werner Mayer <wmayer[at]users.sourceforge.net>     *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 #ifndef _PreComp_
00026 # include <QHeaderView>
00027 # include <QMessageBox>
00028 #endif
00029 
00030 #include <Base/Parameter.h>
00031 
00032 #include "DlgKeyboardImp.h"
00033 #include "Action.h"
00034 #include "Application.h"
00035 #include "BitmapFactory.h"
00036 #include "Command.h"
00037 #include "Widgets.h"
00038 #include "Window.h"
00039 
00040 using namespace Gui::Dialog;
00041 
00042 namespace Gui { namespace Dialog {
00043 typedef std::vector< std::pair<QLatin1String, QString> > GroupMap;
00044 
00045 struct GroupMap_find {
00046     const QLatin1String& item;
00047     GroupMap_find(const QLatin1String& item) : item(item) {}
00048     bool operator () (const std::pair<QLatin1String, QString>& elem) const
00049     {
00050         return elem.first == item;
00051     }
00052 };
00053 }
00054 }
00055 
00056 /* TRANSLATOR Gui::Dialog::DlgCustomKeyboardImp */
00057 
00065 DlgCustomKeyboardImp::DlgCustomKeyboardImp( QWidget* parent  )
00066   : CustomizeActionPage(parent), firstShow(true)
00067 {
00068     this->setupUi(this);
00069 
00070     CommandManager & cCmdMgr = Application::Instance->commandManager();
00071     std::map<std::string,Command*> sCommands = cCmdMgr.getCommands();
00072 
00073     GroupMap groupMap;
00074     groupMap.push_back(std::make_pair(QLatin1String("File"), QString()));
00075     groupMap.push_back(std::make_pair(QLatin1String("Edit"), QString()));
00076     groupMap.push_back(std::make_pair(QLatin1String("View"), QString()));
00077     groupMap.push_back(std::make_pair(QLatin1String("Standard-View"), QString()));
00078     groupMap.push_back(std::make_pair(QLatin1String("Tools"), QString()));
00079     groupMap.push_back(std::make_pair(QLatin1String("Window"), QString()));
00080     groupMap.push_back(std::make_pair(QLatin1String("Help"), QString()));
00081     groupMap.push_back(std::make_pair(QLatin1String("Macros"), qApp->translate("Gui::MacroCommand", "Macros")));
00082 
00083     for (std::map<std::string,Command*>::iterator it = sCommands.begin(); it != sCommands.end(); ++it) {
00084         QLatin1String group(it->second->getGroupName());
00085         QString text = qApp->translate(it->second->className(), it->second->getGroupName());
00086         GroupMap::iterator jt;
00087         jt = std::find_if(groupMap.begin(), groupMap.end(), GroupMap_find(group));
00088         if (jt != groupMap.end())
00089             jt->second = text;
00090         else
00091             groupMap.push_back(std::make_pair(group, text));
00092     }
00093 
00094     int index = 0;
00095     for (GroupMap::iterator it = groupMap.begin(); it != groupMap.end(); ++it, ++index) {
00096         categoryBox->addItem(it->second);
00097         categoryBox->setItemData(index, QVariant(it->first), Qt::UserRole);
00098     }
00099 
00100     QStringList labels; 
00101     labels << tr("Icon") << tr("Command");
00102     commandTreeWidget->setHeaderLabels(labels);
00103     commandTreeWidget->header()->hide();
00104     assignedTreeWidget->setHeaderLabels(labels);
00105     assignedTreeWidget->header()->hide();
00106 }
00107 
00109 DlgCustomKeyboardImp::~DlgCustomKeyboardImp()
00110 {
00111 }
00112 
00113 void DlgCustomKeyboardImp::showEvent(QShowEvent* e)
00114 {
00115     // If we did this already in the constructor we wouldn't get the vertical scrollbar if needed.
00116     // The problem was noticed with Qt 4.1.4 but may arise with any later version.
00117     if (firstShow) {
00118         on_categoryBox_activated(categoryBox->currentIndex());
00119         firstShow = false;
00120     }
00121 }
00122 
00124 void DlgCustomKeyboardImp::on_commandTreeWidget_currentItemChanged(QTreeWidgetItem* item)
00125 {
00126     if (!item)
00127         return;
00128 
00129     QVariant data = item->data(1, Qt::UserRole);
00130     QByteArray name = data.toByteArray(); // command name
00131 
00132     CommandManager & cCmdMgr = Application::Instance->commandManager();
00133     Command* cmd = cCmdMgr.getCommandByName(name.constData());
00134     if (cmd) {
00135         if (cmd->getAction()) {
00136             QKeySequence ks = cmd->getAction()->shortcut();
00137             QKeySequence ks2 = QString::fromAscii(cmd->getAccel());
00138             QKeySequence ks3 = editShortcut->text();
00139 
00140             if (ks.isEmpty())
00141                 accelLineEditShortcut->setText( tr("none") );
00142             else
00143                 accelLineEditShortcut->setText(ks);
00144 
00145             buttonAssign->setEnabled(!editShortcut->text().isEmpty() && (ks != ks3));
00146             buttonReset->setEnabled((ks != ks2));
00147         } else {
00148           QKeySequence ks = QString::fromAscii(cmd->getAccel());
00149             if (ks.isEmpty())
00150                 accelLineEditShortcut->setText( tr("none") );
00151             else
00152                 accelLineEditShortcut->setText(ks);
00153             buttonAssign->setEnabled(false);
00154             buttonReset->setEnabled(false);
00155         }
00156     }
00157 
00158     textLabelDescription->setText(item->toolTip(1));
00159 }
00160 
00162 void DlgCustomKeyboardImp::on_categoryBox_activated(int index)
00163 {
00164     QVariant data = categoryBox->itemData(index, Qt::UserRole);
00165     QString group = data.toString();
00166     commandTreeWidget->clear();
00167     buttonAssign->setEnabled(false);
00168     buttonReset->setEnabled(false);
00169     accelLineEditShortcut->clear();
00170     editShortcut->clear();
00171 
00172     CommandManager & cCmdMgr = Application::Instance->commandManager();
00173     std::vector<Command*> aCmds = cCmdMgr.getGroupCommands( group.toAscii() );
00174     for (std::vector<Command*>::iterator it = aCmds.begin(); it != aCmds.end(); ++it) {
00175         QTreeWidgetItem* item = new QTreeWidgetItem(commandTreeWidget);
00176         item->setText(1, qApp->translate((*it)->className(), (*it)->getMenuText()));
00177         item->setToolTip(1, qApp->translate((*it)->className(), (*it)->getToolTipText()));
00178         item->setData(1, Qt::UserRole, QByteArray((*it)->getName()));
00179         item->setSizeHint(0, QSize(32, 32));
00180         item->setBackgroundColor(0, Qt::lightGray);
00181         if ((*it)->getPixmap())
00182             item->setIcon(0, BitmapFactory().pixmap((*it)->getPixmap()));
00183     }
00184 
00185     commandTreeWidget->resizeColumnToContents(0);
00186 }
00187 
00189 void DlgCustomKeyboardImp::on_buttonAssign_clicked()
00190 {
00191     QTreeWidgetItem* item = commandTreeWidget->currentItem();
00192     if (!item)
00193         return;
00194 
00195     QVariant data = item->data(1, Qt::UserRole);
00196     QByteArray name = data.toByteArray(); // command name
00197 
00198     CommandManager & cCmdMgr = Application::Instance->commandManager();
00199     Command* cmd = cCmdMgr.getCommandByName(name.constData());
00200     if (cmd && cmd->getAction()) {
00201         QKeySequence shortcut = editShortcut->text();
00202         cmd->getAction()->setShortcut(shortcut);
00203         accelLineEditShortcut->setText(editShortcut->text());
00204         editShortcut->clear();
00205 
00206         ParameterGrp::handle hGrp = WindowParameter::getDefaultParameter()->GetGroup("Shortcut");
00207         hGrp->SetASCII(name.constData(), accelLineEditShortcut->text().toAscii());
00208         buttonAssign->setEnabled(false);
00209         buttonReset->setEnabled(true);
00210     }
00211 }
00212 
00214 void DlgCustomKeyboardImp::on_buttonReset_clicked()
00215 {
00216     QTreeWidgetItem* item = commandTreeWidget->currentItem();
00217     if (!item)
00218         return;
00219 
00220     QVariant data = item->data(1, Qt::UserRole);
00221     QByteArray name = data.toByteArray(); // command name
00222 
00223     CommandManager & cCmdMgr = Application::Instance->commandManager();
00224     Command* cmd = cCmdMgr.getCommandByName(name.constData());
00225     if (cmd && cmd->getAction()) {
00226       cmd->getAction()->setShortcut(QString::fromAscii(cmd->getAccel()));
00227         QString txt = cmd->getAction()->shortcut();
00228         accelLineEditShortcut->setText((txt.isEmpty() ? tr("none") : txt));
00229         ParameterGrp::handle hGrp = WindowParameter::getDefaultParameter()->GetGroup("Shortcut");
00230         hGrp->RemoveASCII(name.constData());
00231     }
00232 
00233     buttonReset->setEnabled( false );
00234 }
00235 
00237 void DlgCustomKeyboardImp::on_buttonResetAll_clicked()
00238 {
00239     CommandManager & cCmdMgr = Application::Instance->commandManager();
00240     std::vector<Command*> cmds = cCmdMgr.getAllCommands();
00241     for (std::vector<Command*>::iterator it = cmds.begin(); it != cmds.end(); ++it) {
00242         if ((*it)->getAction()) {
00243           (*it)->getAction()->setShortcut(QKeySequence(QString::fromAscii((*it)->getAccel())));
00244         }
00245     }
00246 
00247     WindowParameter::getDefaultParameter()->RemoveGrp("Shortcut");
00248     buttonReset->setEnabled(false);
00249 }
00250 
00252 void DlgCustomKeyboardImp::on_editShortcut_textChanged(const QString& sc)
00253 {
00254     assignedTreeWidget->clear();
00255     QTreeWidgetItem* item = commandTreeWidget->currentItem();
00256     if (!item)
00257         return;
00258     QVariant data = item->data(1, Qt::UserRole);
00259     QByteArray name = data.toByteArray(); // command name
00260 
00261     CommandManager & cCmdMgr = Application::Instance->commandManager();
00262     Command* cmd = cCmdMgr.getCommandByName(name.constData());
00263     if (cmd && !cmd->getAction()) {
00264         buttonAssign->setEnabled(false); // command not in use
00265         return;
00266     }
00267 
00268     buttonAssign->setEnabled(true);
00269     QKeySequence ks(sc);
00270     if (!ks.isEmpty()) {
00271         int countAmbiguous = 0;
00272         QString ambiguousCommand;
00273         QString ambiguousMenu;
00274 
00275         CommandManager & cCmdMgr = Application::Instance->commandManager();
00276         std::vector<Command*> cmds = cCmdMgr.getAllCommands();
00277         for (std::vector<Command*>::iterator it = cmds.begin(); it != cmds.end(); ++it) {
00278             if ((*it)->getAction() && (*it)->getAction()->shortcut() == ks) {
00279                 ++countAmbiguous;
00280                 ambiguousCommand = QString::fromAscii((*it)->getName()); // store the last one
00281                 ambiguousMenu = qApp->translate((*it)->className(), (*it)->getMenuText());
00282 
00283                 QTreeWidgetItem* item = new QTreeWidgetItem(assignedTreeWidget);
00284                 item->setText(1, qApp->translate((*it)->className(), (*it)->getMenuText()));
00285                 item->setToolTip(1, qApp->translate((*it)->className(), (*it)->getToolTipText()));
00286                 item->setData(1, Qt::UserRole, QByteArray((*it)->getName()));
00287                 item->setSizeHint(0, QSize(32, 32));
00288                 item->setBackgroundColor(0, Qt::lightGray);
00289                 if ((*it)->getPixmap())
00290                     item->setIcon(0, BitmapFactory().pixmap((*it)->getPixmap()));
00291             }
00292         }
00293 
00294         if (countAmbiguous > 0)
00295             assignedTreeWidget->resizeColumnToContents(0);
00296         
00297         if (countAmbiguous > 1) {
00298             QMessageBox::warning(this, tr("Multiple defined shortcut"),
00299                                  tr("The shortcut '%1' is defined more than once. This could result into unexpected behaviour.").arg(sc) );
00300             editShortcut->setFocus();
00301             buttonAssign->setEnabled(false);
00302         } else if (countAmbiguous == 1 && ambiguousCommand != QLatin1String(name)) {
00303             QMessageBox::warning(this, tr("Already defined shortcut"),
00304                                  tr("The shortcut '%1' is already assigned to '%2'.\n\nPlease define another shortcut.").arg(sc).arg(ambiguousMenu) );
00305             editShortcut->setFocus();
00306             buttonAssign->setEnabled(false);
00307         } else {
00308             if (cmd && cmd->getAction() && cmd->getAction()->shortcut() == ks)
00309                 buttonAssign->setEnabled(false);
00310         }
00311     } else {
00312         if (cmd && cmd->getAction() && cmd->getAction()->shortcut().isEmpty())
00313             buttonAssign->setEnabled(false); // both key sequences are empty
00314     }
00315 }
00316 
00317 void DlgCustomKeyboardImp::onAddMacroAction(const QByteArray& macro)
00318 {
00319     QVariant data = categoryBox->itemData(categoryBox->currentIndex(), Qt::UserRole);
00320     QString group = data.toString();
00321     if (group == QLatin1String("Macros"))
00322     {
00323         CommandManager & cCmdMgr = Application::Instance->commandManager();
00324         Command* pCmd = cCmdMgr.getCommandByName(macro);
00325 
00326         QTreeWidgetItem* item = new QTreeWidgetItem(commandTreeWidget);
00327         item->setText(1, QString::fromUtf8(pCmd->getMenuText()));
00328         item->setToolTip(1, QString::fromUtf8(pCmd->getToolTipText()));
00329         item->setData(1, Qt::UserRole, macro);
00330         item->setSizeHint(0, QSize(32, 32));
00331         item->setBackgroundColor(0, Qt::lightGray);
00332         if (pCmd->getPixmap())
00333             item->setIcon(0, BitmapFactory().pixmap(pCmd->getPixmap()));
00334     }
00335 }
00336 
00337 void DlgCustomKeyboardImp::onRemoveMacroAction(const QByteArray& macro)
00338 {
00339     QVariant data = categoryBox->itemData(categoryBox->currentIndex(), Qt::UserRole);
00340     QString group = data.toString();
00341     if (group == QLatin1String("Macros"))
00342     {
00343         for (int i=0; i<commandTreeWidget->topLevelItemCount(); i++) {
00344             QTreeWidgetItem* item = commandTreeWidget->topLevelItem(i);
00345             QByteArray command = item->data(1, Qt::UserRole).toByteArray();
00346             if (command == macro) {
00347                 commandTreeWidget->takeTopLevelItem(i);
00348                 delete item;
00349                 break;
00350             }
00351         }
00352     }
00353 }
00354 
00355 void DlgCustomKeyboardImp::onModifyMacroAction(const QByteArray& macro)
00356 {
00357     QVariant data = categoryBox->itemData(categoryBox->currentIndex(), Qt::UserRole);
00358     QString group = data.toString();
00359     if (group == QLatin1String("Macros"))
00360     {
00361         CommandManager & cCmdMgr = Application::Instance->commandManager();
00362         Command* pCmd = cCmdMgr.getCommandByName(macro);
00363         for (int i=0; i<commandTreeWidget->topLevelItemCount(); i++) {
00364             QTreeWidgetItem* item = commandTreeWidget->topLevelItem(i);
00365             QByteArray command = item->data(1, Qt::UserRole).toByteArray();
00366             if (command == macro) {
00367                 item->setText(1, QString::fromUtf8(pCmd->getMenuText()));
00368                 item->setToolTip(1, QString::fromUtf8(pCmd->getToolTipText()));
00369                 item->setData(1, Qt::UserRole, macro);
00370                 item->setSizeHint(0, QSize(32, 32));
00371                 item->setBackgroundColor(0, Qt::lightGray);
00372                 if (pCmd->getPixmap())
00373                     item->setIcon(0, BitmapFactory().pixmap(pCmd->getPixmap()));
00374                 if (commandTreeWidget->isItemSelected(item))
00375                     textLabelDescription->setText(item->toolTip(1));
00376                 break;
00377             }
00378         }
00379     }
00380 }
00381 
00382 void DlgCustomKeyboardImp::changeEvent(QEvent *e)
00383 {
00384     if (e->type() == QEvent::LanguageChange) {
00385         this->retranslateUi(this);
00386         int count = categoryBox->count();
00387 
00388         CommandManager & cCmdMgr = Application::Instance->commandManager();
00389         for (int i=0; i<count; i++) {
00390             QVariant data = categoryBox->itemData(i, Qt::UserRole);
00391             std::vector<Command*> aCmds = cCmdMgr.getGroupCommands(data.toByteArray());
00392             if (!aCmds.empty()) {
00393                 QString text = qApp->translate(aCmds[0]->className(), aCmds[0]->getGroupName());
00394                 categoryBox->setItemText(i, text);
00395             }
00396         }
00397         on_categoryBox_activated(categoryBox->currentIndex());
00398     }
00399     QWidget::changeEvent(e);
00400 }
00401 
00402 #include "moc_DlgKeyboardImp.cpp"

Generated on Wed Nov 23 19:00:06 2011 for FreeCAD by  doxygen 1.6.1