/*************************************************************************** * fqterm, a terminal emulator for both BBS and *nix. * * Copyright (C) 2008 fqterm development group. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * ***************************************************************************/ #if !defined(WIN32) #include #endif #if defined(__linux__) || defined(__GLIBC__) #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "aboutdialog.h" #include "addrdialog.h" #include "common.h" #include "keydialog.h" #include "prefdialog.h" #include "fqterm.h" #include "fqterm_path.h" #include "fqterm_config.h" #include "fqterm_frame.h" #include "fqterm_param.h" #include "fqterm_session.h" #include "fqterm_screen.h" #include "fqterm_time_label.h" #include "fqterm_tool_button.h" #include "fqterm_window.h" #include "fqterm_wndmgr.h" #ifdef IMAGE_USE_PICFLOW #include "imageviewer.h" #else #include "imageviewer_origin.h" #endif #include "quickdialog.h" #include "statusBar.h" #include "sitemanager.h" #include "fqterm_shortcuthelper.h" #include "shortcutdialog.h" #include "schemadialog.h" #include "fqterm_ip_location.h" #include "iplookup.h" #include "defineescape.h" #include "uaocodec.h" #include "connect_info.h" #ifdef USE_DOTNET_STYLE #include "dotnetstyle.h" #endif //USE_DOTNET_STYLE #ifdef USE_GLOBAL_HOTKEY #include "qxtglobalshortcut.h" #endif //USE_GLOBAL_HOTKEY #ifdef HAVE_PYTHON #include #include "fqterm_python.h" #endif //HAVE_PYTHON namespace FQTerm { const QString FQTermFrame::qmPrefix[FQTermFrame::translatedModule] = {"fqterm_", "ui_", "protocol_", "common_"}; const QString FQTermFrame::qmPostfix = ".qm"; //constructor FQTermFrame::FQTermFrame() : QMainWindow(0), tray_(0), trayMenu_(0), #ifdef HAVE_PYTHON pythonHelper_(0), #endif #ifdef USE_GLOBAL_HOTKEY globalHotkey_(0), #endif //USE_GLOBAL_HOTKEY shortcutHelper_(0) { setAttribute(Qt::WA_DeleteOnClose); /*#ifndef __APPLE__ setWindowFlags(Qt::CustomizeWindowHint); #endif*/ uaoCodec_ = new UAOCodec; config_ = new FQTermConfig(getPath(USER_CONFIG) + "fqterm.cfg"); initTranslator(); shortcutHelper_ = new FQTermShortcutHelper(config_, this); #ifdef IMAGE_USE_PICFLOW imageViewer_ = new FQTermImageFlow(config_, NULL, Qt::Window); #else imageViewer_ = new FQTermImageOrigin(config_, NULL, Qt::Window); #endif //create the window manager to deal with the window-tab-icon pairs windowManager_ = new FQTermWndMgr(this); setCentralWidget(windowManager_); //set menubar addMainMenu(); FQ_VERIFY(connect(this, SIGNAL(changeLanguage()), this, SLOT(recreateMenu()))); //initialize all settings //This should be done before add main tool, since some status of tool will depend on setting iniSetting(); FQTermConfig* conf = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg"); checkHelpExists(conf); delete conf; //setup toolbar addMainTool(); // add the custom defined key // and load toolbar position updateKeyToolBar(); loadToolBarPosition(); enableMenuToolBar(false); // FIXME: !!!create a horizonal layout to hold the tabbar,the reason //of why not put the tabbar directly on the status bar is when no //tab in the tabbar,the statusbar display a horizonal line,ugly. //perhaps there is some function in statusbar to solve this. QWidget *hb = new QWidget(statusBar()); hb->setObjectName("taskbar"); QHBoxLayout *hbLayout = new QHBoxLayout(hb); hbLayout->setMargin(0); hbLayout->setObjectName("tasklayout"); statusBar()->addWidget(hb); //create a tabbar in the hbox hbLayout->addWidget(windowManager_->tabBar()); windowMapper_ = new QSignalMapper(this); FQ_VERIFY(connect(windowMapper_, SIGNAL(mapped(int)), windowManager_, SLOT(activateTheWindow(int)))); initAdditionalActions(); //create a progress bar to notify the download process statusBar_ = new FQTerm::StatusBar(statusBar(), "mainStatusBar"); statusBar()->addWidget(statusBar_, 0); installEventFilter(this); #ifdef HAVE_PYTHON pythonHelper_ = new FQTermPythonHelper; #endif #ifdef USE_GLOBAL_HOTKEY globalHotkey_ = new QxtGlobalShortcut(shortcutHelper_->getAction(FQTermShortcutHelper::GLOBAL_SHOW_FQTERM)->shortcut(), this); FQ_VERIFY(connect(shortcutHelper_->getAction(FQTermShortcutHelper::GLOBAL_SHOW_FQTERM), SIGNAL(changed()), this, SLOT(globalHotkeyChanged()))); FQ_VERIFY(connect(globalHotkey_, SIGNAL(activated()), this, SLOT(globalHotkeyTriggered()))); #endif //USE_GLOBAL_HOTKEY } //destructor FQTermFrame::~FQTermFrame() { #ifdef USE_GLOBAL_HOTKEY delete globalHotkey_; #endif //USE_GLOBAL_HOTKEY #ifdef HAVE_PYTHON delete pythonHelper_; #endif //HAVE_PYTHON clearTranslator(); delete imageViewer_; delete shortcutHelper_; delete config_; // should not delete yourself!! // http://qt-project.org/doc/qt-5/qtextcodec.html#dtor.QTextCodec // delete uaoCodec_; delete windowManager_; FQTermIPLocation::Destroy(); } //initialize setting from fqterm.cfg void FQTermFrame::iniSetting() { QString strTmp; strTmp = config_->getItemValue("global", "fullscreen"); if (strTmp == "1") { getAction(FQTermShortcutHelper::FULLSCREEN)->setChecked(true); showFullScreen(); } else { //window size strTmp = config_->getItemValue("global", "max"); if (strTmp == "1") { showMaximized(); } else { QString size = config_->getItemValue("global", "size"); if (size != "") { int x, y, cx, cy; sscanf(size.toLatin1(), "%d %d %d %d", &x, &y, &cx, &cy); resize(QSize(cx, cy)); move(QPoint(x, y)); } } } theme_ = config_->getItemValue("global", "theme"); QStyle *style; #ifdef USE_DOTNET_STYLE //javaboy@newsmth.org if (theme_ == "Office") style = new DotNetStyle(DotNetStyle::Office); else #endif //USE_DOTNET_STYLE style = QStyleFactory::create(theme_); if (style) { qApp->setStyle(style); } //language updateLanguageMenu(); //TODO: getAction(FQTermShortcutHelper::COLORCTL_NO)->setChecked(true); FQTermPref::getInstance()->escapeString_ = config_->getItemValue("global", "escstr"); if (FQTermPref::getInstance()->escapeString_ == "") { getAction(FQTermShortcutHelper::COLORCTL_NO)->setChecked(true); getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM)->setVisible(false); } else if (FQTermPref::getInstance()->escapeString_ == "^[^[[") { getAction(FQTermShortcutHelper::COLORCTL_SMTH)->setChecked(true); getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM)->setVisible(false); } else if (FQTermPref::getInstance()->escapeString_ == "^u[") { getAction(FQTermShortcutHelper::COLORCTL_PTT)->setChecked(true); getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM)->setVisible(false); } else { QAction *pAction = getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM); QString transStrEsc; transEscapeStr(transStrEsc, FQTermPref::getInstance()->escapeString_); pAction->setText(transStrEsc); pAction->setVisible(true); pAction->setChecked(true); } strTmp = config_->getItemValue("global", "vscrollpos"); if (strTmp == "0") { FQTermPref::getInstance()->termScrollBarPosition_ = 0; getAction(FQTermShortcutHelper::SCROLLBAR_HIDDEN)->setChecked(true); } else if (strTmp == "1") { FQTermPref::getInstance()->termScrollBarPosition_ = 1; getAction(FQTermShortcutHelper::SCROLLBAR_LEFT)->setChecked(true); } else { FQTermPref::getInstance()->termScrollBarPosition_ = 2; getAction(FQTermShortcutHelper::SCROLLBAR_RIGHT)->setChecked(true); } strTmp = config_->getItemValue("global", "switchbar"); isTabBarShown_ = (strTmp != "0"); getAction(FQTermShortcutHelper::SWITCHBAR)->setChecked(isTabBarShown_); if (isTabBarShown_) { statusBar()->show(); } else { statusBar()->hide(); } //read sub-window setting. strTmp = config_->getItemValue("global", "subwindowmax"); windowManager_->setSubWindowMax((strTmp != "0")); strTmp = config_->getItemValue("global", "subwindowsize"); if (strTmp != "") { //FIXME: In case of sub window size not saved properly. int w, h; sscanf(strTmp.toLatin1(), "%d %d", &w, &h); windowManager_->setSubWindowSize(QSize(w, h)); } else { //Magic Number. Initialize Window Size to Avoid Errors. windowManager_->setSubWindowSize(QSize(640, 480)); } FQTermPref::getInstance()->isBossColor_ = false; loadPref(); setUseDock(FQTermPref::getInstance()->openMinimizeToTray_); if (FQTermPref::getInstance()->useStyleSheet_) { loadStyleSheetFromFile(FQTermPref::getInstance()->styleSheetFile_); } } void FQTermFrame::loadPref() { QString strTmp; strTmp = config_->getItemValue("preference", "displayoffset"); FQTermPref::getInstance()->displayOffset_ = strTmp.toInt(); strTmp = config_->getItemValue("preference", "vsetting"); FQTermPref::getInstance()->vsetting_ = strTmp.toInt(); strTmp = config_->getItemValue("preference", "xim"); FQTermPref::getInstance()->imeEncodingID_ = strTmp.toInt(); strTmp = config_->getItemValue("preference", "wordwrap"); FQTermPref::getInstance()->widthToWrapWord_ = strTmp.toInt(); // strTmp = conf->getItemValue("preference", "smartww"); // m_pref.bSmartWW = (strTmp != "0"); strTmp = config_->getItemValue("preference", "wheel"); FQTermPref::getInstance()->isWheelSupported_ = (strTmp != "0"); strTmp = config_->getItemValue("preference", "url"); FQTermPref::getInstance()->openUrlCheck_ = (strTmp != "0"); // strTmp = conf->getItemValue("preference", "logmsg"); // m_pref.bLogMsg = (strTmp != "0"); strTmp = config_->getItemValue("preference", "blinktab"); FQTermPref::getInstance()->openTabBlinking_ = (strTmp != "0"); strTmp = config_->getItemValue("preference", "warn"); FQTermPref::getInstance()->openWarnOnClose_ = (strTmp != "0"); strTmp = config_->getItemValue("preference", "beep"); FQTermPref::getInstance()->openBeep_ = strTmp.toInt(); FQTermPref::getInstance()->beepSoundFileName_ = config_->getItemValue("preference", "wavefile"); strTmp = config_->getItemValue("preference", "http"); FQTermPref::getInstance()->httpBrowser_ = strTmp; // m_pref.strHttp = strTmp; strTmp = config_->getItemValue("preference", "antialias"); FQTermPref::getInstance()->openAntiAlias_ = (strTmp != "0"); strTmp = config_->getItemValue("preference", "enq"); FQTermPref::getInstance()->replyENQ_ = (strTmp != "0"); strTmp = config_->getItemValue("preference", "tray"); if (strTmp.isEmpty()) { #if defined(__APPLE__) || defined(__linux__) || defined(__GLIBC__) FQTermPref::getInstance()->openMinimizeToTray_ = false; #else FQTermPref::getInstance()->openMinimizeToTray_ = true; #endif } else { FQTermPref::getInstance()->openMinimizeToTray_ = (strTmp != "0"); } strTmp = config_->getItemValue("preference", "playmethod"); FQTermPref::getInstance()->beepMethodID_ = strTmp.toInt(); strTmp = config_->getItemValue("preference", "externalplayer"); FQTermPref::getInstance()->beepPlayerName_ = strTmp; strTmp = config_->getItemValue("preference", "clearpool"); FQTermPref::getInstance()->needClearZmodemPoolOnClose_ = (strTmp == "1"); strTmp = config_->getItemValue("preference", "pool"); FQTermPref::getInstance()->poolDir_ = strTmp.isEmpty() ? getPath(USER_CONFIG) + "pool/": strTmp; if (FQTermPref::getInstance()->poolDir_.right(1) != "/") { FQTermPref::getInstance()->poolDir_.append('/'); } strTmp = config_->getItemValue("preference", "zmodem"); FQTermPref::getInstance()->zmodemDir_ = strTmp.isEmpty() ? getPath(USER_CONFIG) + "zmodem/": strTmp; if (FQTermPref::getInstance()->zmodemDir_.right(1) != "/") { FQTermPref::getInstance()->zmodemDir_.append('/'); } strTmp = config_->getItemValue("preference", "image"); FQTermPref::getInstance()->imageViewerName_ = strTmp; strTmp = config_->getItemValue("preference", "qssfile"); FQTermPref::getInstance()->styleSheetFile_ = strTmp; FQTermPref::getInstance()->useStyleSheet_ = !strTmp.isEmpty(); strTmp = config_->getItemValue("preference", "editor"); FQTermPref::getInstance()->externalEditor_ = strTmp; //FIXME: duplicated strings. strTmp = config_->getItemValue("preference", "searchengine"); if (strTmp == "google") { getAction(FQTermShortcutHelper::SEARCH_GOOGLE)->setChecked(true); } else if (strTmp == "baidu") { getAction(FQTermShortcutHelper::SEARCH_BAIDU)->setChecked(true); } else if (strTmp == "bing") { getAction(FQTermShortcutHelper::SEARCH_BING)->setChecked(true); } else if (strTmp == "yahoo") { getAction(FQTermShortcutHelper::SEARCH_YAHOO)->setChecked(true); } else if (strTmp == "custom") { getAction(FQTermShortcutHelper::SEARCH_CUSTOM)->setChecked(true); } else { getAction(FQTermShortcutHelper::SEARCH_GOOGLE)->setChecked(true); strTmp = "google"; } FQTermPref::getInstance()->searchEngine_ = strTmp; strTmp = config_->getItemValue("preference", "editorarg"); FQTermPref::getInstance()->externalEditorArg_ = strTmp; strTmp = config_->getItemValue("preference", "asciienhance"); FQTermPref::getInstance()->isAnsciiEnhance_ = (strTmp == "1"); } //save current setting to fqterm.cfg void FQTermFrame::saveSetting() { QString strTmp; //save font config_->setItemValue("global", "font", qApp->font().family()); strTmp.setNum(QFontInfo(qApp->font()).pointSize()); config_->setItemValue("global", "pointsize", strTmp); strTmp.setNum(QFontInfo(qApp->font()).pixelSize()); config_->setItemValue("global", "pixelsize", strTmp); //save window position and size if (isMaximized()) { config_->setItemValue("global", "max", "1"); } else { strTmp = QString("%1 %2 %3 %4").arg(x()).arg(y()).arg(width()).arg(height()); // cstrTmp.sprintf("%d %d %d %d",x(),y(),width(),height()); config_->setItemValue("global", "size", strTmp); config_->setItemValue("global", "max", "0"); } if (windowState() & Qt::WindowFullScreen) { config_->setItemValue("global", "fullscreen", "1"); } else { config_->setItemValue("global", "fullscreen", "0"); } // cstrTmp.setNum(theme); config_->setItemValue("global", "theme", theme_); config_->setItemValue("global", "escstr", FQTermPref::getInstance()->escapeString_); strTmp.setNum(FQTermPref::getInstance()->termScrollBarPosition_); config_->setItemValue("global", "vscrollpos", strTmp); config_->setItemValue("global", "switchbar", isTabBarShown_ ? "1" : "0"); //save subwindow setting config_->setItemValue("global", "subwindowmax", windowManager_->getSubWindowMax() ? "1" : "0"); int w = windowManager_->getSubWindowSize().width(); int h = windowManager_->getSubWindowSize().height(); strTmp = QString("%1 %2").arg(w).arg(h); config_->setItemValue("global", "subwindowsize", strTmp); //Save toolbarstate. QByteArray state = saveState().toHex(); strTmp = QString(state); config_->setItemValue("global", "toolbarstate", strTmp); config_->save(getPath(USER_CONFIG) + "fqterm.cfg"); } void FQTermFrame::initAdditionalActions() { #if defined(__APPLE__) QString opt(tr("Ctrl")); #else QString opt(tr("Alt")); #endif for (int i = 1; i <= 10; ++i) { QAction *idAction = new QAction(this); QString shortcut(opt); shortcut += "+" + QString("").setNum(i % 10); idAction->setShortcut(shortcut); connect(idAction, SIGNAL(triggered()), windowMapper_, SLOT(map())); windowMapper_->setMapping(idAction, i - 1); addAction(idAction); } FQTERM_ADDACTION(windowManager_, NEXTWINDOW, windowManager_, activateNextWindow); FQTERM_ADDACTION(windowManager_, PREVWINDOW, windowManager_, activatePrevWindow); } //addressbook void FQTermFrame::addressBook() { siteDialog siteManager(this, 0); if (siteManager.exec() == 1) { newWindow(siteManager.currentParameter(), siteManager.currentSiteIndex()); } } //quicklogin void FQTermFrame::quickLogin() { quickDialog quick(config_, this); FQTermConfig *pConf = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg"); loadAddress(pConf, -1, quick.param_); delete pConf; if (quick.exec() == 1) { newWindow(quick.param_); } } void FQTermFrame::exitFQTerm() { if (!clearUp()) return; deleteLater(); } void FQTermFrame::newWindow(const FQTermParam ¶m, int index) { QIcon *icon = new QIcon(QPixmap(getPath(RESOURCE) + "pic/tabpad.png")); FQTermWindow* window = windowManager_->newWindow(param, config_, icon, index); updateFontCombo(); FQ_VERIFY(connect(window->getScreen(), SIGNAL(termFontChange(bool,QFont)), this, SLOT(termFontChange(bool,QFont)))); window->connectHost(); } void FQTermFrame::aboutFQTerm() { aboutDialog about(this); about.exec(); } //slot Help->Homepage void FQTermFrame::homepage() { const QString &httpBrowser = FQTermPref::getInstance()->httpBrowser_; const QString homeUrl = "https://github.com/mytbk/fqterm/"; if (httpBrowser.isNull() || httpBrowser.isEmpty()) { QDesktopServices::openUrl(homeUrl); } else { runProgram(httpBrowser, homeUrl); } } //slot Windows menu aboutToShow void FQTermFrame::windowsMenuAboutToShow() { menuWindows_->clear(); FQTERM_ADDACTION(menuWindows_, CASCADEWINDOWS, windowManager_, cascade); FQTERM_ADDACTION(menuWindows_, TILEWINDOWS, windowManager_, tile); if (windowManager_->count() == 0) { getAction(FQTermShortcutHelper::CASCADEWINDOWS)->setEnabled(false); getAction(FQTermShortcutHelper::TILEWINDOWS)->setEnabled(false); } menuWindows_->addSeparator(); #ifdef Q_OS_MACX // used to dock the program if (isHidden()) { menuWindows_->addAction(tr("Main Window"), this, SLOT(trayShow())); } #endif for (int i = 0; i < int(windowManager_->count()); ++i) { QAction *idAction = menuWindows_->addAction(windowManager_->subWindowList().at(i)->windowTitle()); idAction->setCheckable(true); idAction->setChecked(windowManager_->activeWindow() == windowManager_->nthWindow(i)); connect(idAction, SIGNAL(triggered()), windowMapper_, SLOT(map())); windowMapper_->setMapping(idAction, i); } } void FQTermFrame::reloadConfig() { config_->load(getPath(USER_CONFIG) + "fqterm.cfg"); } void FQTermFrame::popupConnectMenu() { menuConnect_->clear(); menuConnect_->addAction(tr("Quick Login"), this, SLOT(quickLogin())); menuConnect_->addSeparator(); FQTermConfig conf(getPath(USER_CONFIG) + "address.cfg"); QStringList listName; loadNameList(&conf, listName); for (int i = 0; i < listName.count(); i++) { QAction *idAction = menuConnect_->addAction(listName[i], this, SLOT (connectMenuActivated())); idAction->setData(i); if (i < 10) { #ifdef __APPLE__ QString shortCut(tr("Ctrl+Meta")); #else QString shortCut(tr("Ctrl+Alt")); #endif shortCut += "+" + QString("").setNum((i + 1)% 10); idAction->setShortcut(shortCut); } } int lastIndex = config_->getItemValue("global", "lastaddrindex").toInt(); if (lastIndex < 0 || lastIndex >= listName.count()) lastIndex = 0; if (listName.count() > 0) { menuConnect_->addSeparator(); QAction *idAction = menuConnect_->addAction(listName[lastIndex], this, SLOT (connectMenuActivated())); idAction->setData(LAST_ADDRESS_INDEX); #ifdef __APPLE__ QString shortCut(tr("Ctrl+Meta")); #else QString shortCut(tr("Ctrl+Alt")); #endif shortCut += "+" + QString("-"); idAction->setShortcut(shortCut); } } void FQTermFrame::connectMenuActivated() { FQTermConfig *pConf = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg"); int id = static_cast < QAction * > (sender())->data().toInt(); if (id == LAST_ADDRESS_INDEX) { id = config_->getItemValue("global", "lastaddrindex").toInt(); } FQTermParam param; // FIXME: don't know the relation with id and param set by setItemParameter if (loadAddress(pConf, id, param)) { newWindow(param, id); } delete pConf; } bool FQTermFrame::eventFilter(QObject *o, QEvent *e) { return false; } void FQTermFrame::closeEvent(QCloseEvent *clse) { if (FQTermPref::getInstance()->openMinimizeToTray_ && windowManager_->count() > 0) { trayHide(); clse->ignore(); return ; } if (!clearUp()) { clse->ignore(); return; } clse->accept(); deleteLater(); } void FQTermFrame::langEnglish() { installTranslator("en_US"); } void FQTermFrame::connectIt() { if (windowManager_->activeWindow() == NULL) { FQTermParam param; FQTermConfig *pConf = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg"); loadAddress(pConf, -1, param); delete pConf; newWindow(param); } else if (!windowManager_->activeWindow()->isConnected()) { windowManager_->activeWindow()->getSession()->reconnect(); } } void FQTermFrame::disconnect() { FQTermWindow* aw = windowManager_->activeWindow(); if (aw) { aw->disconnect(); } } static QString ssh2_info(conn_info_t *info) { QString txt; txt.append("\nhost key (SHA256): "); const char *tab = "0123456789ABCDEF"; for (int i=0; i<32; i++) { unsigned char b = info->ssh_proto_info.hash[i]; char hex[4] = { tab[(b>>4)], tab[b&0xf], ':', 0 }; if (i==31) hex[2] = 0; txt.append(hex); } txt.append(QString("\ncipher(c2s): %1\ncipher(s2c): %2") .arg(info->ssh_proto_info.c2s_cipher) .arg(info->ssh_proto_info.s2c_cipher)); if (info->ssh_proto_info.c2s_mac) { txt.append(QString("\nMAC(c2s): %1") .arg(info->ssh_proto_info.c2s_mac)); } if (info->ssh_proto_info.s2c_mac) { txt.append(QString("\nMAC(s2c): %1") .arg(info->ssh_proto_info.s2c_mac)); } if (info->ssh_proto_info.key_matches) txt.append("\nkey matches"); else txt.append("\nkey mismatch!"); return txt; } void FQTermFrame::conn_info() { FQTermSession *sess = windowManager_->activeWindow()->getSession(); conn_info_t *info = sess->connectionInfo(); QString txt; switch (info->proto) { case PROTO_TELNET: txt = "protocol: Telnet"; txt.append(QString("\nHost: %1\nPort: %2") .arg(info->hostname).arg(info->port)); break; case PROTO_LOCAL: txt = "protocol: Local"; break; case PROTO_SSH: txt = QString("protocol: SSH %1") .arg(info->ssh_proto_info.proto_version); txt.append(QString("\nHost: %1\nPort: %2") .arg(info->hostname).arg(info->port)); if (info->ssh_proto_info.proto_version == 2) txt.append(ssh2_info(info)); break; } QMessageBox b(QMessageBox::Information, "Connection Information", txt, QMessageBox::Ok, this); b.exec(); } void FQTermFrame::copy() { windowManager_->activeWindow()->copy(); } void FQTermFrame::paste() { windowManager_->activeWindow()->paste(); } void FQTermFrame::searchIt() { windowManager_->activeWindow()->searchIt(); } void FQTermFrame::shareIt() { windowManager_->activeWindow()->shareIt(); } void FQTermFrame::externalEditor() { windowManager_->activeWindow()->externalEditor(); } void FQTermFrame::fastPost() { windowManager_->activeWindow()->fastPost(); } void FQTermFrame::copyRect() { windowManager_->activeWindow()->getSession()->param().isRectSelect_ = !windowManager_->activeWindow()->getSession()->param().isRectSelect_; getAction(FQTermShortcutHelper::RECTANGLESELECTION)->setChecked( windowManager_->activeWindow()->getSession()->param().isRectSelect_); } void FQTermFrame::copyColor() { windowManager_->activeWindow()->getSession()->param().isColorCopy_ = !windowManager_->activeWindow()->getSession()->param().isColorCopy_; getAction(FQTermShortcutHelper::COPYWITHCOLOR)->setChecked( windowManager_->activeWindow()->getSession()->param().isColorCopy_); } void FQTermFrame::copyArticle() { windowManager_->activeWindow()->copyArticle(); } void FQTermFrame::autoCopy() { windowManager_->activeWindow()->getSession()->param().isAutoCopy_ = !windowManager_->activeWindow()->getSession()->param().isAutoCopy_; getAction(FQTermShortcutHelper::AUTOCOPYSELECTION)->setChecked( windowManager_->activeWindow()->getSession()->param().isAutoCopy_); } void FQTermFrame::wordWrap() { windowManager_->activeWindow()->getSession()->param().isAutoWrap_ = !windowManager_->activeWindow()->getSession()->param().isAutoWrap_; getAction(FQTermShortcutHelper::PASTEWORDWRAP)->setChecked( windowManager_->activeWindow()->getSession()->param().isAutoWrap_); } void FQTermFrame::noEsc() { FQTermPref::getInstance()->escapeString_ = ""; getAction(FQTermShortcutHelper::COLORCTL_NO)->setChecked(true); getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM)->setVisible(false); } void FQTermFrame::escEsc() { FQTermPref::getInstance()->escapeString_ = "^[^[["; getAction(FQTermShortcutHelper::COLORCTL_SMTH)->setChecked(true); getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM)->setVisible(false); } void FQTermFrame::uEsc() { FQTermPref::getInstance()->escapeString_ = "^u["; getAction(FQTermShortcutHelper::COLORCTL_PTT)->setChecked(true); getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM)->setVisible(false); } void FQTermFrame::oldCustomEsc() { } void FQTermFrame::customEsc() { QString strEsc(FQTermPref::getInstance()->escapeString_); DefineEscapeDialog defineEscapeDialog_(strEsc, this); if (defineEscapeDialog_.exec() == 1) { FQTermPref::getInstance()->escapeString_ = strEsc; QAction *pAction = getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM); if (strEsc != QString("") && strEsc != QString("^[^[[") && strEsc != QString("^u[")) { QString transStrEsc; transEscapeStr(transStrEsc, strEsc); pAction->setText(transStrEsc); pAction->setVisible(true); pAction->setChecked(true); } else { pAction->setVisible(false); } } } bool FQTermFrame::isDelimiterExistedBefore(const QString& str, const std::vector& existingDelimiters) { for (std::vector::const_iterator cit = existingDelimiters.begin(); cit != existingDelimiters.end(); ++cit) { if (str.right(cit->length()) == *cit) { return true; } } return false; } int FQTermFrame::isDelimiterExistedAfter(const QString& str, const std::vector& existingDelimiters) { for (std::vector::const_iterator cit = existingDelimiters.begin(); cit != existingDelimiters.end(); ++cit) { if (str.left(cit->length()) == *cit) { return cit->length(); } } return 0; } bool FQTermFrame::uppercaseCharFollowingCtrl(QString& str, int& i, const QString& after) { if (after == QString("Ctrl") && str[i] > 'a' - 1 && str[i] < 'z' - 1) { str[i] = str[i].toUpper(); ++i; return true; } else { return false; } } void FQTermFrame::replaceEscapeString(QString& str, const QString& before, const QString& after, const QString& delimiter, const std::vector *existingDelimiters /* = NULL */) { bool preMatched = false; int i = 0; while (i < str.length()) { bool matched = true; for (int j = 0; j < before.length(); ++j) { if (str[i + j] != before[j]) { matched = false; break; } }// end of for if (matched) { if (i == 0) { // the matched string is the head of the string str = after + delimiter + str.right(str.length() - before.length()); i = after.length() + delimiter.length(); bool changed = uppercaseCharFollowingCtrl(str, i, after); preMatched = !changed; } else if (i == str.length() - before.length()) { // the matched string is the tail of the string if (existingDelimiters != NULL && isDelimiterExistedBefore(str.left(i), *existingDelimiters)) { preMatched = true; } if (preMatched) { str = str.left(i) + after; } else { str = str.left(i) + delimiter + after; } break; } else { // the matched string is at the middle of the string if (existingDelimiters != NULL && isDelimiterExistedBefore(str.left(i), *existingDelimiters)) { preMatched = true; } if (preMatched) { str = str.left(i) + after + delimiter + str.right(str.length() - i - before.length()); i += after.length() + delimiter.length(); } else { str = str.left(i) + delimiter + after + delimiter + str.right(str.length() - i - before.length()); i += after.length() + 2 * delimiter.length(); } bool changed = uppercaseCharFollowingCtrl(str, i, after); preMatched = !changed; } if (preMatched) { int len; if (existingDelimiters != NULL && (len = isDelimiterExistedAfter(str.right(str.length() - i), *existingDelimiters)) != 0) { str = str.left(i) + str.right(str.length() - i - len); } } } else { preMatched = false; ++i; } }// end of while } void FQTermFrame::transEscapeStr(QString& target, const QString& source) { const QChar cSpecial(17); target = source; replaceEscapeString(target, QString("^["), QString("ESC"), QString(cSpecial)); std::vector existingDelimiters; existingDelimiters.push_back(QString(cSpecial)); replaceEscapeString(target, QString("^"), QString("Ctrl"), QString("+"), &existingDelimiters); target.replace(cSpecial, QChar(' ')); } void FQTermFrame::setColor() { windowManager_->activeWindow()->setColor(); } void FQTermFrame::refreshScreen() { windowManager_->activeWindow()->forcedRepaintScreen(); } void FQTermFrame::uiFont() { bool ok; QFont font = QFontDialog::getFont(&ok, qApp->font()); if (FQTermPref::getInstance()->openAntiAlias_) { font.setStyleStrategy(QFont::PreferAntialias); } if (ok == true) { qApp->setFont(font); //refresh style sheet if (FQTermPref::getInstance()->useStyleSheet_) { refreshStyleSheet(); } imageViewer_->adjustItemSize(); } } void FQTermFrame::fullscreen() { if (!(windowState() & Qt::WindowFullScreen)) { menuBar()->hide(); toolBarMdiTools_->hide(); toolBarMdiConnectTools_->hide(); toolBarSetupKeys_->hide(); toolBarFonts_->hide(); hideScroll(); showSwitchBar(); showFullScreen(); } else { menuBar()->show(); toolBarMdiTools_->show(); toolBarMdiConnectTools_->show(); toolBarSetupKeys_->show(); toolBarFonts_->show(); emit updateScroll(); showSwitchBar(); showNormal(); } } void FQTermFrame::bosscolor() { FQTermPref::getInstance()->isBossColor_ = !FQTermPref::getInstance()->isBossColor_; emit bossColor(); getAction(FQTermShortcutHelper::BOSSCOLOR)->setChecked(FQTermPref::getInstance()->isBossColor_); } void FQTermFrame::themesMenuAboutToShow() { QVector vectorShortcutKeys; menuThemes_->clear(); QStringList styles = QStyleFactory::keys(); for (QStringList::ConstIterator it = styles.begin(); it != styles.end(); it++) { QString strTheme = *it; for (int i = 0; i < strTheme.length(); ++i) { if (vectorShortcutKeys.indexOf(strTheme.at(i)) == -1) { vectorShortcutKeys.append(strTheme.at(i)); strTheme.insert(i, QChar('&')); break; } } insertThemeItem(strTheme); } #ifdef USE_DOTNET_STYLE insertThemeItem("Office"); //javaboy@newsmth.org #endif //USE_DOTNET_STYLE } void FQTermFrame::themesMenuActivated() { theme_ = ((QAction*)QObject::sender())->text().remove(QChar('&')); QStyle *style; #ifdef USE_DOTNET_STYLE //javaboy@newsmth.org if (theme_ == "Office") style = new DotNetStyle(DotNetStyle::Office); else #endif //USE_DOTNET_STYLE style = QStyleFactory::create(theme_); if (style) { qApp->setStyle(style); } } void FQTermFrame::hideScroll() { FQTermPref::getInstance()->termScrollBarPosition_ = 0; emit updateScroll(); } void FQTermFrame::leftScroll() { FQTermPref::getInstance()->termScrollBarPosition_ = 1; emit updateScroll(); } void FQTermFrame::rightScroll() { FQTermPref::getInstance()->termScrollBarPosition_ = 2; emit updateScroll(); } void FQTermFrame::setSE(const QString& se) { FQTermPref::getInstance()->searchEngine_ = se; config_->setItemValue("preference", "searchengine", se); } void FQTermFrame::setSEGoogle() { setSE("google"); } void FQTermFrame::setSEBaidu(){ setSE("baidu"); } void FQTermFrame::setSEYahoo() { setSE("yahoo"); } void FQTermFrame::setSEBing() { setSE("bing"); } void FQTermFrame::setSECustom(){ setSE("custom"); } void FQTermFrame::showSwitchBar() { isTabBarShown_ = !isTabBarShown_; getAction(FQTermShortcutHelper::SWITCHBAR)->setChecked(isTabBarShown_); if (isTabBarShown_) { statusBar()->show(); } else { statusBar()->hide(); } } void FQTermFrame::setting() { windowManager_->activeWindow()->setting(); updateMenuToolBar(); } void FQTermFrame::saveSessionSetting() { windowManager_->activeWindow()->saveSetting(false); } void FQTermFrame::defaultSetting() { FQTermConfig *pConf = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg"); FQTermParam tmpParam; if (pConf->hasSection("default")) { loadAddress(pConf, -1, tmpParam); } addrDialog set(this, tmpParam, addrDialog::SAVE); if (set.exec() == 2) { saveAddress(pConf, -1, set.param()); pConf->save(getPath(USER_CONFIG) + "address.cfg"); } delete pConf; } void FQTermFrame::preference() { prefDialog pref(config_, this); bool styleSheetUsed = FQTermPref::getInstance()->useStyleSheet_; if (pref.exec() == 1) { //TODO: refactor loadPref(); setUseDock(FQTermPref::getInstance()->openMinimizeToTray_); if (FQTermPref::getInstance()->useStyleSheet_) { loadStyleSheetFromFile(FQTermPref::getInstance()->styleSheetFile_); } else if (styleSheetUsed) { clearStyleSheet(); } } emit fontAntiAliasing(FQTermPref::getInstance()->openAntiAlias_); } void FQTermFrame::shortcutSetting() { int act = windowManager_->activeWindowIndex(); FQTermShortcutDialog fsd(shortcutHelper_, this); fsd.exec(); windowManager_->activateTheWindow(act); } void FQTermFrame::keySetup() { keyDialog keyDlg(config_, this); if (keyDlg.exec() == 1) { updateKeyToolBar(); } } void FQTermFrame::ipLookup() { IPLookupDialog ipLookupDialog_(this); ipLookupDialog_.exec(); } void FQTermFrame::logRaw() { FQTermSession *s = windowManager_->activeWindow()->getSession(); if (!s->isLogging()) { s->startLogging(); } else { s->stopLogging(true); } getAction(FQTermShortcutHelper::LOGRAW)->setChecked( s->isLogging()); } void FQTermFrame::antiIdle() { windowManager_->activeWindow()->toggleAntiIdle(); getAction(FQTermShortcutHelper::ANTIIDLE)->setChecked( windowManager_->activeWindow()->getSession()->isAntiIdle()); } void FQTermFrame::autoReply() { windowManager_->activeWindow()->toggleAutoReply(); getAction(FQTermShortcutHelper::AUTOREPLY)->setChecked( windowManager_->activeWindow()->getSession()->isAutoReply()); } void FQTermFrame::viewMessages() { windowManager_->activeWindow()->viewMessages(); } void FQTermFrame::enableMouse() { windowManager_->activeWindow()->getSession()->param().isSupportMouse_ = !windowManager_->activeWindow()->getSession()->param().isSupportMouse_; getAction(FQTermShortcutHelper::MOUSESUPPORT)->setChecked( windowManager_->activeWindow()->getSession()->param().isSupportMouse_); } void FQTermFrame::viewImages(QString filename, bool raiseViewer) { if (filename.isEmpty()) { filename = FQTermPref::getInstance()->poolDir_; } if (raiseViewer) { imageViewer_->scrollTo(filename); if (imageViewer_->isHidden()) { imageViewer_->resize(size() * 3 / 4 + QSize(1,1)); imageViewer_->show(); } clearFocus(); imageViewer_->raise(); imageViewer_->activateWindow(); } else { imageViewer_->updateImage(filename); } } void FQTermFrame::viewImages() { viewImages(FQTermPref::getInstance()->poolDir_, true); } void FQTermFrame::beep() { windowManager_->activeWindow()->getSession()->param().isBeep_ = !windowManager_->activeWindow()->getSession()->param().isBeep_; getAction(FQTermShortcutHelper::BEEP)->setChecked(windowManager_->activeWindow()->getSession()->param().isBeep_); } void FQTermFrame::reconnect() { FQTermWindow * qtw = windowManager_->activeWindow(); if (qtw){ qtw->toggleAutoReconnect(); } } void FQTermFrame::delayedRunScript() { windowManager_->activeWindow()->runScript(); } void FQTermFrame::runScript() { QTimer::singleShot(1, this, SLOT(delayedRunScript())); } void FQTermFrame::stopScript() { windowManager_->activeWindow()->stopScript(); } void FQTermFrame::runPyScript() { #ifdef HAVE_PYTHON windowManager_->activeWindow()->runPythonScript(); #endif //HAVE_PYTHON } bool FQTermFrame::event(QEvent *e) { static bool shown = false; if (e->type() == QEvent::WindowStateChange) { if ((((QWindowStateChangeEvent*)(e))->oldState() & Qt::WindowMinimized) && !(windowState() & Qt::WindowMinimized)) { shown = true; } if (!(windowState() & Qt::WindowMinimized)) { config_->setItemValue("global", "max", (windowState() & Qt::WindowMaximized) ? "1" : "0"); config_->setItemValue("global", "fullscreen", (windowState() & Qt::WindowFullScreen) ? "1" : "0"); } } if (e->type() == QEvent::Paint && shown) { shown = false; qApp->setActiveWindow(NULL); qApp->setActiveWindow(this); } bool res = this->QMainWindow::event(e); if (e->type() == QEvent::HoverMove || e->type() == QEvent::MouseMove || e->type() == QEvent::Move) { if (res) { FQ_TRACE("frameEvent", 10) << "Accept event: " << e->type() << " " << getEventName(e->type()) << "."; } else { FQ_TRACE("frameEvent", 10) << "Ignore event: " << e->type() << " " << getEventName(e->type()) << "."; } } else { if (res) { FQ_TRACE("frameEvent", 9) << "Accept event: " << e->type() << " " << getEventName(e->type()) << "."; } else { FQ_TRACE("frameEvent", 9) << "Ignore event: " << e->type() << " " << getEventName(e->type()) << "."; } } return res; } void FQTermFrame::keyClicked(int id) { if (windowManager_->activeWindow() == NULL) { return ; } QString strItem = QString("key%1").arg(id); QString strTmp = config_->getItemValue("key", strItem); if (strTmp[0] == '0') { // key windowManager_->activeWindow()->externInput(strTmp.mid(1)); } else if (strTmp[0] == '1') { // script QString scriptFile = strTmp.mid(1).trimmed(); #ifdef HAVE_PYTHON if (scriptFile.endsWith(".py", Qt::CaseInsensitive)) windowManager_->activeWindow()->runPythonScriptFile(scriptFile); else #endif windowManager_->activeWindow()->runScript(scriptFile.toLatin1()); } else if (strTmp[0] == '2') { // program runProgram(strTmp.mid(1)); } } void FQTermFrame::addMainTool() { // the main toolbar toolBarMdiTools_ = addToolBar("Main ToolBar"); toolBarMdiTools_->setObjectName("Main ToolBar"); connectButton_ = new QToolButton(toolBarMdiTools_); connectButton_->setIcon(QPixmap(getPath(RESOURCE) + "pic/connect.png")); toolBarMdiTools_->addWidget(connectButton_); menuConnect_ = new QMenu(this); //FIXME: autoupdate menu FQ_VERIFY(connect(menuConnect_, SIGNAL(aboutToShow()), this, SLOT(popupConnectMenu()))); connectButton_->setMenu(menuConnect_); connectButton_->setPopupMode(QToolButton::InstantPopup); toolBarMdiTools_->addAction(getAction(FQTermShortcutHelper::QUICKLOGIN)); // custom define toolBarSetupKeys_ = addToolBar("Custom Key"); toolBarSetupKeys_->setObjectName("Custom Key"); // the toolbar toolBarMdiConnectTools_ = addToolBar("BBS operations"); toolBarMdiConnectTools_->setObjectName("BBS operations"); toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::CONN_INFO)); FQTERM_ADDACTION(toolBarMdiConnectTools_, DISCONNECT, this, disconnect); getAction(FQTermShortcutHelper::DISCONNECT)->setEnabled(false); toolBarMdiConnectTools_->addSeparator(); //Font Tool Bar toolBarFonts_ = addToolBar("Font ToolBar"); toolBarFonts_->setObjectName("Font ToolBar"); // Edit (5) toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::COPY)); toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::PASTE)); toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::COPYWITHCOLOR)); toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::RECTANGLESELECTION)); toolBarMdiConnectTools_->addSeparator(); //Font fontButton_ = new QToolButton(toolBarFonts_); QAction* dummyAction = new QAction(QPixmap(getPath(RESOURCE) + "pic/change_fonts.png"), tr("Set Terminal Fonts"), fontButton_); fontButton_->setDefaultAction(dummyAction); toolBarFonts_->addWidget(fontButton_); fontButton_->setMenu(menuFont_); fontButton_->setPopupMode(QToolButton::InstantPopup); toolBarFonts_->addSeparator(); englishFontCombo_ = new QFontComboBox(toolBarFonts_); otherFontCombo_ = new QFontComboBox(toolBarFonts_); QLabel *englishFontLabel = new QLabel(toolBarFonts_); englishFontLabel->setPixmap(QPixmap(getPath(RESOURCE) + "pic/english_font.png")); toolBarFonts_->addWidget(englishFontLabel); toolBarFonts_->addWidget(englishFontCombo_); toolBarFonts_->addSeparator(); QLabel *otherFontLabel = new QLabel(toolBarFonts_); otherFontLabel->setPixmap(QPixmap(getPath(RESOURCE) + "pic/other_font.png")); toolBarFonts_->addWidget(otherFontLabel); toolBarFonts_->addWidget(otherFontCombo_); FQ_VERIFY(connect(englishFontCombo_, SIGNAL(currentFontChanged(const QFont&)), this, SLOT(comboFontChanged(const QFont&)))); FQ_VERIFY(connect(otherFontCombo_, SIGNAL(currentFontChanged(const QFont&)), this, SLOT(comboFontChanged(const QFont&)))); toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::COLORSETTING)); toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::ANSICOLOR)); toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::REFRESHSCREEN)); toolBarMdiConnectTools_->addSeparator(); // Option toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::CURRENTSETTING)); toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::SAVESETTING)); toolBarMdiConnectTools_->addSeparator(); // Spec (5) toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::COPYARTICLE)); toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::LOGRAW)); toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::ANTIIDLE)); toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::AUTOREPLY)); toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::VIEWMESSAGE)); toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::IMAGEVIEWER)); toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::MOUSESUPPORT)); toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::BEEP)); toolBarMdiConnectTools_->addAction(getAction(FQTermShortcutHelper::AUTORECONNECT)); //call popupConnectMenu() to enable the shortcuts popupConnectMenu(); } QAction* FQTermFrame::getAction(int shortcut) { if (!shortcutHelper_) return NULL; return shortcutHelper_->getAction(shortcut); } void FQTermFrame::addMainMenu() { menuMain_ = menuBar(); //File Menu menuFile_ = menuMain_->addMenu(tr("&File")); FQTERM_ADDACTION(menuFile_, CONNECT, this, connectIt); FQTERM_ADDACTION(menuFile_, DISCONNECT, this, disconnect); FQTERM_ADDACTION(menuFile_, CONN_INFO, this, conn_info); menuFile_->addSeparator(); FQTERM_ADDACTION(menuFile_, ADDRESSBOOK, this, addressBook); FQTERM_ADDACTION(menuFile_, QUICKLOGIN, this, quickLogin); menuFile_->addSeparator(); FQTERM_ADDACTION(menuFile_, EXIT, this, exitFQTerm); getAction(FQTermShortcutHelper::EXIT)->setMenuRole(QAction::QuitRole); //Edit Menu QMenu *edit = menuMain_->addMenu(tr("&Edit")); FQTERM_ADDACTION(edit, COPY, this, copy); FQTERM_ADDACTION(edit, PASTE, this, paste); edit->addSeparator(); FQTERM_ADDACTION(edit, COPYWITHCOLOR, this, copyColor); FQTERM_ADDACTION(edit, RECTANGLESELECTION, this, copyRect); FQTERM_ADDACTION(edit, AUTOCOPYSELECTION, this, autoCopy); FQTERM_ADDACTION(edit, PASTEWORDWRAP, this, wordWrap); edit->addSeparator(); FQTERM_ADDACTION(edit, SEARCHIT, this, searchIt); FQTERM_ADDACTION(edit, WEIBOSHARE, this, shareIt); edit->addSeparator(); FQTERM_ADDACTION(edit, EXTERNALEDITOR, this, externalEditor); edit->addSeparator(); FQTERM_ADDACTION(edit, FASTPOST, this, fastPost); edit->addSeparator(); QMenu *escapeMenu = edit->addMenu(tr("Control sequence in clipboar&d")); escapeGroup = new QActionGroup(this); FQTERM_ADDACTION(escapeMenu, COLORCTL_NO,this, noEsc); escapeGroup->addAction(getAction(FQTermShortcutHelper::COLORCTL_NO)); FQTERM_ADDACTION(escapeMenu, COLORCTL_SMTH,this, escEsc); escapeGroup->addAction(getAction(FQTermShortcutHelper::COLORCTL_SMTH)); FQTERM_ADDACTION(escapeMenu, COLORCTL_PTT,this, uEsc); escapeGroup->addAction(getAction(FQTermShortcutHelper::COLORCTL_PTT)); FQTERM_ADDACTION(escapeMenu, COLORCTL_OLD_CUSTOM,this, oldCustomEsc); escapeGroup->addAction(getAction(FQTermShortcutHelper::COLORCTL_OLD_CUSTOM)); FQTERM_ADDACTION(escapeMenu, COLORCTL_CUSTOM,this, customEsc); escapeGroup->addAction(getAction(FQTermShortcutHelper::COLORCTL_CUSTOM)); //View menu QMenu *view = menuMain_->addMenu(tr("&View")); menuFont_ = view->addMenu(tr("&Font")); menuFont_->setIcon(QPixmap(getPath(RESOURCE) + "pic/change_fonts.png")); view->addMenu(menuFont_); FQTERM_ADDACTION(menuFont_, OTHERFONT, this, setFont); getAction(FQTermShortcutHelper::OTHERFONT)->setData(0); FQTERM_ADDACTION(menuFont_, ENGLISHFONT, this, setFont); getAction(FQTermShortcutHelper::ENGLISHFONT)->setData(1); FQTERM_ADDACTION(view, COLORSETTING, this, setColor); FQTERM_ADDACTION(view, ANSICOLOR, this, toggleAnsiColor); FQTERM_ADDACTION(view, REFRESHSCREEN, this, refreshScreen); view->addSeparator(); //language menu languageGroup = new QActionGroup(view); languageGroup->setExclusive(true); if (installerList_.isEmpty()) { FQ_TRACE("frame", 0) << "No language menu because of lack of translation files"; } else { menuLanguage_ = view->addMenu(tr("&Language")); FQTERM_ADDACTION(menuLanguage_, LANGUAGE_ENGLISH, this, langEnglish); languageGroup->addAction(getAction(FQTermShortcutHelper::LANGUAGE_ENGLISH)); foreach(TranslatorInstaller* installer, installerList_) { QAction* action = menuLanguage_->addAction( installer->languageName(), installer, SLOT(installTranslator())); action->setCheckable(true); languageGroup->addAction(action); } } FQTERM_ADDACTION(view, UIFONT, this, uiFont); menuThemes_ = view->addMenu(tr("&Themes")); FQ_VERIFY(connect(menuThemes_, SIGNAL(aboutToShow()), this, SLOT(themesMenuAboutToShow()))); FQTERM_ADDACTION(view, FULLSCREEN, this, fullscreen); FQTERM_ADDACTION(view, BOSSCOLOR, this, bosscolor); view->addSeparator(); QMenu *scrollMenu = view->addMenu(tr("&ScrollBar")); scrollGroup = new QActionGroup(this); FQTERM_ADDACTION(scrollMenu, SCROLLBAR_HIDDEN,this, hideScroll); scrollGroup->addAction(getAction(FQTermShortcutHelper::SCROLLBAR_HIDDEN)); FQTERM_ADDACTION(scrollMenu, SCROLLBAR_RIGHT,this, rightScroll); scrollGroup->addAction(getAction(FQTermShortcutHelper::SCROLLBAR_RIGHT)); FQTERM_ADDACTION(scrollMenu, SCROLLBAR_LEFT,this, leftScroll); scrollGroup->addAction(getAction(FQTermShortcutHelper::SCROLLBAR_LEFT)); FQTERM_ADDACTION(view, SWITCHBAR, this, showSwitchBar); // Option Menu QMenu *option = menuMain_->addMenu(tr("&Option")); FQTERM_ADDACTION(option, CURRENTSETTING, this, setting); FQTERM_ADDACTION(option, SAVESETTING, this, saveSessionSetting); option->addSeparator(); FQTERM_ADDACTION(option, DEFAULTSETTING, this, defaultSetting); #ifdef Q_OS_MAC FQTERM_ADDACTION(menuFile_, PREFERENCE, this, preference); #else FQTERM_ADDACTION(option, PREFERENCE, this, preference); #endif getAction(FQTermShortcutHelper::PREFERENCE)->setMenuRole(QAction::PreferencesRole); FQTERM_ADDACTION(option, SHORTCUTSETTING, this, shortcutSetting); option->addSeparator(); FQTERM_ADDACTION(option, EDITSCHEMA, this, editSchema); option->addSeparator(); QMenu *searchEngineMenu = option->addMenu(tr("Searc&h Engine")); searchEngineGroup = new QActionGroup(this); FQTERM_ADDACTION(searchEngineMenu, SEARCH_GOOGLE,this, setSEGoogle); searchEngineGroup->addAction(getAction(FQTermShortcutHelper::SEARCH_GOOGLE)); FQTERM_ADDACTION(searchEngineMenu, SEARCH_BAIDU,this, setSEBaidu); searchEngineGroup->addAction(getAction(FQTermShortcutHelper::SEARCH_BAIDU)); FQTERM_ADDACTION(searchEngineMenu, SEARCH_BING,this, setSEBing); searchEngineGroup->addAction(getAction(FQTermShortcutHelper::SEARCH_BING)); FQTERM_ADDACTION(searchEngineMenu, SEARCH_YAHOO,this, setSEYahoo); searchEngineGroup->addAction(getAction(FQTermShortcutHelper::SEARCH_YAHOO)); FQTERM_ADDACTION(searchEngineMenu, SEARCH_CUSTOM,this, setSECustom); searchEngineGroup->addAction(getAction(FQTermShortcutHelper::SEARCH_CUSTOM)); // Special QMenu *spec = menuMain_->addMenu(tr("&Special")); FQTERM_ADDACTION(spec, COPYARTICLE, this, copyArticle); FQTERM_ADDACTION(spec, LOGRAW, this, logRaw); FQTERM_ADDACTION(spec, ANTIIDLE, this, antiIdle); FQTERM_ADDACTION(spec, AUTOREPLY, this, autoReply); FQTERM_ADDACTION(spec, VIEWMESSAGE, this, viewMessages); FQTERM_ADDACTION(spec, BEEP, this, beep); FQTERM_ADDACTION(spec, MOUSESUPPORT, this, enableMouse); FQTERM_ADDACTION(spec, IMAGEVIEWER, this, viewImages); FQTERM_ADDACTION(spec, IPLOOKUP, this, ipLookup); //Script QMenu *script = menuMain_->addMenu(tr("Scrip&t")); FQTERM_ADDACTION(script, RUNSCRIPT, this, runScript); FQTERM_ADDACTION(script, STOPSCRIPT, this, stopScript); #ifdef HAVE_PYTHON script->addSeparator(); FQTERM_ADDACTION(script, RUNPYTHONSCRIPT, this, runPyScript); #endif //HAVE_PYTHON //Window menu menuWindows_ = menuMain_->addMenu(tr("&Windows")); FQ_VERIFY(connect(menuWindows_, SIGNAL(aboutToShow()),this, SLOT(windowsMenuAboutToShow()))); menuMain_->addSeparator(); //Help menu QMenu *help = menuMain_->addMenu(tr("&Help")); FQTERM_ADDACTION(help, ABOUT, this, aboutFQTerm); getAction(FQTermShortcutHelper::ABOUT)->setMenuRole(QAction::AboutRole); FQTERM_ADDACTION(help, HOMEPAGE, this, homepage); } void FQTermFrame::updateMenuToolBar() { FQTermWindow *window = windowManager_->activeWindow(); if (window == NULL) { return ; } // update menu getAction(FQTermShortcutHelper::CONN_INFO)->setEnabled(window->isConnected()); getAction(FQTermShortcutHelper::DISCONNECT)->setEnabled(window->isConnected()); getAction(FQTermShortcutHelper::COPYWITHCOLOR)->setChecked(window->getSession()->param().isColorCopy_); getAction(FQTermShortcutHelper::RECTANGLESELECTION)->setChecked(window->getSession()->param().isRectSelect_); getAction(FQTermShortcutHelper::AUTOCOPYSELECTION)->setChecked(window->getSession()->param().isAutoCopy_); getAction(FQTermShortcutHelper::PASTEWORDWRAP)->setChecked(window->getSession()->param().isAutoWrap_); getAction(FQTermShortcutHelper::FULLSCREEN)->setChecked(windowState() & Qt::WindowFullScreen); getAction(FQTermShortcutHelper::ANSICOLOR)->setChecked(window->getSession()->param().isAnsiColor_); getAction(FQTermShortcutHelper::LOGRAW)->setChecked(window->getSession()->isLogging()); getAction(FQTermShortcutHelper::ANTIIDLE)->setChecked(window->getSession()->isAntiIdle()); getAction(FQTermShortcutHelper::AUTOREPLY)->setChecked(window->getSession()->isAutoReply()); getAction(FQTermShortcutHelper::BEEP)->setChecked(window->getSession()->param().isBeep_); getAction(FQTermShortcutHelper::MOUSESUPPORT)->setChecked(window->getSession()->param().isSupportMouse_); getAction(FQTermShortcutHelper::AUTORECONNECT)->setChecked(window->getSession()->param().isAutoReconnect_); updateFontCombo(); } void FQTermFrame::updateFontCombo() { FQTermWindow *window = windowManager_->activeWindow(); if (window == NULL) { return ; } englishFontCombo_->blockSignals(true); otherFontCombo_->blockSignals(true); englishFontCombo_->setCurrentFont(window->getScreen()->termFont(true)); otherFontCombo_->setCurrentFont(window->getScreen()->termFont(false)); englishFontCombo_->blockSignals(false); otherFontCombo_->blockSignals(false); } void FQTermFrame::termFontChange(bool isEnglish, QFont font) { updateFontCombo(); } void FQTermFrame::comboFontChanged(const QFont & font) { FQTermWindow *window = windowManager_->activeWindow(); if (window == NULL) { return ; } window->getScreen()->blockSignals(true); bool isEnglish = (sender() == (QObject*)englishFontCombo_); QString& fontName = isEnglish? window->getSession()->param().englishFontName_:window->getSession()->param().otherFontName_; int& fontSize = isEnglish? window->getSession()->param().englishFontSize_:window->getSession()->param().otherFontSize_; QFontComboBox* combo = isEnglish ? englishFontCombo_ : otherFontCombo_; QFont f(combo->currentFont().family(), window->getScreen()->termFont(true).pointSize()); window->getScreen()->setTermFont(isEnglish, f); fontName = f.family(); fontSize = f.pointSize(); window->getScreen()->blockSignals(false); window->forcedRepaintScreen(); } void FQTermFrame::enableMenuToolBar(bool enable) { getAction(FQTermShortcutHelper::CONN_INFO)->setEnabled(enable); getAction(FQTermShortcutHelper::DISCONNECT)->setEnabled(enable); getAction(FQTermShortcutHelper::COPY)->setEnabled(enable); getAction(FQTermShortcutHelper::PASTE)->setEnabled(enable); getAction(FQTermShortcutHelper::COPYWITHCOLOR)->setEnabled(enable); getAction(FQTermShortcutHelper::RECTANGLESELECTION)->setEnabled(enable); getAction(FQTermShortcutHelper::AUTOCOPYSELECTION)->setEnabled(enable); getAction(FQTermShortcutHelper::PASTEWORDWRAP)->setEnabled(enable); getAction(FQTermShortcutHelper::ANSICOLOR)->setEnabled(enable); fontButton_->setEnabled(enable); englishFontCombo_->setEnabled(enable); otherFontCombo_->setEnabled(enable); menuFont_->setEnabled(enable); getAction(FQTermShortcutHelper::COLORSETTING)->setEnabled(enable); getAction(FQTermShortcutHelper::REFRESHSCREEN)->setEnabled(enable); getAction(FQTermShortcutHelper::CURRENTSETTING)->setEnabled(enable); getAction(FQTermShortcutHelper::SAVESETTING)->setEnabled(enable); getAction(FQTermShortcutHelper::COPYARTICLE)->setEnabled(enable); getAction(FQTermShortcutHelper::LOGRAW)->setEnabled(enable); getAction(FQTermShortcutHelper::ANTIIDLE)->setEnabled(enable); getAction(FQTermShortcutHelper::AUTOREPLY)->setEnabled(enable); getAction(FQTermShortcutHelper::VIEWMESSAGE)->setEnabled(enable); getAction(FQTermShortcutHelper::BEEP)->setEnabled(enable); getAction(FQTermShortcutHelper::MOUSESUPPORT)->setEnabled(enable); getAction(FQTermShortcutHelper::RUNSCRIPT)->setEnabled(enable); getAction(FQTermShortcutHelper::STOPSCRIPT)->setEnabled(enable); #ifdef HAVE_PYTHON getAction(FQTermShortcutHelper::RUNPYTHONSCRIPT)->setEnabled(enable); #endif getAction(FQTermShortcutHelper::SEARCHIT)->setEnabled(enable); getAction(FQTermShortcutHelper::WEIBOSHARE)->setEnabled(enable); getAction(FQTermShortcutHelper::EXTERNALEDITOR)->setEnabled(enable); getAction(FQTermShortcutHelper::FASTPOST)->setEnabled(enable); } void FQTermFrame::updateKeyToolBar() { toolBarSetupKeys_->clear(); toolBarSetupKeys_->addAction(QPixmap(getPath(RESOURCE) + "pic/setup_shortcuts.png"), tr("Key Setup"), this, SLOT(keySetup())); QString strItem, strTmp; strTmp = config_->getItemValue("key", "num"); int num = strTmp.toInt(); for (int i = 0; i < num; i++) { strItem = QString("name%1").arg(i); strTmp = config_->getItemValue("key", strItem); FQTermToolButton *button = new FQTermToolButton(toolBarSetupKeys_, i, strTmp); button->setText(strTmp); strItem = QString("key%1").arg(i); strTmp = (config_->getItemValue("key", strItem)); //TODO: add tool tip here // QToolTip::add( button, strTmp.mid(1) ); // button->addToolTip(strTmp.mid(1)); strTmp = config_->getItemValue("key", QString("shortcut%1").arg(i)); if (!strTmp.isEmpty()) { QAction *act = new QAction(button); act->setShortcut(strTmp); button->addAction(act); FQ_VERIFY(connect(act, SIGNAL(triggered()), button, SLOT(slotClicked()))); } FQ_VERIFY(connect(button, SIGNAL(buttonClicked(int)), this, SLOT(keyClicked(int)))); toolBarSetupKeys_->addWidget(button); } } void FQTermFrame::popupFocusIn(FQTermWindow*) { // bring to font if (isHidden()) { show(); } if (isMinimized()) { if (isMaximized()) { showMaximized(); } else { showNormal(); } } raise(); activateWindow(); } void FQTermFrame::insertThemeItem(const QString& themeitem) { QAction *idAction; idAction = menuThemes_->addAction(themeitem, this, SLOT(themesMenuActivated())); idAction->setCheckable(true); idAction->setChecked(themeitem == theme_); } void FQTermFrame::setUseDock(bool use) { if (use == false) { if (tray_) { tray_->hide(); delete tray_; tray_ = 0; //delete menuTray_; //menuTray_ = 0; } return ; } if (tray_ || !QSystemTrayIcon::isSystemTrayAvailable()) { return ; } trayMenu_ = new QMenu; FQ_VERIFY(connect(trayMenu_, SIGNAL(aboutToShow()), SLOT(buildTrayMenu()))); tray_ = new QSystemTrayIcon(this); tray_->setIcon(QPixmap(getPath(RESOURCE) + "pic/fqterm_tray.png")); tray_->setContextMenu(trayMenu_); FQ_VERIFY(connect(tray_, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), SLOT(trayActived(QSystemTrayIcon::ActivationReason)))); tray_->show(); } void FQTermFrame::buildTrayMenu() { if (!trayMenu_) { return ; } trayMenu_->clear(); if (isHidden()) { trayMenu_->addAction(tr("Show"), this, SLOT(trayShow())); } else { trayMenu_->addAction(tr("Hide"), this, SLOT(trayHide())); } trayMenu_->addSeparator(); trayMenu_->addAction(tr("About"), this, SLOT(aboutFQTerm())); trayMenu_->addAction(tr("Exit"), this, SLOT(exitFQTerm())); } void FQTermFrame::trayActived(QSystemTrayIcon::ActivationReason reason) { if (reason == QSystemTrayIcon::Context) { return ; } if (!isVisible()) { trayShow(); } else { trayHide(); } } void FQTermFrame::trayShow() { show(); // bring to font if (isHidden()) { show(); } if (isMinimized()) { if (isMaximized()) { showMaximized(); } else { #ifdef Q_OS_MACX showMaximized(); #else showNormal(); #endif } } raise(); activateWindow(); FQTermWindow* window = windowManager_->activeWindow(); if (window) { window->forcedRepaintScreen(); if (!window->isMaximized()) { windowManager_->refreshAllExcept(window); } } } void FQTermFrame::trayHide() { static bool showTip = true; QString str = config_->getItemValue("global", "traytipshown"); if (str == "1") { showTip = false; } hide(); if (showTip && tray_) { tray_->showMessage(tr("FQTerm"), tr("FQTerm will keep running in the system tray.\n" "To terminate the program, " "choose exit in the tray menu.")); showTip = false; config_->setItemValue("global", "traytipshown", "1"); } } void FQTermFrame::buzz(FQTermWindow* window) { if (windowManager_->activeWindow() == window) return; int xp = x(); int yp = y(); QTime t; t.start(); for (int i = 32; i > 0;) { if (t.elapsed() >= 1) { int delta = i >> 2; int dir = i &3; int dx = ((dir == 1) || (dir == 2)) ? delta : -delta; int dy = (dir < 2) ? delta : -delta; move(xp + dx, yp + dy); t.restart(); i--; } } move(xp, yp); } //-------------------------- //recreate the main menu //-------------------------- void FQTermFrame::recreateMenu() { if (shortcutHelper_) { shortcutHelper_->retranslateActions(); } menuBar()->clear(); delete escapeGroup; delete languageGroup; addMainMenu(); updateLanguageMenu(); QString strTmp = QString(saveState().toHex()); config_->setItemValue("global", "toolbarstate", strTmp); config_->save(getPath(USER_CONFIG) + "fqterm.cfg"); delete toolBarMdiTools_; delete toolBarSetupKeys_; delete toolBarMdiConnectTools_; delete toolBarFonts_; delete menuConnect_; addMainTool(); updateKeyToolBar(); loadToolBarPosition(); if (!windowManager_->activeWindow()) { enableMenuToolBar(false); } else { enableMenuToolBar(true); updateMenuToolBar(); } if (FQTermPref::getInstance()->useStyleSheet_) { refreshStyleSheet(); } } void FQTermFrame::installTranslator(const QString& lang) { config_->setItemValue("global", "language", lang); config_->save(getPath(USER_CONFIG) + "fqterm.cfg"); for (int i = 0; i < translatedModule; ++i) { if (translator[i] != 0) { qApp->removeTranslator(translator[i]); delete translator[i]; translator[i] = 0; } } if (lang != "en_US" && !lang.isEmpty()) { for (int i = 0; i < translatedModule; ++i) { QString dict = getPath(RESOURCE) + "dict/" + qmPrefix[i] + lang + qmPostfix; translator[i] = new QTranslator(0); translator[i]->load(dict); qApp->installTranslator(translator[i]); } } emit changeLanguage(); } void FQTermFrame::initTranslator() { QString dict_path = getPath(RESOURCE) + "dict/"; QDir dictDir(dict_path); QStringList langList; for (int i = 0; i < translatedModule; ++i) { translator[i] = 0; QStringList filter; filter << qmPrefix[i] + "*" + qmPostfix; dictDir.setNameFilters(filter); QFileInfoList list = dictDir.entryInfoList(); FQ_TRACE("translator", 3) << "Found " << list.size() << " " << qmPostfix << " file(s) under path " << dict_path; foreach(QFileInfo info, list){ QString language = info.fileName(); language = language.mid( qmPrefix[i].length(), language.length() - qmPrefix[i].length() - qmPostfix.length()); FQ_TRACE("translator", 3) << "Check file " << info.fileName(); if (!langList.contains(language)) { langList << language; installerList_.append(new TranslatorInstaller(language, this)); FQ_TRACE("translator", 3) << "Found translations for " << language; } else { FQ_TRACE("translator", 3) << "Language " << language << " is already registered."; } } } if (installerList_.empty()) { FQ_TRACE("translator", 0) << "No translations found."; } QString lang = config_->getItemValue("global", "language"); if (!langList.contains(lang)) { lang = QLocale::system().name(); } #if defined(__linux__) || defined(__GLIBC__) if (QLocale::system().language() == QLocale::English) lang = QLocale::system().name(); #endif installTranslator(lang); } void FQTermFrame::clearTranslator() { foreach(TranslatorInstaller* installer, installerList_){ delete installer; } } void FQTermFrame::updateLanguageMenu() { QString strTmp = config_->getItemValue("global", "language"); int i = 0; foreach(TranslatorInstaller* installer, installerList_){ if (installer->languageFormalName() == strTmp) { languageGroup->actions().at(i + 1)->setChecked(true); break; } ++i; } if (!installerList_.isEmpty() && (strTmp == "en_US" || i == installerList_.size())) { languageGroup->actions().at(0)->setChecked(true); } } void FQTermFrame::setFont() { bool isEnglish = (QAction*)(sender()) == getAction(FQTermShortcutHelper::ENGLISHFONT); windowManager_->activeWindow()->setFont(isEnglish); } void FQTermFrame::refreshStyleSheet() { qApp->setStyleSheet(qApp->styleSheet()); } void FQTermFrame::loadStyleSheetFromFile( const QString qssFile ) { QFile file(qssFile); file.open(QIODevice::ReadOnly); QString qss = file.readAll(); qApp->setStyleSheet(qss); file.close(); } void FQTermFrame::clearStyleSheet() { qApp->setStyleSheet(""); } void FQTermFrame::loadToolBarPosition() { //load toolbar setting QString strTmp = config_->getItemValue("global", "toolbarstate"); if (!strTmp.isEmpty()) { restoreState(QByteArray::fromHex(strTmp.toLatin1())); } else { addToolBar(Qt::TopToolBarArea, toolBarMdiConnectTools_); insertToolBar(toolBarMdiConnectTools_,toolBarSetupKeys_); insertToolBar(toolBarSetupKeys_, toolBarMdiTools_); insertToolBar(toolBarMdiTools_, toolBarFonts_); } } void FQTermFrame::toggleAnsiColor() { windowManager_->activeWindow()->getSession()->param().isAnsiColor_ = !windowManager_->activeWindow()->getSession()->param().isAnsiColor_; getAction(FQTermShortcutHelper::ANSICOLOR)->setChecked( windowManager_->activeWindow()->getSession()->param().isAnsiColor_); refreshScreen(); } bool FQTermFrame::clearUp() { if (!windowManager_->closeAllWindow()) return false; saveSetting(); // clear zmodem and pool if needed if (FQTermPref::getInstance()->needClearZmodemPoolOnClose_) { clearDir(FQTermPref::getInstance()->zmodemDir_); clearDir(FQTermPref::getInstance()->poolDir_); clearDir(FQTermPref::getInstance()->poolDir_ + "shadow-cache/"); } setUseDock(false); return true; } void FQTermFrame::editSchema() { schemaDialog schema(this); FQ_VERIFY(connect(&schema, SIGNAL(schemaEdited()), this, SLOT(schemaUpdated()))); schema.exec(); } void FQTermFrame::schemaUpdated() { for (int i = 0; i < windowManager_->count(); ++i) { windowManager_->nthWindow(i)->getScreen()->setSchema(); windowManager_->nthWindow(i)->forcedRepaintScreen(); } } #ifdef USE_GLOBAL_HOTKEY void FQTermFrame::globalHotkeyTriggered() { if (isActiveWindow() && !isMinimized() && isVisible()) { showMinimized(); return; } show(); if (config_->getItemValue("global", "fullscreen") == "1") showFullScreen(); else if (config_->getItemValue("global", "max") == "1") showMaximized(); else showNormal(); raise(); activateWindow(); } void FQTermFrame::globalHotkeyChanged() { globalHotkey_->setShortcut(shortcutHelper_->getAction(FQTermShortcutHelper::GLOBAL_SHOW_FQTERM)->shortcut()); } #endif //USE_GLOBAL_HOTKEY TranslatorInstaller::TranslatorInstaller(const QString& language, FQTermFrame* frame) : language_(language), frame_(frame) { FQTermConfig conf(getPath(USER_CONFIG) + "language.cfg"); languageName_ = conf.getItemValue("Name", language_); if (languageName_.isEmpty()){ languageName_ = QLocale::languageToString(QLocale(language_).language()); if (languageName_ == "C") { languageName_ = "Unknown Language"; } } } QString TranslatorInstaller::languageName() { return languageName_; } void TranslatorInstaller::installTranslator() { frame_->installTranslator(language_); } QString TranslatorInstaller::languageFormalName() { return language_; } } // namespace FQTerm #include "fqterm_frame.moc"