diff options
Diffstat (limited to 'src/ui')
67 files changed, 14852 insertions, 0 deletions
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt new file mode 100644 index 0000000..09af483 --- /dev/null +++ b/src/ui/CMakeLists.txt @@ -0,0 +1,122 @@ +set(fqterm_ui_SRCS + aboutdialog.h + addrdialog.h + articledialog.h + keydialog.h + msgdialog.h + prefdialog.h + quickdialog.h + schemadialog.h + soundconf.h + sshlogindialog.h + zmodemdialog.h + aboutdialog.cpp + addrdialog.cpp + articledialog.cpp + keydialog.cpp + msgdialog.cpp + prefdialog.cpp + quickdialog.cpp + schemadialog.cpp + soundconf.cpp + sshlogindialog.cpp + zmodemdialog.cpp + osdmessage.h + osdmessage.cpp + overlayWidget.h + overlayWidget.cpp + pictureflow.h + pictureflow.cpp + popupMessage.h + popupMessage.cpp + popwidget.h + popwidget.cpp + progressBar.h + progressBar.cpp + fqterm_time_label.h + fqterm_time_label.cpp + fqterm_tool_button.h + fqterm_tool_button.cpp + imageviewer.h + imageviewer.cpp + shortcutdialog.h + shortcutdialog.cpp + statusBar.h + statusBar.cpp + fqterm_canvas.h + fqterm_canvas.cpp + sitemanager.h + sitemanager.cpp + iplookup.h + iplookup.cpp + defineescape.h + defineescape.cpp +) + +set(fqterm_ui_gen_HS + ui_aboutdialog.h + ui_addrdialog.h + ui_articledialog.h + ui_keydialog.h + ui_msgdialog.h + ui_prefdialog.h + ui_quickdialog.h + ui_schemadialog.h + ui_sitemanager.h + ui_soundconf.h + ui_sshlogin.h + ui_zmodemdialog.h + ui_iplookup.h + ui_defineescape.h +) + +set(fqterm_ui_UIS + aboutdialog.ui + addrdialog.ui + articledialog.ui + keydialog.ui + msgdialog.ui + prefdialog.ui + quickdialog.ui + schemadialog.ui + sitemanager.ui + soundconf.ui + sshlogin.ui + zmodemdialog.ui + iplookup.ui + defineescape.ui +) + +qt4_wrap_ui(fqterm_ui_UIS_H + ${fqterm_ui_UIS} +) + +qt4_automoc( + ${fqterm_ui_SRCS} + ${fqterm_ui_gen_HS} +) + +qt4_create_translation(fqterm_ui_qm_file + ${fqterm_ui_UIS} + ${fqterm_ui_SRCS} + ${CMAKE_SOURCE_DIR}/res/dict/ui_zh_CN.ts +) + +include_directories( + ${QT_INCLUDE_DIR} + ${QT_QTCORE_INCLUDE_DIR} + ${QT_QTGUI_INCLUDE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../common + ${CMAKE_CURRENT_SOURCE_DIR}/../utilities + ${CMAKE_CURRENT_BINARY_DIR} +) + +add_library(fqterm_ui + ${fqterm_ui_SRCS} + ${fqterm_ui_gen_HS} +) + +add_dependencies(fqterm_ui + fqterm_common + fqterm_utilities +) diff --git a/src/ui/aboutdialog.cpp b/src/ui/aboutdialog.cpp new file mode 100644 index 0000000..5c56dcc --- /dev/null +++ b/src/ui/aboutdialog.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include <QPixmap> +#include <QFile> +#include <QTextBrowser> +#include <QTextStream> +#include <QtGlobal> + +#include "fqterm.h" +#include "fqterm_path.h" +#include "aboutdialog.h" + +namespace FQTerm { + +/* + * Constructs a aboutDialog which is a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +aboutDialog::aboutDialog(QWidget *parent, Qt::WFlags fl) + : QDialog(parent, fl) { + ui_.setupUi(this); + + QFile file(getPath(RESOURCE) + "credits"); + if (file.open(QIODevice::ReadOnly)) { + QTextStream stream(&file); + QString line; + while (!stream.atEnd()) { + // line of text excluding '\n' + line += stream.readLine() + "\n"; + } + ui_.TextBrowser->setPlainText(line); + file.close(); + } + QString aboutText = "FQTerm " + QString(FQTERM_VERSION_STRING) + QString("\nSVN revision ") + QString(FQTERM_SVN_REVISION) + QString("\n Built with Qt") + QT_VERSION_STR + QString("\n Running with Qt ") + qVersion(); + if (QString(FQTERM_VERSION_STRING).startsWith("0.9.8")) { + aboutText += "\n>>2012 - End of the world edition<<"; + } + ui_.TextLabel->setText(aboutText); +} + +/* + * Destroys the object and frees any allocated resources + */ +aboutDialog::~aboutDialog() { + // no need to delete child widgets, Qt does it all for us +} + +} // namespace FQTerm + +#include "aboutdialog.moc" diff --git a/src/ui/aboutdialog.h b/src/ui/aboutdialog.h new file mode 100644 index 0000000..cf40c4b --- /dev/null +++ b/src/ui/aboutdialog.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef FQTERM_ABOUT_DIALOG_H +#define FQTERM_ABOUT_DIALOG_H + +#include "ui_aboutdialog.h" + +namespace FQTerm { + +class aboutDialog: public QDialog { + Q_OBJECT; + public: + aboutDialog(QWidget *parent = 0, Qt::WFlags fl = 0); + ~aboutDialog(); + private: + Ui::aboutDialog ui_; +}; + +} // namespace FQTerm + +#endif // FQTERM_ABOUT_DIALOG_H diff --git a/src/ui/aboutdialog.ui b/src/ui/aboutdialog.ui new file mode 100644 index 0000000..5770cd8 --- /dev/null +++ b/src/ui/aboutdialog.ui @@ -0,0 +1,175 @@ +<ui version="4.0" > + <class>aboutDialog</class> + <widget class="QDialog" name="aboutDialog" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>290</height> + </rect> + </property> + <property name="mouseTracking" > + <bool>false</bool> + </property> + <property name="windowTitle" > + <string>About FQTerm</string> + </property> + <layout class="QGridLayout" > + <item row="0" column="0" > + <widget class="QLabel" name="pixmapLabel" > + <property name="text" > + <string/> + </property> + <property name="scaledContents" > + <bool>true</bool> + </property> + </widget> + </item> + <item row="0" column="1" > + <widget class="QLabel" name="TextLabel" > + <property name="frameShape" > + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow" > + <enum>QFrame::Plain</enum> + </property> + <property name="text" > + <string>FQTerm</string> + </property> + <property name="alignment" > + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="1" column="0" colspan="3" > + <widget class="QTabWidget" name="mainTabWidget" > + <property name="currentIndex" > + <number>0</number> + </property> + <widget class="QWidget" name="tab1" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>376</width> + <height>194</height> + </rect> + </property> + <attribute name="title" > + <string>About</string> + </attribute> + <layout class="QGridLayout" > + <item row="0" column="0" > + <widget class="QLabel" name="label" > + <property name="text" > + <string><html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br />FQTerm<br /><br /><br /><a href="http://code.google.com/p/fqterm"><span style=" text-decoration: underline; color:#0000ff;">http://code.google.com/p/fqterm</span></a></p></body></html></string> + </property> + <property name="textFormat" > + <enum>Qt::RichText</enum> + </property> + <property name="alignment" > + <set>Qt::AlignCenter</set> + </property> + <property name="openExternalLinks" > + <bool>true</bool> + </property> + <property name="textInteractionFlags" > + <set>Qt::TextBrowserInteraction</set> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab2" > + <property name="geometry" > + <rect> + <x>77</x> + <y>97</y> + <width>944</width> + <height>522</height> + </rect> + </property> + <attribute name="title" > + <string>Authors</string> + </attribute> + <layout class="QGridLayout" > + <item row="0" column="0" > + <widget class="QLabel" name="TextLabel1" > + <property name="text" > + <string>fqterm@gmail.com + +devilphoenix@newsmth</string> + </property> + <property name="alignment" > + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab3" > + <property name="geometry" > + <rect> + <x>100</x> + <y>120</y> + <width>944</width> + <height>522</height> + </rect> + </property> + <attribute name="title" > + <string>Credits</string> + </attribute> + <layout class="QGridLayout" > + <item row="0" column="0" > + <widget class="QTextBrowser" name="TextBrowser" > + <property name="html" > + <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'SimSun'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html></string> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + <item row="2" column="2" > + <widget class="QPushButton" name="closeButton" > + <property name="text" > + <string>Close</string> + </property> + </widget> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11" /> + <tabstops> + <tabstop>closeButton</tabstop> + <tabstop>mainTabWidget</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>closeButton</sender> + <signal>clicked()</signal> + <receiver>aboutDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel" > + <x>339</x> + <y>261</y> + </hint> + <hint type="destinationlabel" > + <x>211</x> + <y>249</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/ui/addrdialog.cpp b/src/ui/addrdialog.cpp new file mode 100644 index 0000000..79e62a8 --- /dev/null +++ b/src/ui/addrdialog.cpp @@ -0,0 +1,396 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include <QPixmap> +#include <QMessageBox> +#include <QColorDialog> +#include <QFontDialog> +#include <QPainter> +#include <QFileDialog> +#include <QPalette> +#include <QMenu> + +#include "fqterm_config.h" +#include "fqterm_param.h" +#include "fqterm_path.h" +#include "fqterm_trace.h" + +#include "addrdialog.h" +#include "schemadialog.h" + +namespace FQTerm { + +const int addrDialog::ports[3] = {23, 22, 22}; + +/* + * Constructs a addrDialog which is a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +addrDialog::addrDialog(QWidget *parent_, const FQTermParam& parameter, int buttons, Qt::WFlags fl) + : QDialog(parent_, fl), + menuButtonGroup_(this), + param_(parameter) { + ui_.setupUi(this); + menuButtonGroup_.addButton(ui_.radioButton1, 0); + menuButtonGroup_.addButton(ui_.radioButton2, 1); + menuButtonGroup_.addButton(ui_.radioButton3, 2); + if (!(buttons & SAVE)) + ui_.savePushButton->setVisible(false); + if (!(buttons & APPLY)) + ui_.applyPushButton->setVisible(false); + QMenu *fontMenu = new QMenu(this); + for (int i = 0; i < 2; ++i) { + QAction *act = fontMenu->addAction(FQTermParam::getLanguageName(bool(i)) + " Font", this, SLOT(onFont())); + act->setData(i); + } + ui_.fontToolButton->setMenu(fontMenu); + setUIFromParam(); + connector(); +} + +void addrDialog::setParamFromUI() { + param_.name_ = ui_.nameLineEdit->text(); + param_.hostAddress_ = ui_.addrLineEdit->text(); + param_.port_ = ui_.portLineEdit->text().toUShort(); + param_.hostType_ = ui_.hostTypeComboBox->currentIndex(); + param_.preLoginCommand_ = ui_.preloginLineEdit->text(); + param_.userName_ = ui_.userLineEdit->text(); + param_.password_ = ui_.passwdLineEdit->text(); + param_.postLoginCommand_ = ui_.postloginLineEdit->text(); + param_.serverEncodingID_ = ui_.bbscodeComboBox->currentIndex(); + param_.isFontAutoFit_ = ui_.fontAdjustComboBox->currentIndex(); + param_.isAlwaysHighlight_ = ui_.highlightCheckBox->isChecked(); + param_.isAnsiColor_ = ui_.ansicolorCheckBox->isChecked(); + param_.backgroundColor_ = ui_.fontPreviewer->palette().color(QPalette::Background); + param_.foregroundColor_ = ui_.fontPreviewer->palette().color(QPalette::Foreground); + param_.schemaFileName_ = ui_.schemaComboBox->currentText().isEmpty() || ui_.schemaComboBox->currentIndex() >= schemaDialog::getSchemaList().count() + ? "" : schemaDialog::getSchemaList()[ui_.schemaComboBox->currentIndex()].absoluteFilePath(); + param_.virtualTermType_ = ui_.termtypeLineEdit->text(); + param_.keyboardType_ = ui_.keytypeComboBox->currentIndex(); + param_.backspaceType_ = ui_.backspace8->isChecked()?0:1; + param_.numColumns_ = ui_.columnLineEdit->text().toInt(); + param_.numRows_ = ui_.rowLineEdit->text().toInt(); + param_.numScrollLines_ = ui_.scrollLineEdit->text().toInt(); + param_.cursorType_ = ui_.cursorTypeComboBox->currentIndex(); + param_.escapeString_ = ui_.escapeLineEdit->text(); + param_.proxyType_ = ui_.proxytypeComboBox->currentIndex(); + param_.proxyHostName_ = ui_.proxyaddrLineEdit->text(); + param_.proxyPort_ = ui_.proxyportLineEdit->text().toUShort(); + param_.isAuthentation_ = ui_.authentationGroup->isChecked(); + param_.proxyUserName_ = ui_.proxyuserLineEdit->text(); + param_.proxyPassword_ = ui_.proxypasswdLineEdit->text(); + param_.protocolType_ = ui_.protocolComboBox->currentIndex(); + if (param_.port_ != ports[param_.protocolType_]) { + ui_.portCheckBox->setChecked(true); + } + switch(param_.protocolType_) + { + case 0: + param_.isAutoLogin_ = ui_.telnetAutoLoginGroup->isChecked(); + break; + case 1: + case 2: + param_.isAutoLogin_ = ui_.sshAutoLoginGroup->isChecked(); + case 100: + break; + } + param_.sshUserName_ = ui_.sshuserLineEdit->text(); + param_.sshPassword_ = ui_.sshpasswdLineEdit->text(); + param_.maxIdleSeconds_ = ui_.idletimeLineEdit->text().toInt(); + param_.replyKeyCombination_ = ui_.replykeyLineEdit->text(); + if (param_.replyKeyCombination_.isNull()) { + FQ_TRACE("addrdialog", 0) << "Key combination for reply is NULL."; + } + param_.antiIdleMessage_ = ui_.antiLineEdit->text(); + param_.isAntiIdle_ = ui_.antiIdleGroupBox->isChecked(); + param_.isAutoReply_ = ui_.replyCheckBox->isChecked(); + param_.autoReplyMessage_ = ui_.replyLineEdit->text(); + param_.isAutoReconnect_ = ui_.reconnectCheckBox->isChecked(); + param_.reconnectInterval_ = ui_.reconnectLineEdit->text().toInt(); + param_.retryTimes_ = ui_.retryLineEdit->text().toInt(); + param_.isAutoCloseWin_ = ui_.autoCloseWinCheckBox->isChecked(); + param_.isAutoLoadScript_ = ui_.scriptCheckBox->isChecked(); + param_.enableZmodem_ = ui_.zmodemCheck->isChecked(); + param_.isBeep_ = ui_.beepCheck->isChecked(); + param_.isBuzz_ = ui_.buzzCheck->isChecked(); + param_.isSupportMouse_ = ui_.mouseCheck->isChecked(); + param_.autoLoadedScriptFileName_ = ui_.scriptLineEdit->text(); + param_.menuType_ = menuButtonGroup_.checkedId(); + param_.menuColor_ = ui_.menuLabel->palette().color(QPalette::Background); + param_.alignMode_ = ui_.alignComboBox->currentIndex(); + param_.charSpacing_ = ui_.charSpacingSpinBox->value(); + param_.lineSpacing_ = ui_.lineSpacingSpinBox->value(); +} + +void addrDialog::setUIFromParam() { + + updateSchemaList(param_.schemaFileName_); + QString strTmp; + ui_.nameLineEdit->setText(param_.name_); + ui_.addrLineEdit->setText(param_.hostAddress_); + ui_.hostTypeComboBox->setCurrentIndex(param_.hostType_); +// ui_.autoLoginCheckBox->setChecked(param_.isAutoLogin_); + ui_.preloginLineEdit->setText(param_.preLoginCommand_); + ui_.userLineEdit->setText(param_.userName_); + ui_.passwdLineEdit->setText(param_.password_); + ui_.postloginLineEdit->setText(param_.postLoginCommand_); + ui_.bbscodeComboBox->setCurrentIndex(param_.serverEncodingID_); + ui_.fontAdjustComboBox->setCurrentIndex(param_.isFontAutoFit_); + ui_.highlightCheckBox->setChecked(param_.isAlwaysHighlight_); + ui_.ansicolorCheckBox->setChecked(param_.isAnsiColor_); + ui_.termtypeLineEdit->setText(param_.virtualTermType_); + ui_.keytypeComboBox->setCurrentIndex(param_.keyboardType_); + ui_.backspace8->setChecked(param_.backspaceType_ == 0); + ui_.backspace127->setChecked(param_.backspaceType_ == 1); + strTmp.setNum(param_.numColumns_); + ui_.columnLineEdit->setText(strTmp); + strTmp.setNum(param_.numRows_); + ui_.rowLineEdit->setText(strTmp); + strTmp.setNum(param_.numScrollLines_); + ui_.scrollLineEdit->setText(strTmp); + ui_.cursorTypeComboBox->setCurrentIndex(param_.cursorType_); + ui_.escapeLineEdit->setText(param_.escapeString_); + ui_.proxytypeComboBox->setCurrentIndex(param_.proxyType_); + ui_.proxyaddrLineEdit->setText(param_.proxyHostName_); + strTmp.setNum(param_.proxyPort_); + ui_.proxyportLineEdit->setText(strTmp); + ui_.authentationGroup->setChecked(param_.isAuthentation_); + ui_.proxyuserLineEdit->setText(param_.proxyUserName_); + ui_.proxypasswdLineEdit->setText(param_.proxyPassword_); + ui_.protocolComboBox->setCurrentIndex(param_.protocolType_); + onProtocol(param_.protocolType_); + strTmp.setNum(param_.port_); + ui_.portLineEdit->setText(strTmp); + ui_.portCheckBox->setChecked(param_.port_ != ports[param_.protocolType_]); + ui_.sshuserLineEdit->setText(param_.sshUserName_); + ui_.sshpasswdLineEdit->setText(param_.sshPassword_); + strTmp.setNum(param_.maxIdleSeconds_); + ui_.idletimeLineEdit->setText(strTmp); + ui_.replykeyLineEdit->setText(param_.replyKeyCombination_); + ui_.antiLineEdit->setText(param_.antiIdleMessage_); + ui_.antiIdleGroupBox->setChecked(param_.isAntiIdle_); + ui_.replyCheckBox->setChecked(param_.isAutoReply_); + ui_.replyLineEdit->setEnabled(param_.isAutoReply_); + ui_.replyLineEdit->setText(param_.autoReplyMessage_); + ui_.reconnectCheckBox->setChecked(param_.isAutoReconnect_); + ui_.reconnectLineEdit->setEnabled(param_.isAutoReconnect_); + ui_.retryLineEdit->setEnabled(param_.isAutoReconnect_); + ui_.alignComboBox->setCurrentIndex(param_.alignMode_); + ui_.charSpacingSpinBox->setValue(param_.charSpacing_); + ui_.lineSpacingSpinBox->setValue(param_.lineSpacing_); + strTmp.setNum(param_.reconnectInterval_); + ui_.reconnectLineEdit->setText(strTmp); + strTmp.setNum(param_.retryTimes_); + ui_.retryLineEdit->setText(strTmp); + ui_.autoCloseWinCheckBox->setChecked(param_.isAutoCloseWin_); + ui_.scriptCheckBox->setChecked(param_.isAutoLoadScript_); + ui_.scriptLineEdit->setText(param_.autoLoadedScriptFileName_); + ui_.zmodemCheck->setChecked(param_.enableZmodem_); + ui_.beepCheck->setChecked(param_.isBeep_); + ui_.buzzCheck->setChecked(param_.isBuzz_); + ui_.mouseCheck->setChecked(param_.isSupportMouse_); + //ui.menuGroup->setButton(param_.m_nMenuType); + QRadioButton *rbMenu = qobject_cast < QRadioButton * > (menuButtonGroup_.button + (param_.menuType_)); + rbMenu->setChecked(true); + previewFont(); + previewMenu(); +} + + +/* + * Destroys the object and frees any allocated resources + */ +addrDialog::~addrDialog() { +} + + +void addrDialog::onOK() { + setParamFromUI(); + done(1); +} + +void addrDialog::onSave() { + setParamFromUI(); + done(2); +} +void addrDialog::onCancel() { + done(0); +} + + + +void addrDialog::onFgcolor() { + QColor color = QColorDialog::getColor(param_.foregroundColor_); + if (color.isValid() == TRUE) { + param_.foregroundColor_ = color; + previewFont(); + } +} + +void addrDialog::onBgcolor() { + QColor color = QColorDialog::getColor(param_.backgroundColor_); + if (color.isValid() == TRUE) { + param_.backgroundColor_ = color; + previewFont(); + } +} + + + +void addrDialog::onProtocol(int n) { + ui_.portCheckBox->setChecked(false); + ui_.portLineEdit->setText(QString("%1").arg(ports[n])); + switch(n) + { + case 0: //telnet + ui_.telnetAutoLoginGroup->setEnabled(true); + ui_.telnetAutoLoginGroup->setChecked(param_.isAutoLogin_); + ui_.sshAutoLoginGroup->setEnabled(false); + ui_.sshAutoLoginGroup->setChecked(false); + break; + case 1: +#if defined(_NO_SSH_COMPILED) + QMessageBox::warning(this, "sorry", + "SSH support is not compiled, check your OpenSSL and try to recompile FQTerm"); + ui_.protocolComboBox->setCurrentItem(0); +#else + ui_.telnetAutoLoginGroup->setEnabled(false); + ui_.telnetAutoLoginGroup->setChecked(false); + ui_.sshAutoLoginGroup->setEnabled(true); + ui_.sshAutoLoginGroup->setChecked(param_.isAutoLogin_); +#endif + break; + case 2: +#if defined(_NO_SSH_COMPILED) + QMessageBox::warning(this, "sorry", + "SSH support is not compiled, check your OpenSSL and try to recompile FQTerm"); + ui_.protocolComboBox->setCurrentItem(0); +#else + ui_.telnetAutoLoginGroup->setEnabled(false); + ui_.telnetAutoLoginGroup->setChecked(false); + ui_.sshAutoLoginGroup->setEnabled(true); + ui_.sshAutoLoginGroup->setChecked(param_.isAutoLogin_); +#endif + break; + } +} + +void addrDialog::onChooseScript() { + QString path = getPath(RESOURCE) + "script"; + + QString strFile = QFileDialog::getOpenFileName(this, "choose a script file", + path, "JavaScript/Python File (*.js *.py)"); + + if (strFile.isNull()) { + return ; + } + + ui_.scriptLineEdit->setText(strFile); +} + +void addrDialog::onMenuColor() { + QColor color = QColorDialog::getColor(param_.menuColor_); + if (color.isValid() == TRUE) { + param_.menuColor_ = color; + previewMenu(); + } +} + +void addrDialog::previewFont() { + //issue 98 preview both en and zh + + QPalette palette; + palette.setColor(QPalette::Window, param_.backgroundColor_); + palette.setColor(QPalette::WindowText, param_.foregroundColor_); + ui_.fontPreviewer->setPalette(palette); + QString sample("<html><body style=\" font-family:'" + param_.englishFontName_ + + "'; font-size:" + QString().setNum(param_.englishFontSize_) + + "pt;\"><BR>AaBbCc</body></html>"); + sample += QString("<html><body style=\" font-family:'" + + param_.otherFontName_ + "'; font-size:" + + QString().setNum(param_.otherFontSize_) + "pt;\">" + + param_.otherFontName_ + "<BR></body></html>"); + ui_.fontPreviewer->setText(sample); +} + + +void addrDialog::connector() { + FQ_VERIFY(connect(ui_.applyPushButton, SIGNAL(clicked()), this, SLOT(onOK()))); + FQ_VERIFY(connect(ui_.savePushButton, SIGNAL(clicked()), this, SLOT(onSave()))); + FQ_VERIFY(connect(ui_.closePushButton, SIGNAL(clicked()), this, SLOT(onCancel()))); + + + FQ_VERIFY(connect(ui_.fgcolorPushButton, SIGNAL(clicked()), this, SLOT(onFgcolor()))); + FQ_VERIFY(connect(ui_.bgcolorPushButton, SIGNAL(clicked()), this, SLOT(onBgcolor()))); + + FQ_VERIFY(connect(ui_.protocolComboBox, SIGNAL(activated(int)), this, SLOT(onProtocol(int)))); + + FQ_VERIFY(connect(ui_.scriptPushButton, SIGNAL(clicked()), this, SLOT(onChooseScript()))); + + FQ_VERIFY(connect(ui_.menuColorButton, SIGNAL(clicked()), this, SLOT(onMenuColor()))); +} + +void addrDialog::previewMenu() { + QPalette palette; + palette.setColor(QPalette::Window, param_.menuColor_); + ui_.menuLabel->setPalette(palette); +} + +void addrDialog::onFont() { + bool isEnglish = ((QAction*)(sender()))->data().toBool(); + bool ok; + QString& fontName = isEnglish?param_.englishFontName_:param_.otherFontName_; + int& fontSize = isEnglish?param_.englishFontSize_:param_.otherFontSize_; + QFont now(fontName, fontSize); + + QFont font = QFontDialog::getFont(&ok, now, this, tr("Font Selector") +#ifdef __APPLE__ + , QFontDialog::DontUseNativeDialog +#endif + ); + if (ok == true) { + fontName = font.family(); + fontSize = font.pointSize(); + previewFont(); + } +} + +void addrDialog::updateSchemaList(const QString& currentSchema) { + ui_.schemaComboBox->clear(); + QFileInfoList lstFile = schemaDialog::getSchemaList(); + foreach(QFileInfo fi, lstFile) { + FQTermConfig *pConf = new FQTermConfig(fi.absoluteFilePath()); + ui_.schemaComboBox->addItem(pConf->getItemValue("schema", "title")); + delete pConf; + } + ui_.schemaComboBox->addItem(""); + int schemaIdx = lstFile.indexOf(currentSchema); + if (schemaIdx < 0) + schemaIdx = ui_.schemaComboBox->count() - 1; + ui_.schemaComboBox->setCurrentIndex(schemaIdx); +} + +} // namespace FQTerm + +#include "addrdialog.moc" diff --git a/src/ui/addrdialog.h b/src/ui/addrdialog.h new file mode 100644 index 0000000..8405a0a --- /dev/null +++ b/src/ui/addrdialog.h @@ -0,0 +1,87 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef FQTERM_ADDR_DIALOG_H +#define FQTERM_ADDR_DIALOG_H + +#include <QButtonGroup> + +#include "fqterm_param.h" +#include "ui_addrdialog.h" + +namespace FQTerm { + +class FQTermConfig; + +class addrDialog: public QDialog { + Q_OBJECT; + public: + enum BUTTONS{SAVE = 0x01, APPLY = 0x02}; + addrDialog(QWidget *parent_ = 0, const FQTermParam& param = FQTermParam(), int buttons = SAVE | APPLY, Qt::WFlags fl = 0); + ~addrDialog(); + void setParam(const FQTermParam& param) { + param_ = param; + } + FQTermParam param() { + return param_; + } + + enum Tabs{General, Display, Terminal, Keyboard, Proxy, Misc, Mouse}; + void setCurrentTabIndex(Tabs tab) { + ui_.tabWidget->setCurrentIndex(tab); + } + + static const int ports[3]; // telnet, ssh1, ssh2 + + protected slots: + void onOK(); + void onSave(); + void onCancel(); + void onFgcolor(); + void onBgcolor(); + void onProtocol(int); + void onChooseScript(); + void onMenuColor(); + void onFont(); + + protected: + void connector(); + bool isChanged(); + void previewFont(); + void previewMenu(); + void setUIFromParam(); + void setParamFromUI(); + + QButtonGroup menuButtonGroup_; + + private: + + FQTermParam param_; + Ui::addrDialog ui_; + + void updateSchemaList(const QString& currentFile); +}; + + + + +} // namespace FQTerm + +#endif // FQTERM_ADDR_DIALOG_H diff --git a/src/ui/addrdialog.ui b/src/ui/addrdialog.ui new file mode 100644 index 0000000..e5dc40b --- /dev/null +++ b/src/ui/addrdialog.ui @@ -0,0 +1,1211 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>addrDialog</class> + <widget class="QDialog" name="addrDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>493</width> + <height>383</height> + </rect> + </property> + <property name="windowTitle"> + <string>Site Setting</string> + </property> + <layout class="QGridLayout" name="gridLayout_4"> + <item row="1" column="0"> + <spacer> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="1"> + <widget class="QPushButton" name="applyPushButton"> + <property name="text"> + <string>Apply (&Temporarily)</string> + </property> + </widget> + </item> + <item row="1" column="3"> + <widget class="QPushButton" name="closePushButton"> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="shortcut"> + <string/> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QPushButton" name="savePushButton"> + <property name="text"> + <string>&Apply (Save)</string> + </property> + </widget> + </item> + <item row="0" column="0" colspan="4"> + <widget class="QTabWidget" name="tabWidget"> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="Widget2"> + <attribute name="title"> + <string>General</string> + </attribute> + <layout class="QGridLayout"> + <item row="0" column="0"> + <layout class="QGridLayout" name="_2"> + <item row="0" column="0"> + <widget class="QLabel" name="TextLabel1"> + <property name="text"> + <string>Name</string> + </property> + <property name="alignment"> + <set>Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="0" column="1" colspan="3"> + <widget class="QLineEdit" name="nameLineEdit"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="TextLabel2"> + <property name="text"> + <string>Address</string> + </property> + <property name="alignment"> + <set>Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="1" column="1" colspan="3"> + <widget class="QLineEdit" name="addrLineEdit"/> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="TextLabel1_3"> + <property name="text"> + <string>Protocol</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QComboBox" name="protocolComboBox"> + <item> + <property name="text"> + <string>Telnet</string> + </property> + </item> + <item> + <property name="text"> + <string>SSH1</string> + </property> + </item> + <item> + <property name="text"> + <string>SSH2</string> + </property> + </item> + </widget> + </item> + <item row="2" column="3"> + <widget class="QLineEdit" name="portLineEdit"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="TextLabel3_6"> + <property name="text"> + <string>Type</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QComboBox" name="hostTypeComboBox"> + <item> + <property name="text"> + <string>BBS</string> + </property> + </item> + <item> + <property name="text"> + <string>*NIX</string> + </property> + </item> + </widget> + </item> + <item row="4" column="0" colspan="4"> + <widget class="QGroupBox" name="telnetAutoLoginGroup"> + <property name="title"> + <string>Telnet Auto Login</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <layout class="QGridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="TextLabel1_2"> + <property name="text"> + <string>Prelogin</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="preloginLineEdit"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="TextLabel4"> + <property name="text"> + <string>User</string> + </property> + <property name="alignment"> + <set>Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="userLineEdit"/> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="TextLabel5"> + <property name="text"> + <string>Password</string> + </property> + <property name="alignment"> + <set>Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLineEdit" name="passwdLineEdit"> + <property name="echoMode"> + <enum>QLineEdit::Password</enum> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="TextLabel11"> + <property name="text"> + <string>Postlogin</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLineEdit" name="postloginLineEdit"/> + </item> + </layout> + </widget> + </item> + <item row="2" column="2"> + <widget class="QCheckBox" name="portCheckBox"> + <property name="text"> + <string>Port</string> + </property> + </widget> + </item> + <item row="4" column="4"> + <widget class="QGroupBox" name="sshAutoLoginGroup"> + <property name="title"> + <string>SSH Auto Login</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <layout class="QGridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="TextLabel2_3"> + <property name="text"> + <string>User</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="sshuserLineEdit"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="TextLabel3_3"> + <property name="text"> + <string>Password</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="sshpasswdLineEdit"> + <property name="echoMode"> + <enum>QLineEdit::Password</enum> + </property> + </widget> + </item> + <item row="2" column="0"> + <spacer> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab1"> + <attribute name="title"> + <string>Display</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <widget class="QLabel" name="TextLabel6"> + <property name="text"> + <string>BBS Encoding</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="bbscodeComboBox"> + <item> + <property name="text"> + <string>GBK</string> + </property> + </item> + <item> + <property name="text"> + <string>BIG5</string> + </property> + </item> + <item> + <property name="text"> + <string>UTF8</string> + </property> + </item> + <item> + <property name="text"> + <string>BIG5-HKSCS</string> + </property> + </item> + <item> + <property name="text"> + <string>BIG5-UAO</string> + </property> + </item> + </widget> + </item> + <item row="2" column="0"> + <widget class="QCheckBox" name="highlightCheckBox"> + <property name="text"> + <string>Always Hightlight</string> + </property> + </widget> + </item> + <item row="4" column="0" rowspan="4" colspan="4"> + <widget class="QLabel" name="fontPreviewer"> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="text"> + <string>TextLabel3</string> + </property> + <property name="textFormat"> + <enum>Qt::RichText</enum> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="2" column="3"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Align Mode</string> + </property> + </widget> + </item> + <item row="0" column="4"> + <widget class="QSpinBox" name="lineSpacingSpinBox"/> + </item> + <item row="0" column="3"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Line Spacing</string> + </property> + </widget> + </item> + <item row="1" column="4"> + <widget class="QSpinBox" name="charSpacingSpinBox"/> + </item> + <item row="1" column="3"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Char Spacing</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QCheckBox" name="ansicolorCheckBox"> + <property name="text"> + <string>ANSI Color</string> + </property> + </widget> + </item> + <item row="2" column="4"> + <widget class="QComboBox" name="alignComboBox"> + <item> + <property name="text"> + <string>Align Mid</string> + </property> + </item> + <item> + <property name="text"> + <string>Align Bottom</string> + </property> + </item> + <item> + <property name="text"> + <string>Align Top</string> + </property> + </item> + </widget> + </item> + <item row="7" column="4"> + <widget class="QComboBox" name="schemaComboBox"/> + </item> + <item row="6" column="4"> + <widget class="QPushButton" name="bgcolorPushButton"> + <property name="text"> + <string>Background</string> + </property> + </widget> + </item> + <item row="5" column="4"> + <widget class="QPushButton" name="fgcolorPushButton"> + <property name="text"> + <string>Text Color</string> + </property> + </widget> + </item> + <item row="4" column="4"> + <widget class="QToolButton" name="fontToolButton"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Font</string> + </property> + <property name="popupMode"> + <enum>QToolButton::InstantPopup</enum> + </property> + <property name="toolButtonStyle"> + <enum>Qt::ToolButtonTextOnly</enum> + </property> + <property name="arrowType"> + <enum>Qt::DownArrow</enum> + </property> + </widget> + </item> + <item row="1" column="0" colspan="2"> + <widget class="QComboBox" name="fontAdjustComboBox"> + <property name="currentIndex"> + <number>1</number> + </property> + <item> + <property name="text"> + <string>Keep Font; Adjust Row/Column.</string> + </property> + </item> + <item> + <property name="text"> + <string>Keep Row/Column; Adjust Font.</string> + </property> + </item> + <item> + <property name="text"> + <string>Keep Font; Keep Row/Column.</string> + </property> + </item> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab2"> + <attribute name="title"> + <string>Terminal</string> + </attribute> + <layout class="QGridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="TextLabel1_5"> + <property name="text"> + <string>Term Type</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="termtypeLineEdit"/> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="TextLabel2_5"> + <property name="text"> + <string>Key Type</string> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QComboBox" name="keytypeComboBox"> + <item> + <property name="text"> + <string>VT100</string> + </property> + </item> + <item> + <property name="text"> + <string>XTERM</string> + </property> + </item> + <item> + <property name="text"> + <string>BBS</string> + </property> + </item> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="TextLabel3_4"> + <property name="text"> + <string>Columns</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="columnLineEdit"/> + </item> + <item row="1" column="2"> + <widget class="QLabel" name="TextLabel5_3"> + <property name="text"> + <string>Scroll Lines</string> + </property> + </widget> + </item> + <item row="1" column="3"> + <widget class="QLineEdit" name="scrollLineEdit"/> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="TextLabel4_3"> + <property name="text"> + <string>Rows</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLineEdit" name="rowLineEdit"/> + </item> + <item row="2" column="2"> + <widget class="QLabel" name="TextLabel6_3"> + <property name="text"> + <string>Cursor Type</string> + </property> + </widget> + </item> + <item row="2" column="3"> + <widget class="QComboBox" name="cursorTypeComboBox"> + <item> + <property name="text"> + <string>Block</string> + </property> + </item> + <item> + <property name="text"> + <string>Underline</string> + </property> + </item> + <item> + <property name="text"> + <string>I Type</string> + </property> + </item> + </widget> + </item> + <item row="3" column="0" colspan="2"> + <widget class="QLabel" name="TextLabel1_4"> + <property name="text"> + <string>Escape string (i.e. *[ )</string> + </property> + </widget> + </item> + <item row="3" column="2" colspan="2"> + <widget class="QLineEdit" name="escapeLineEdit"/> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab7"> + <attribute name="title"> + <string>Keyboard</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="BackSpace"> + <property name="title"> + <string>BackSpace Setting</string> + </property> + <layout class="QGridLayout" name="_3"> + <item row="0" column="0"> + <widget class="QRadioButton" name="backspace8"> + <property name="text"> + <string>Send backspace as ^H</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QRadioButton" name="backspace127"> + <property name="text"> + <string>Send backspace as ^? (127)</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="spacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab3"> + <attribute name="title"> + <string>Proxy</string> + </attribute> + <layout class="QGridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="TextLabel2_2"> + <property name="text"> + <string>Type</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="proxytypeComboBox"> + <item> + <property name="text"> + <string>None</string> + </property> + </item> + <item> + <property name="text"> + <string>Wingate</string> + </property> + </item> + <item> + <property name="text"> + <string>SOCKS4</string> + </property> + </item> + <item> + <property name="text"> + <string>SOCKS5</string> + </property> + </item> + <item> + <property name="text"> + <string>HTTP</string> + </property> + </item> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="TextLabel3_2"> + <property name="text"> + <string>Address</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="proxyaddrLineEdit"/> + </item> + <item row="1" column="2"> + <widget class="QLabel" name="TextLabel4_2"> + <property name="text"> + <string>Port</string> + </property> + </widget> + </item> + <item row="1" column="3"> + <widget class="QLineEdit" name="proxyportLineEdit"/> + </item> + <item row="2" column="0" colspan="4"> + <widget class="QGroupBox" name="authentationGroup"> + <property name="title"> + <string>Authentation</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <layout class="QGridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="TextLabel5_2"> + <property name="text"> + <string>User</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="proxyuserLineEdit"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="TextLabel5_4"> + <property name="text"> + <string>Password</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="proxypasswdLineEdit"/> + </item> + </layout> + </widget> + </item> + <item row="3" column="0"> + <spacer> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <widget class="QWidget" name="Widget3"> + <attribute name="title"> + <string>Misc</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0" colspan="5"> + <widget class="QGroupBox" name="antiIdleGroupBox"> + <property name="title"> + <string>Anti-idle</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="1"> + <widget class="QLineEdit" name="antiLineEdit"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="TextLabel8"> + <property name="text"> + <string>Max Idle Time</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="idletimeLineEdit"/> + </item> + <item row="1" column="2"> + <widget class="QLabel" name="TextLabel9"> + <property name="text"> + <string>s</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Anti-idle String</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item row="1" column="0" colspan="2"> + <widget class="QLabel" name="textLabel1_2"> + <property name="text"> + <string>Key to reply message</string> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QLineEdit" name="replykeyLineEdit"/> + </item> + <item row="2" column="0" colspan="2"> + <widget class="QCheckBox" name="replyCheckBox"> + <property name="text"> + <string>Autoreply Message</string> + </property> + </widget> + </item> + <item row="2" column="2" colspan="3"> + <widget class="QLineEdit" name="replyLineEdit"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="3" column="0" colspan="3"> + <widget class="QCheckBox" name="reconnectCheckBox"> + <property name="text"> + <string>When disconnected, reconnect every</string> + </property> + </widget> + </item> + <item row="3" column="3"> + <widget class="QLineEdit" name="reconnectLineEdit"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="3" column="4"> + <widget class="QLabel" name="textLabel2"> + <property name="text"> + <string>s</string> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="textLabel4"> + <property name="text"> + <string>For Maximum</string> + </property> + </widget> + </item> + <item row="4" column="1" colspan="2"> + <widget class="QLineEdit" name="retryLineEdit"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="4" column="3" colspan="2"> + <widget class="QLabel" name="textLabel5"> + <property name="text"> + <string>Times (-1 means infinite)</string> + </property> + </widget> + </item> + <item row="6" column="0" colspan="2"> + <widget class="QCheckBox" name="scriptCheckBox"> + <property name="text"> + <string>Load Control Script</string> + </property> + </widget> + </item> + <item row="7" column="0" colspan="3"> + <widget class="QLineEdit" name="scriptLineEdit"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="7" column="3" colspan="2"> + <widget class="QPushButton" name="scriptPushButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Browse...</string> + </property> + </widget> + </item> + <item row="8" column="0"> + <widget class="QCheckBox" name="zmodemCheck"> + <property name="text"> + <string>Enable Zmodem</string> + </property> + </widget> + </item> + <item row="8" column="3"> + <widget class="QCheckBox" name="buzzCheck"> + <property name="text"> + <string>Enable Buzz</string> + </property> + </widget> + </item> + <item row="8" column="2"> + <widget class="QCheckBox" name="beepCheck"> + <property name="text"> + <string>Enable Beep</string> + </property> + </widget> + </item> + <item row="5" column="0" colspan="3"> + <widget class="QCheckBox" name="autoCloseWinCheckBox"> + <property name="text"> + <string>When disconnected, close window automatically</string> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab4"> + <attribute name="title"> + <string>Mouse</string> + </attribute> + <layout class="QGridLayout"> + <item row="0" column="0"> + <widget class="QGroupBox" name="menuGroup"> + <property name="title"> + <string>Menu Type</string> + </property> + <layout class="QGridLayout"> + <item row="0" column="0"> + <widget class="QRadioButton" name="radioButton1"> + <property name="text"> + <string>Underline</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QRadioButton" name="radioButton2"> + <property name="text"> + <string>Reverse</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QRadioButton" name="radioButton3"> + <property name="text"> + <string>Custom Color</string> + </property> + </widget> + </item> + <item row="1" column="0" colspan="2"> + <widget class="QLabel" name="menuLabel"> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="text"> + <string>Menu Color</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QPushButton" name="menuColorButton"> + <property name="text"> + <string>Color...</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="2" column="0"> + <spacer> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="0"> + <widget class="QCheckBox" name="mouseCheck"> + <property name="text"> + <string>Enable Mouse Support</string> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11"/> + <tabstops> + <tabstop>tabWidget</tabstop> + <tabstop>nameLineEdit</tabstop> + <tabstop>addrLineEdit</tabstop> + <tabstop>portLineEdit</tabstop> + <tabstop>hostTypeComboBox</tabstop> + <tabstop>preloginLineEdit</tabstop> + <tabstop>userLineEdit</tabstop> + <tabstop>passwdLineEdit</tabstop> + <tabstop>postloginLineEdit</tabstop> + <tabstop>bbscodeComboBox</tabstop> + <tabstop>highlightCheckBox</tabstop> + <tabstop>termtypeLineEdit</tabstop> + <tabstop>keytypeComboBox</tabstop> + <tabstop>columnLineEdit</tabstop> + <tabstop>scrollLineEdit</tabstop> + <tabstop>rowLineEdit</tabstop> + <tabstop>cursorTypeComboBox</tabstop> + <tabstop>escapeLineEdit</tabstop> + <tabstop>idletimeLineEdit</tabstop> + <tabstop>replykeyLineEdit</tabstop> + <tabstop>replyCheckBox</tabstop> + <tabstop>replyLineEdit</tabstop> + <tabstop>reconnectCheckBox</tabstop> + <tabstop>reconnectLineEdit</tabstop> + <tabstop>retryLineEdit</tabstop> + <tabstop>autoCloseWinCheckBox</tabstop> + <tabstop>scriptCheckBox</tabstop> + <tabstop>scriptLineEdit</tabstop> + <tabstop>scriptPushButton</tabstop> + <tabstop>radioButton1</tabstop> + <tabstop>radioButton2</tabstop> + <tabstop>radioButton3</tabstop> + <tabstop>menuColorButton</tabstop> + <tabstop>applyPushButton</tabstop> + <tabstop>closePushButton</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>radioButton2</sender> + <signal>toggled(bool)</signal> + <receiver>menuColorButton</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>260</x> + <y>79</y> + </hint> + <hint type="destinationlabel"> + <x>392</x> + <y>110</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton1</sender> + <signal>toggled(bool)</signal> + <receiver>menuColorButton</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>53</x> + <y>79</y> + </hint> + <hint type="destinationlabel"> + <x>392</x> + <y>110</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton3</sender> + <signal>toggled(bool)</signal> + <receiver>menuColorButton</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>392</x> + <y>79</y> + </hint> + <hint type="destinationlabel"> + <x>392</x> + <y>110</y> + </hint> + </hints> + </connection> + <connection> + <sender>replyCheckBox</sender> + <signal>toggled(bool)</signal> + <receiver>replyLineEdit</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>23</x> + <y>158</y> + </hint> + <hint type="destinationlabel"> + <x>168</x> + <y>156</y> + </hint> + </hints> + </connection> + <connection> + <sender>reconnectCheckBox</sender> + <signal>toggled(bool)</signal> + <receiver>reconnectLineEdit</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>23</x> + <y>184</y> + </hint> + <hint type="destinationlabel"> + <x>295</x> + <y>182</y> + </hint> + </hints> + </connection> + <connection> + <sender>reconnectCheckBox</sender> + <signal>toggled(bool)</signal> + <receiver>retryLineEdit</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>23</x> + <y>184</y> + </hint> + <hint type="destinationlabel"> + <x>147</x> + <y>213</y> + </hint> + </hints> + </connection> + <connection> + <sender>scriptCheckBox</sender> + <signal>toggled(bool)</signal> + <receiver>scriptLineEdit</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>26</x> + <y>236</y> + </hint> + <hint type="destinationlabel"> + <x>26</x> + <y>261</y> + </hint> + </hints> + </connection> + <connection> + <sender>scriptCheckBox</sender> + <signal>toggled(bool)</signal> + <receiver>scriptPushButton</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>26</x> + <y>236</y> + </hint> + <hint type="destinationlabel"> + <x>289</x> + <y>260</y> + </hint> + </hints> + </connection> + <connection> + <sender>portCheckBox</sender> + <signal>toggled(bool)</signal> + <receiver>portLineEdit</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>187</x> + <y>108</y> + </hint> + <hint type="destinationlabel"> + <x>209</x> + <y>108</y> + </hint> + </hints> + </connection> + <connection> + <sender>antiIdleGroupBox</sender> + <signal>toggled(bool)</signal> + <receiver>antiLineEdit</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>89</x> + <y>42</y> + </hint> + <hint type="destinationlabel"> + <x>145</x> + <y>67</y> + </hint> + </hints> + </connection> + <connection> + <sender>antiIdleGroupBox</sender> + <signal>toggled(bool)</signal> + <receiver>idletimeLineEdit</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>114</x> + <y>40</y> + </hint> + <hint type="destinationlabel"> + <x>270</x> + <y>110</y> + </hint> + </hints> + </connection> + <connection> + <sender>beepCheck</sender> + <signal>toggled(bool)</signal> + <receiver>buzzCheck</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>223</x> + <y>301</y> + </hint> + <hint type="destinationlabel"> + <x>298</x> + <y>299</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/ui/articledialog.cpp b/src/ui/articledialog.cpp new file mode 100644 index 0000000..43ba617 --- /dev/null +++ b/src/ui/articledialog.cpp @@ -0,0 +1,105 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include "articledialog.h" +#include <QFileDialog> +#include <QMessageBox> +#include "fqterm_trace.h" +#include "fqterm_path.h" +#include "fqterm_config.h" +#include "fqterm_filedialog.h" + +/* + * Constructs a articleDialog as a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ + +namespace FQTerm { + +articleDialog::articleDialog(FQTermConfig *config, QWidget *parent, Qt::WFlags fl) + : QDialog(parent, fl) { + ui_.setupUi(this); + connectSlots(); + + config_ = config; +} + +/* + * Destroys the object and frees any allocated resources + */ +articleDialog::~articleDialog() { + // no need to delete child widgets, Qt does it all for us +} + + +void articleDialog::connectSlots() { + FQ_VERIFY(connect(ui_.selectButton, SIGNAL(clicked()), this, SLOT(onSelect()))); + FQ_VERIFY(connect(ui_.copyButton, SIGNAL(clicked()), this, SLOT(onCopy()))); + FQ_VERIFY(connect(ui_.saveButton, SIGNAL(clicked()), this, SLOT(onSave()))); + FQ_VERIFY(connect(ui_.closeButton, SIGNAL(clicked()), this, SLOT(onClose()))); +} + +void articleDialog::onSelect() { + ui_.textBrowser->selectAll(); +} + +void articleDialog::onCopy() { + ui_.textBrowser->copy(); + // QString strText = textBrowser->selectedText(); + // + // QClipboard *clipboard = QApplication::clipboard(); + // + // #if (QT_VERSION>=0x030100) + // clipboard->setText(strText, QClipboard::Selection ); + // clipboard->setText(strText, QClipboard::Clipboard ); + // #else + // clipboard->setText(strText); + // #endif +} + +void articleDialog::onSave() { + + QString filename; + FQTermFileDialog fileDialog(config_); + filename = fileDialog.getSaveName(NULL, ""); + + if (!filename.isNull()) { + QFile f(filename); + if ((f.open(QIODevice::WriteOnly))) { + f.write(articleText_.toLocal8Bit()); + f.close(); + } else { + QMessageBox mb("Access file error:", filename, QMessageBox::Warning, 0, 0, 0, + this, 0); + mb.exec(); + } + } +} + +void articleDialog::onClose() { + done(0); +} + +} // namespace FQTerm + +#include "articledialog.moc" diff --git a/src/ui/articledialog.h b/src/ui/articledialog.h new file mode 100644 index 0000000..0e40cbf --- /dev/null +++ b/src/ui/articledialog.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef FQTERM_ARTICLEDIALOG_H +#define FQTERM_ARTICLEDIALOG_H + +#include "ui_articledialog.h" + +namespace FQTerm { + +class FQTermConfig; +class FQTermFileDialog; + +class articleDialog: public QDialog { + Q_OBJECT; +public: + articleDialog(FQTermConfig *, QWidget *parent_ = 0, Qt::WFlags fl = 0); + ~articleDialog(); + + QString articleText_; + Ui::articleDialog ui_; +protected: + void connectSlots(); +protected slots: + void onClose(); + void onSave(); + void onSelect(); + void onCopy(); +private: + FQTermConfig * config_; +}; + +} // name space FQTerm + +#endif // FQTERM_ARTICLEDIALOG_H diff --git a/src/ui/articledialog.ui b/src/ui/articledialog.ui new file mode 100644 index 0000000..436671f --- /dev/null +++ b/src/ui/articledialog.ui @@ -0,0 +1,132 @@ +<ui version="4.0" > + <class>articleDialog</class> + <widget class="QDialog" name="articleDialog" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>542</width> + <height>487</height> + </rect> + </property> + <property name="windowTitle" > + <string>Article Viewer</string> + </property> + <layout class="QGridLayout" > + <item row="0" column="0" colspan="8" > + <widget class="QTextBrowser" name="textBrowser" /> + </item> + <item row="1" column="4" > + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType" > + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>50</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="2" > + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType" > + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="0" colspan="6" > + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType" > + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>410</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="6" colspan="2" > + <widget class="QPushButton" name="closeButton" > + <property name="text" > + <string>Close</string> + </property> + </widget> + </item> + <item row="1" column="1" > + <widget class="QPushButton" name="selectButton" > + <property name="text" > + <string>Select All</string> + </property> + </widget> + </item> + <item row="1" column="0" > + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType" > + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>60</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="7" > + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType" > + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>60</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="5" colspan="2" > + <widget class="QPushButton" name="saveButton" > + <property name="text" > + <string>Save...</string> + </property> + </widget> + </item> + <item row="1" column="3" > + <widget class="QPushButton" name="copyButton" > + <property name="text" > + <string>Copy</string> + </property> + </widget> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11" /> + <resources/> + <connections/> +</ui> diff --git a/src/ui/defineescape.cpp b/src/ui/defineescape.cpp new file mode 100644 index 0000000..e9dd655 --- /dev/null +++ b/src/ui/defineescape.cpp @@ -0,0 +1,51 @@ +/*************************************************************************** +* 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. * +***************************************************************************/ + +#include "defineescape.h" +#include "fqterm.h" + +namespace FQTerm { + +DefineEscapeDialog::~DefineEscapeDialog() +{ +} + +DefineEscapeDialog::DefineEscapeDialog(QString& strEsc, QWidget *parent_ /*= 0*/, Qt::WFlags fl /*= 0*/) +: QDialog(parent_, fl), strEsc_(strEsc) +{ + ui_.setupUi(this); + ui_.edtEscape->setText(strEsc_); + FQ_VERIFY(connect(ui_.btnOK, SIGNAL(clicked()), this, SLOT(onOK()))); + FQ_VERIFY(connect(ui_.btnCancel, SIGNAL(clicked()), this, SLOT(onCancel()))); +} + +void DefineEscapeDialog::onOK() +{ + strEsc_ = ui_.edtEscape->text(); + done(1); +} + +void DefineEscapeDialog::onCancel() +{ + done(0); +} +} //namespace FQTerm + +#include "defineescape.moc" diff --git a/src/ui/defineescape.h b/src/ui/defineescape.h new file mode 100644 index 0000000..0083603 --- /dev/null +++ b/src/ui/defineescape.h @@ -0,0 +1,44 @@ +/*************************************************************************** +* 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. * +***************************************************************************/ + +#ifndef __FQTERM_DEFINEESCAPE__ +#define __FQTERM_DEFINEESCAPE__ + +#include <QDialog> +#include "ui_defineescape.h" +namespace FQTerm { + +class DefineEscapeDialog : public QDialog { + Q_OBJECT; +public: + DefineEscapeDialog(QString& strEsc, QWidget *parent_ = 0, Qt::WFlags fl = 0); + ~DefineEscapeDialog(); + +protected slots: + void onOK(); + void onCancel(); +private: + QString& strEsc_; + Ui::dlgDefineEscape ui_; +}; + +} //namespace FQTerm + +#endif //__FQTERM_DEFINEESCAPE__
\ No newline at end of file diff --git a/src/ui/defineescape.ui b/src/ui/defineescape.ui new file mode 100644 index 0000000..6549610 --- /dev/null +++ b/src/ui/defineescape.ui @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>dlgDefineEscape</class>
+ <widget class="QDialog" name="dlgDefineEscape">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>213</width>
+ <height>121</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Define Escape</string>
+ </property>
+ <widget class="QLabel" name="lblEscape">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>10</y>
+ <width>81</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Escape String *[</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" name="edtEscape">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>40</y>
+ <width>171</width>
+ <height>20</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QWidget" name="">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>76</y>
+ <width>171</width>
+ <height>31</height>
+ </rect>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="btnOK">
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnCancel">
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/ui/fqterm_canvas.cpp b/src/ui/fqterm_canvas.cpp new file mode 100644 index 0000000..f17ee58 --- /dev/null +++ b/src/ui/fqterm_canvas.cpp @@ -0,0 +1,537 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include <QCloseEvent> +#include <QKeyEvent> +#include <QResizeEvent> +#include <QMouseEvent> +#include <QMenu> +#include <QMenuBar> +#include <QFileDialog> +#include <QMessageBox> +#include <QLabel> +#include <QMatrix> +#include <QToolBar> +#include <QActionGroup> +#include <QToolButton> +#include <QDesktopServices> +#include <QDir> +#include <QUrl> +#include <QImageReader> +#include <QMovie> + +#include "fqterm_canvas.h" +#include "fqterm.h" +#include "fqterm_config.h" +#include "fqterm_path.h" +#include "fqterm_filedialog.h" + +namespace FQTerm { + +FQTermCanvas::FQTermCanvas(FQTermConfig * config, QWidget *parent, Qt::WFlags f) + : QScrollArea(parent), + adjustMode_(Fit), + aspectRatioMode_(Qt::KeepAspectRatio){ + // TODO: dirty trick + + if (f == 0) { + isEmbedded = true; + } else { + isEmbedded = false; + } + + config_ = config; + + menu_ = new QMenu(parent); + menu_->addAction(tr("zoom 1:1"), this, SLOT(oriSize()), tr("Ctrl+Z")); + menu_->addAction(tr("adjust size"), this, SLOT(autoAdjust()), tr("Ctrl+X")); + menu_->addSeparator(); + QAction* zoomInAction = menu_->addAction(tr("zoom in"), this, + SLOT(zoomIn()), tr("Ctrl+=")); + QAction* zoomOutAction = menu_->addAction(tr("zoom out"), this, + SLOT(zoomOut()), tr("Ctrl+-")); + if (!isEmbedded) { + menu_->addAction(tr("fullscreen"), this, SLOT(fullScreen()), tr("Ctrl+F")); + } + menu_->addSeparator(); + menu_->addAction(tr("rotate CW 90"), this, SLOT(cwRotate()), + tr("Ctrl+]")); + menu_->addAction(tr("rotate CCW 90"), this, SLOT(ccwRotate()), + tr("Ctrl+[")); + menu_->addSeparator(); + gifPlayAction_ = menu_->addAction(tr("play gif"), this, + SLOT(playGIF()), tr("Ctrl+/")); + menu_->addSeparator(); + menu_->addAction(tr("save as"), this, SLOT(saveImage()), tr("Ctrl+S")); + menu_->addAction(tr("copy to"), this, SLOT(copyImage()), tr("Ctrl+C")); + menu_->addAction(tr("silent copy"), this, SLOT(silentCopy()), + tr("Shift+S")); + + if (!isEmbedded) { + menu_->addAction(tr("delete"), this, SLOT(deleteImage()), tr("Ctrl+D")); + + menu_->addSeparator(); + menu_->addAction(tr("exit"), this, SLOT(close()), tr("Ctrl+Q")); + } + + toolBar_ = new QToolBar(this); + + toolBar_->addAction(QIcon(getPath(RESOURCE) + "pic/ViewerButtons/open.png"), + tr("Open Dir"), this, SLOT(openDir())); + + zoomInAction->setIcon( + QIcon(getPath(RESOURCE) + "pic/ViewerButtons/zoomin.png")); + zoomOutAction->setIcon( + QIcon(getPath(RESOURCE) + "pic/ViewerButtons/zoomout.png")); + + toolBar_->addAction(zoomInAction); + toolBar_->addAction(zoomOutAction); + + QActionGroup* gifGroup = new QActionGroup(this); + gifPlayAction_->setIcon( + QIcon(getPath(RESOURCE) + "pic/ViewerButtons/play_gif.png")); + toolBar_->addAction(gifPlayAction_); + + QActionGroup* showSettingGroup = new QActionGroup(this); + QMenu* showSettingMenu = new QMenu(this); + + QAction* showSettingFitAction = + showSettingMenu->addAction(tr("show Fit"), this, SLOT(SetAdjustMode())); + showSettingFitAction->setCheckable(true); + showSettingFitAction->setData(Fit); + showSettingGroup->addAction(showSettingFitAction); + + QAction* showSettingMaxFitAction = + showSettingMenu->addAction(tr("show MaxFit"), + this, SLOT(SetAdjustMode())); + showSettingMaxFitAction->setCheckable(true); + showSettingMaxFitAction->setData(MaxFit); + showSettingGroup->addAction(showSettingMaxFitAction); + + QAction* showSettingOriginAction = + showSettingMenu->addAction(tr("show Origin"), + this, SLOT(SetAdjustMode())); + showSettingOriginAction->setCheckable(true); + showSettingOriginAction->setData(Origin); + showSettingGroup->addAction(showSettingOriginAction); + + QAction* showSettingStrechAction = + showSettingMenu->addAction(tr("show Stretch"), + this, SLOT(SetAdjustMode())); + showSettingStrechAction->setCheckable(true); + showSettingStrechAction->setData(Stretch); + showSettingGroup->addAction(showSettingStrechAction); + + QToolButton* showSettingButton = new QToolButton(this); + QAction* dummyAction = new QAction( + QIcon(getPath(RESOURCE) + "pic/ViewerButtons/adjustsize.png"), + tr("Adjust Mode"), showSettingButton); + showSettingButton->setDefaultAction(dummyAction); + showSettingButton->setMenu(showSettingMenu); + showSettingButton->setPopupMode(QToolButton::InstantPopup); + + showSettingFitAction->setChecked(true); + + toolBar_->addWidget(showSettingButton); + + + +#if QT_VERSION >= 0x040200 + setAlignment(Qt::AlignCenter); +#endif + label_ = new QLabel(viewport()); + label_->setScaledContents(true); + label_->setAlignment(Qt::AlignCenter); + label_->setText(tr("No Preview Available")); + setWidget(label_); + // resize(200, 100); +} + +FQTermCanvas::~FQTermCanvas() { + //delete label; + //delete m_pMenu; +} + +void FQTermCanvas::oriSize() { + useAdjustMode_ = false; + imageSize_ = image_.size(); + adjustSize(size()); +} + +void FQTermCanvas::zoomIn() { + useAdjustMode_ = false; + resizeImage(0.05f); +} + +void FQTermCanvas::zoomOut() { + useAdjustMode_ = false; + resizeImage(-0.05f); +} + +void FQTermCanvas::autoAdjust() { + useAdjustMode_ = true; + adjustSize(size()); +} + +void FQTermCanvas::cwRotate() { + rotateImage(90); +} + +void FQTermCanvas::ccwRotate() { + rotateImage(-90); +} + +void FQTermCanvas::fullScreen() { + if (!isFullScreen()) { + showFullScreen(); + } else { + showNormal(); + } +} + +void FQTermCanvas::loadImage(const QString& name, bool performAdjust) { + if (label_->movie()) { + label_->movie()->stop(); + label_->setMovie(NULL); + } + + gifPlayAction_->setEnabled(name.endsWith("gif")); + + + bool res = image_.load(name); + if (!res) { + QList<QByteArray> formats = QImageReader::supportedImageFormats(); + for (QList<QByteArray>::iterator it = formats.begin(); + !res && it != formats.end(); + ++it) { + res = image_.load(name, it->data()); + } + } + if (!image_.isNull()) { + fileName_ = QFileInfo(name).absoluteFilePath(); + setWindowTitle(QFileInfo(name).fileName()); + + useAdjustMode_ = true; + + if (!isEmbedded) { + QSize szView(image_.size()); + szView.scale(640, 480, aspectRatioMode_); + + if (szView.width() < image_.width()) { + imageSize_ = szView; + label_->resize(imageSize_); + label_->clear(); + label_->setAlignment(Qt::AlignCenter); + label_->setPixmap(scaleImage(imageSize_)); + + if (!isEmbedded) { + resize(szView *1.1); + } + } else { + imageSize_ = image_.size(); + label_->resize(imageSize_); + label_->setPixmap(QPixmap::fromImage(image_)); + if (!isEmbedded) { + resize(imageSize_ + QSize(5, 5)); + } + } + } + if (isEmbedded) { + label_->hide(); + if (performAdjust) autoAdjust(); + else label_->setPixmap(QPixmap::fromImage(image_)); + + label_->show(); + } + + } else { + FQ_TRACE("canvas", 1) << "Can't load the image: " << name; + } +} + +void FQTermCanvas::playGIF() { + if (fileName_.endsWith("gif")) { + gifPlayer_.setFileName(fileName_); + if (gifPlayer_.isValid()) { + label_->setMovie(&gifPlayer_); + gifPlayer_.stop(); + gifPlayer_.start(); + return; + } + } +} + +void FQTermCanvas::resizeImage(float ratio) { + QSize szImg = imageSize_; + szImg *= (1+ratio); + //we dont need so big + if (szImg.width() > 10000 || szImg.height() > 10000 || + szImg.width() < 1 || szImg.height() < 1) { + return ; + } + imageSize_ = szImg; + + if (!isFullScreen() && !isEmbedded) { + resize(imageSize_ *1.1); + } else { + adjustSize(size()); + } +} + +void FQTermCanvas::rotateImage(float ang) { + QMatrix wm; + + wm.rotate(ang); + + image_ = image_.transformed(wm, Qt::SmoothTransformation); + + imageSize_ = image_.size(); + + adjustSize(size()); +} + +void FQTermCanvas::copyImage() { + QFileInfo fi(fileName_); +// QString strSave = +// QFileDialog::getSaveFileName( +// this,tr("Choose a filename to save under"), +// QDir::currentPath() + fi.fileName()); + FQTermFileDialog fileDialog(config_); + QString strSave = fileDialog.getSaveName(fi.fileName(), ""); + if (strSave.isEmpty()) { + return ; + } + QFile file(fileName_); + if (file.open(QIODevice::ReadOnly)) { + QFile save(strSave); + if (save.open(QIODevice::WriteOnly)) { + QByteArray ba = file.readAll(); + QDataStream ds(&save); + ds.writeRawData(ba, ba.size()); + save.close(); + } + file.close(); + } +} + +void FQTermCanvas::silentCopy() { + // save it to $savefiledialog + QString strPath = config_->getItemValue("global", "savefiledialog"); + + QFileInfo fi(fileName_); + QString strSave = strPath + "/" + fi.fileName(); + + fi.setFile(strSave); + + // add (%d) if exist + int i = 1; + while (fi.exists()) { + strSave = QString("%1/%2(%3).%4").arg(fi.dir().path()).arg + (fi.completeBaseName()).arg(i).arg(fi.suffix()); + fi.setFile(strSave); + } + + // copy it + QFile file(fileName_); + if (file.open(QIODevice::ReadOnly)) { + QFile save(strSave); + if (save.open(QIODevice::WriteOnly)) { + QByteArray ba = file.readAll(); + QDataStream ds(&save); + ds.writeRawData(ba, ba.size()); + save.close(); + } + file.close(); + } +} + +QPixmap FQTermCanvas::scaleImage(const QSize &sz) { + return QPixmap::fromImage( + image_.scaled(sz, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); +} + +void FQTermCanvas::moveImage(float dx, float dy) { + scrollContentsBy(int(widget()->width()*dx), int(widget()->height() *dy)); +} + +void FQTermCanvas::saveImage() { + + QFileInfo fi(fileName_); + FQTermFileDialog fileDialog(config_); + QString strSave = fileDialog.getSaveName(fi.fileName(), ""); + if (strSave.isEmpty()) { + return ; + } + QString fmt = fi.suffix().toUpper(); + if (!image_.save(strSave, fmt.toLatin1())) { + QMessageBox::warning(this, tr("Failed to save file"), + tr("Cant save file, maybe format not supported")); + } +} + +void FQTermCanvas::deleteImage() { + QFile::remove(fileName_); + close(); +} + +void FQTermCanvas::closeEvent(QCloseEvent *ce) { + if (!isEmbedded) { + delete this; + } +} + +void FQTermCanvas::viewportResizeEvent(QResizeEvent *re) { + adjustSize(re->size()); +} + +void FQTermCanvas::mousePressEvent(QMouseEvent *me) { + /* remove this to avoid click by mistake + if(me->button()&LeftButton) + { + close(); + return; + } + */ + if (me->button() &Qt::RightButton) { + menu_->popup(me->globalPos()); + } +} + +void FQTermCanvas::keyPressEvent(QKeyEvent *ke) { + switch (ke->key()) { + case Qt::Key_Escape: + if (!isEmbedded) { + if (isFullScreen()) { + showNormal(); + } else { + close(); + } + } + + break; + case Qt::Key_D: + if (!isEmbedded){ + deleteImage(); + } + break; + case Qt::Key_Q: + if (!isEmbedded){ + close(); + } + break; + } +} + +void FQTermCanvas::adjustSize(QSize szView) { + szView -= QSize(2 * frameWidth(), 2 * frameWidth()); + if (label_->pixmap() == NULL && image_.isNull()) { + label_->resize(szView); + return ; + } + + QSize szImg = imageSize_; + + if (useAdjustMode_) { + szImg = image_.size(); + switch(adjustMode_) + { + case MaxFit: + szImg.scale(szView, aspectRatioMode_); + break; + case Fit: + if (szImg.width() > szView.width() || szImg.height() > szView.height() || + szImg.width() < image_.width()) { + szImg.scale(szView, aspectRatioMode_); + } + szImg = szImg.boundedTo(image_.size()); + if (szImg.width() < 1 || szImg.height() < 1) { + return; + } + break; + case Origin: + break; + case Stretch: + szImg = szView; + break; + } + } + + imageSize_ = szImg; + label_->resize(imageSize_); + label_->setPixmap(scaleImage(imageSize_)); +} + +void FQTermCanvas::resizeEvent(QResizeEvent * event) { + if (useAdjustMode_){ + autoAdjust(); + } + else adjustSize(size()); + QScrollArea::resizeEvent(event); +} + +QMenu* FQTermCanvas::menu() { + return menu_; +} + + +QToolBar* FQTermCanvas::ToolBar() { + return toolBar_; +} + +void FQTermCanvas::SetAdjustMode(AdjustMode am) { + adjustMode_ = am; + if (adjustMode_ == Stretch) { + aspectRatioMode_ = Qt::IgnoreAspectRatio; + } + else { + aspectRatioMode_ = Qt::KeepAspectRatio; + } + autoAdjust(); +} + +void FQTermCanvas::SetAdjustMode() { + SetAdjustMode(AdjustMode((((QAction*)sender())->data()).toInt())); +} + +void FQTermCanvas::openDir() { + QString poolPath = config_->getItemValue("preference", "pool"); + if (poolPath.isEmpty()) { + poolPath = getPath(USER_CONFIG) + "pool/"; + } +#ifdef WIN32 + QString path = "file:///" + poolPath; +#else + QString path = "file://" + poolPath; +#endif + QDesktopServices::openUrl(path); +} + +void FQTermCanvas::updateImage(const QString& filename) +{ + if (QFileInfo(filename).absoluteFilePath().toLower() == fileName_) { + loadImage(fileName_); + } + +} + + +} // namespace FQTerm + +#include "fqterm_canvas.moc" diff --git a/src/ui/fqterm_canvas.h b/src/ui/fqterm_canvas.h new file mode 100644 index 0000000..be15879 --- /dev/null +++ b/src/ui/fqterm_canvas.h @@ -0,0 +1,105 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef FQTERM_CANVAS_H +#define FQTERM_CANVAS_H + +#include <QScrollArea> +#include <QImage> +#include <QMovie> + +class QAction; +class QLabel; +class QMenu; +class QCloseEvent; +class QMouseEvent; +class QKeyEvent; +class QResizeEvent; +class QToolBar; +class QImage; + +namespace FQTerm { + +class FQTermConfig; +class ExifExtractor; +class FQTermFileDialog; + +class FQTermCanvas: public QScrollArea { + Q_OBJECT; + public: + FQTermCanvas(FQTermConfig *, QWidget *parent_ = NULL, Qt::WFlags f = Qt::Window); + ~FQTermCanvas(); + + enum AdjustMode{Origin, Fit, Stretch, MaxFit}; + + void updateImage(const QString& filename); + void loadImage(const QString&, bool = true); + QMenu* menu(); + QToolBar* ToolBar(); + public slots: + void oriSize(); + void zoomIn(); + void zoomOut(); + void autoAdjust(); + void fullScreen(); + void saveImage(); + void copyImage(); + void silentCopy(); + void cwRotate(); + void ccwRotate(); + void deleteImage(); + void SetAdjustMode(AdjustMode am); + void openDir(); + void playGIF(); + protected slots: + void SetAdjustMode(); + protected: + void resizeEvent (QResizeEvent * event); + void moveImage(float, float); + void resizeImage(float); + void rotateImage(float); + + void closeEvent(QCloseEvent*); + void mousePressEvent(QMouseEvent*); + void keyPressEvent(QKeyEvent *ke); + void viewportResizeEvent(QResizeEvent *re); + void adjustSize(QSize); + QPixmap scaleImage(const QSize &); + protected: + QLabel *label_; + bool useAdjustMode_; + QSize imageSize_; + QString fileName_; + QImage image_; + QMovie gifPlayer_; + QMenu *menu_; + QToolBar *toolBar_; + FQTermConfig * config_; + QAction* gifPlayAction_; + + AdjustMode adjustMode_; + Qt::AspectRatioMode aspectRatioMode_; + // TODO: Very dirty trick, I hate it + bool isEmbedded; +}; + +} // namespace FQTerm + +#endif // FQTERM_CANVAS_H diff --git a/src/ui/fqterm_time_label.cpp b/src/ui/fqterm_time_label.cpp new file mode 100644 index 0000000..1d05b0e --- /dev/null +++ b/src/ui/fqterm_time_label.cpp @@ -0,0 +1,50 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include "fqterm_time_label.h" + +#include <QLabel> +#include <QTimerEvent> +#include <QDateTime> + +namespace FQTerm { + +//constructor +FQTermTimeLabel::FQTermTimeLabel(QWidget *parent, const char *name, Qt::WFlags f) + : QLabel(parent, f) { + setAlignment(Qt::AlignHCenter); + currentTime_ = new QTime(); + currentTime_->start(); + startTimer(1000); +} + +//destructor +FQTermTimeLabel::~FQTermTimeLabel() { + delete currentTime_; +} + +//timer to display the current time +void FQTermTimeLabel::timerEvent(QTimerEvent*) { + setText(currentTime_->currentTime().toString()); +} + +} // namespace FQTerm + +#include "fqterm_time_label.moc" diff --git a/src/ui/fqterm_time_label.h b/src/ui/fqterm_time_label.h new file mode 100644 index 0000000..ac510b6 --- /dev/null +++ b/src/ui/fqterm_time_label.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef FQTERM_TIME_LABEL_H +#define FQTERM_TIME_LABEL_H + +#include <QTimerEvent> +#include <QLabel> + +class QTime; + +namespace FQTerm { + +class FQTermTimeLabel: public QLabel { + Q_OBJECT; + public: + FQTermTimeLabel(QWidget *parent, const char *name = 0, Qt::WFlags f = 0); + ~FQTermTimeLabel(); + + protected: + QTime *currentTime_; + void timerEvent(QTimerEvent*); +}; + +} // namespace FQTerm + +#endif // FQTERM_TIME_LABEL_H diff --git a/src/ui/fqterm_tool_button.cpp b/src/ui/fqterm_tool_button.cpp new file mode 100644 index 0000000..4680e6f --- /dev/null +++ b/src/ui/fqterm_tool_button.cpp @@ -0,0 +1,41 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include "fqterm_tool_button.h" +#include "fqterm_trace.h" + +namespace FQTerm { + +FQTermToolButton::FQTermToolButton(QWidget *parent_, int id, QString name) + : QToolButton(parent_) { + setObjectName(name); + this->id_ = id; + FQ_VERIFY(connect(this, SIGNAL(clicked()), this, SLOT(slotClicked()))); +} + +FQTermToolButton::~FQTermToolButton(){} + +void FQTermToolButton::slotClicked() { + emit(buttonClicked(id_)); +} + +} // namespace FQTerm + +#include "fqterm_tool_button.moc" diff --git a/src/ui/fqterm_tool_button.h b/src/ui/fqterm_tool_button.h new file mode 100644 index 0000000..56f5626 --- /dev/null +++ b/src/ui/fqterm_tool_button.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef FQTERM_TOOL_BUTTON_H +#define FQTERM_TOOL_BUTTON_H + +#include <QToolButton> + +namespace FQTerm { + +class FQTermToolButton: public QToolButton { + Q_OBJECT; + public: + FQTermToolButton(QWidget *parent_, int id, QString name = ""); + ~FQTermToolButton(); + + signals: + void buttonClicked(int); + + protected slots: + void slotClicked(); + + protected: + int id_; +}; + +} // namespace FQTerm + +#endif // FQTERM_TOOL_BUTTON_H diff --git a/src/ui/imageviewer.cpp b/src/ui/imageviewer.cpp new file mode 100644 index 0000000..296c5a8 --- /dev/null +++ b/src/ui/imageviewer.cpp @@ -0,0 +1,1749 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include <QAction> +#include <QBuffer> +#include <QCursor> +#include <QComboBox> +#include <QDateTime> +#include <QDataStream> +#include <QDir> +#include <QFile> +#include <QFileInfo> +#include <QIcon> +#include <QKeyEvent> +#include <QLineEdit> +#include <QMessageBox> +#include <QMouseEvent> +#include <QMenu> +#include <QMenuBar> +#include <QPainter> +#include <QPixmap> +#include <QPushButton> +#include <QSizeGrip> +#include <QString> +#include <QTextCodec> +#include <QTimer> +#include <QToolTip> +#include <QTransform> +#include <QTreeView> +#include <QTextEdit> +#include <QHeaderView> +#include <QImageReader> + +#include "fqterm_canvas.h" +#include "fqterm_config.h" +#include "fqterm_exif_extractor.h" +#include "fqterm_filedialog.h" +#include "fqterm_path.h" +#include "fqterm_trace.h" +#include "imageviewer.h" + + +namespace FQTerm { + + typedef enum { + V_UNKNOWN = -1, + V_ORIGINAL = 0, + V_SHADOW, + V_BESTFIT, + V_ZOOMIN, + V_ZOOMOUT, + V_ROTLEFT, + V_ROTRIGHT, + V_FULLSCREEN + } slideViewModes; + + typedef enum { + SORT_UNSORTED = -1, + SORT_LIKE, + SORT_NEW, + SORT_TRASH, + SORT_RECOVER, + SORT_TITLE + } slideSortFlags; + + + typedef enum { + STAT_UNKNOWN = -1, + STAT_LIKE, + STAT_NEW, + STAT_TRASH, + STAT_RECOVER, + STAT_TITLE, + STAT_ALL + } slideStatus; + + typedef enum { + GEN_UNKNOWN = -1, + GEN_CANCEL, + GEN_NOCHANGE, + GEN_RESHUFFLE, + GEN_NOTAG, + GEN_INTRASH, + GEN_INTRASHES, + GEN_TOSAVE, + GEN_TOSAVES, + GEN_TRASH, + GEN_TRASHES, + GEN_NOTRASH, + GEN_RECOVER, + GEN_RECOVERS, + GEN_NORECOVER, + GEN_SAVE, + GEN_SAVES, + GEN_DELETE, + GEN_DELETES, + GEN_SEARCHWRAP, + GEN_SEARCHNOMATCH + } generalStatus; + + static const char *fqloraTagStatus[] = { + "Like", + "New", + "Trash", + "Recover", + "Title" + }; + + static const char *fqloraGeneralStatus[] = { + "Canceled.", + "No changes for ", + "Reshuffled by ", + "No tags by ", + "item in the trash.", + "items in the trash.", + "item to save.", + "items to save.", + "image trashed.", + "images trashed.", + "Nothing to trash.", + "image recovered.", + "images recovered.", + "Nothing to recover.", + "image saved in ", + "images saved in ", + "image deleted.", + "images deleted.", + "Search wrapped.", + "No matches." + }; + + static const int toolBarFixedHeight = 40; + static const int statusBarFixedHeight = 18; + static const QSize sortBoxFixedSize(110, 25); + + static const QString &iconPath(const QString &fileName) { + + static QString p = ""; + + if (!fileName.isEmpty()) { + p = getPath(RESOURCE) + ICON_SOURCE + fileName; + } + + return p; + } + + const QString &isPlural(const int num, const int status) { + + static QString m = ""; + + if (num == 1) { + return (m = fqloraGeneralStatus[status]); + } else if (num > 1 && status > GEN_UNKNOWN && status < GEN_DELETES) { + return (m = fqloraGeneralStatus[status + 1]); + } + + return (m = fqloraGeneralStatus[GEN_UNKNOWN]); + } + + // get user's desktop rectangle + static const QRect &desktopSize() { + + static QRect size; + QDesktopWidget myDesktop; + return ((size = myDesktop.screenGeometry(myDesktop.primaryScreen()))); + } + + // FQTermImageFlow + FQTermImageFlow::~FQTermImageFlow() { + + delete statusBar_; + delete imageMenu_; + delete imageFlow_; + + statusBar_ = NULL; + imageMenu_ = NULL; + imageFlow_ = NULL; + } + + FQTermImageFlow::FQTermImageFlow(FQTermConfig * config, QWidget *parent, + Qt::WindowFlags wflag) : + FQTermImage(parent, wflag), + imageFlow_(new ImageFlow(this)), + imageMenu_(new ImageMenu(this)), + statusBar_(new QStatusBar(this)), + config_(config) { + + setWindowTitle(IMAGE_BROWSER_NAME); + setAutoFillBackground(true); + setBackgroundRole(QPalette::Midlight); + setFixedSize(desktopSize().width() / 1.3, desktopSize().height() / 1.9); + + FQ_VERIFY(connect(this, SIGNAL(isTrashEmpty()), this, SLOT(checkTrashState()))); + + // emblem state + FQ_VERIFY(connect(imageFlow_, SIGNAL(emblemStatus(const int)), imageMenu_, SLOT(updateEmblems(const int)))); + FQ_VERIFY(connect(imageMenu_, SIGNAL(toggleFlowStatus(const int)), imageFlow_, SLOT(toggleStatus(const int)))); + + // clear state + FQ_VERIFY(connect(imageFlow_, SIGNAL(clearStatus(const bool)), imageMenu_, SLOT(updateClear(const bool)))); + FQ_VERIFY(connect(imageMenu_, SIGNAL(clearImages()), this, SLOT(clearImages()))); + + // save state + FQ_VERIFY(connect(imageFlow_, SIGNAL(saveStatus(const bool)), imageMenu_, SLOT(updateSave(const bool)))); + FQ_VERIFY(connect(imageMenu_, SIGNAL(saveImages()), this, SLOT(saveImages()))); + + // trash state + FQ_VERIFY(connect(this, SIGNAL(trashStatus(const bool)), imageMenu_, SLOT(updateDustbin(const bool)))); + FQ_VERIFY(connect(imageMenu_, SIGNAL(recoverImages()), this, SLOT(recoverImages()))); + + // constructs a tool bar and its tool buttons + QAction *closeBrowserAct = new QAction(QIcon(iconPath("window-close.png")), tr("Close"), this); + closeBrowserAct->setShortcut(QKeySequence(Qt::Key_Q)); + FQ_VERIFY(connect(closeBrowserAct, SIGNAL(triggered()), this, SLOT(close()))); + + QAction *trashAllAct = new QAction(QIcon(iconPath("trash-empty.png")), tr("Trash All"), this); + trashAllAct->setShortcut(QKeySequence(Qt::Key_Delete)); + FQ_VERIFY(connect(trashAllAct, SIGNAL(triggered()), this, SLOT(trashAllImages()))); + + QLabel *sortLabel = new QLabel(this); + sortLabel->setMargin(5); + sortLabel->setToolTip("Reshuffle images by tags"); + sortLabel->setPixmap(QPixmap(iconPath("edit-shuffle.png"))); + + QComboBox *sortBox = new QComboBox(this); + sortBox->setFocusPolicy(Qt::ClickFocus); + sortBox->setFont(QFont("Serif", 12)); + sortBox->setFrame(false); + sortBox->setFixedSize(sortBoxFixedSize); + sortBox->insertItem(0, QIcon(iconPath("emblem-like-16x16.png")), tr("Like ")); + sortBox->insertItem(1, QIcon(iconPath("emblem-new-16x16.png")), tr("New ")); + sortBox->insertItem(2, QIcon(iconPath("emblem-trash-16x16.png")), tr("Trash ")); + sortBox->insertItem(3, QIcon(iconPath("emblem-recover-16x16.png")), tr("Recover ")); + sortBox->insertItem(4, QIcon(iconPath("emblem-title-16x16.png")), tr("Title ")); + FQ_VERIFY(connect(sortBox, SIGNAL(currentIndexChanged(int)), this, SLOT(reshuffleImages(int)))); + + QToolBar *toolBar = new QToolBar(this); + toolBar->setFixedHeight(toolBarFixedHeight); + toolBar->setIconSize(QSize(32, 32)); + toolBar->addAction(closeBrowserAct); + toolBar->addSeparator(); + toolBar->addWidget(sortLabel); + toolBar->addWidget(sortBox); + toolBar->addSeparator(); + toolBar->addAction(trashAllAct); + + // constructs a status bar to show instant messages + statusBar_->setSizeGripEnabled(false); + statusBar_->setFixedHeight(statusBarFixedHeight); + statusBar_->setFont(QFont("Serif", 10, QFont::Bold)); + FQ_VERIFY(connect(imageFlow_, SIGNAL(statusMessage(const QString &)), this, SLOT(showStatusMessage(const QString &)))); + FQ_VERIFY(connect(this, SIGNAL(statusMessage(const QString &)), this, SLOT(showStatusMessage(const QString &)))); + // constructs a horizontal layout + QVBoxLayout *vBox = new QVBoxLayout(this); + vBox->setMargin(0); + vBox->setSpacing(0); + vBox->addWidget(toolBar); + vBox->addWidget(imageFlow_); + vBox->addWidget(imageMenu_); + vBox->addWidget(statusBar_); + vBox->setEnabled(true); + setLayout(vBox); + } + + const QString &FQTermImageFlow::poolSource(void) const { + + static QString p = ""; + + p = config_->getItemValue("preference", "pool"); + + if (p.isEmpty()) { + p = getPath(USER_CONFIG) + POOL_SOURCE; + } + + return p; + } + + const QString &FQTermImageFlow::trashSource(void) const { + + static QString p = ""; + + p = poolSource() + TRASH_SOURCE; + return p; + } + + // these three functions below are kept for + // API compatibility. + void FQTermImageFlow::adjustItemSize() { + + } + + void FQTermImageFlow::scrollTo(const QString &filePath) { + + } + + void FQTermImageFlow::updateImage(const QString &filePath) { + + } + + // slots and functions + void FQTermImageFlow::loadImages(const int status) { + + int i; + int itemStatus = (status == STAT_RECOVER) ? status : STAT_UNKNOWN; + QString comment; + QFileInfoList sourceList = sortedList(poolSource()); + QFileInfoList targetList = imageFlow_->digest(STAT_ALL); + + for (i = 0; i < sourceList.count(); i++) { + + if (!targetList.contains(sourceList[i])) { + + QImage image; + + if (!image.load(sourceList[i].absoluteFilePath())) { + QFileIconProvider iconProvider; + image = iconProvider.icon(sourceList[i]).pixmap(desktopSize().height() / 6.0).toImage(); + } else { + image = image.scaled(desktopSize().width() / 6.0, desktopSize().height() / 6.0, + Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + } + + /* TODO */ + /* there should be a more flexible */ + /* method to deal with items' status */ + if (status == STAT_ALL) { + itemStatus = STAT_NEW; + } + + ImageFlowItem newItem(image, sourceList[i], comment,itemStatus); + imageFlow_->add(newItem); + } + } + } + + void FQTermImageFlow::reshuffleImages(const int status) { + + // there are images in the pool directory + QList<qint64> itemKeys = imageFlow_->sort(status); + + if (imageFlow_->reorder(itemKeys)) { + imageFlow_->setCurrentSlide(0); + emit statusMessage(tr(fqloraGeneralStatus[GEN_RESHUFFLE]) + tr(fqloraTagStatus[status])); + } else { + emit statusMessage(tr(fqloraGeneralStatus[GEN_NOCHANGE]) + tr(fqloraTagStatus[status])); + } + } + + void FQTermImageFlow::saveImages() { + + QFileInfoList toSave = imageFlow_->digest(STAT_LIKE); + + if (!toSave.isEmpty()) { + + QMessageBox box; + box.setWindowModality(Qt::NonModal); + box.setWindowTitle("Information"); + box.setIconPixmap(QPixmap(iconPath("emblem-info.png"))); + box.setTextFormat(Qt::RichText); + box.setText(QString("<b>%1</b> ").arg(toSave.count()) + isPlural(toSave.count(), GEN_TOSAVE)); + QPushButton *cancelButton = box.addButton(QMessageBox::Cancel); + QPushButton *saveAllButton = box.addButton(QMessageBox::SaveAll); + box.setDefaultButton(cancelButton); + box.exec(); + + if (box.clickedButton() == saveAllButton) { + + FQTermFileDialog fileDialog(config_); + QString savePath = + fileDialog.getExistingDirectory(tr("Save your likes under"), "*"); + + if (savePath.isEmpty()) { + emit statusMessage(tr(fqloraGeneralStatus[GEN_CANCEL])); + return; + } + + int i; + for (i = 0; i < toSave.count(); i++) { + QFile::rename(toSave[i].absoluteFilePath(), savePath + toSave[i].fileName()); + } + + imageFlow_->strip(STAT_LIKE); + emit statusMessage(QString("%1 ").arg(i) + isPlural(i, GEN_SAVE) + savePath); + } else { + emit statusMessage(tr(fqloraGeneralStatus[GEN_CANCEL])); + } + } else { + emit statusMessage(tr(fqloraGeneralStatus[GEN_NOTAG]) + tr(fqloraTagStatus[STAT_LIKE])); + } + } + + void FQTermImageFlow::checkTrashState() { + + QDir trashPath(trashSource()); + + if (trashPath.count() <= 2) { + emit trashStatus(false); + } else { + emit trashStatus(true); + } + } + + void FQTermImageFlow::clearImages() { + + int i; + QString trashPath = trashSource(); + QDir trashDir(trashPath); + QFileInfoList toRemove = imageFlow_->digest(STAT_TRASH); + + if (!trashDir.exists()) { + trashDir.mkdir(trashPath); + } + + if (!toRemove.isEmpty()) { + + for (i = 0; i < toRemove.count(); i++) { + if (QFile::exists(toRemove[i].absoluteFilePath())) { + QFile::rename(toRemove[i].absoluteFilePath(), trashPath + toRemove[i].fileName()); + } + } + + imageFlow_->strip(STAT_TRASH); + emit statusMessage(QString("%1 ").arg(i) + isPlural(i, GEN_TRASH)); + emit isTrashEmpty(); + } else { + emit statusMessage(tr(fqloraGeneralStatus[GEN_NOTAG]) + tr(fqloraTagStatus[STAT_TRASH])); + } + } + + void FQTermImageFlow::trashAllImages() { + + int i; + QString trashPath = trashSource(); + QDir trashDir(trashPath); + QFileInfoList toRemove = imageFlow_->digest(STAT_ALL); + + if (!trashDir.exists()) { + trashDir.mkdir(trashPath); + } + + if (imageFlow_->count() > 0) { + for (i = 0; i < imageFlow_->count(); i++) { + if (QFile::exists(toRemove[i].absoluteFilePath())) { + QFile::rename(toRemove[i].absoluteFilePath(), trashPath + toRemove[i].fileName()); + } + } + + imageFlow_->clear(); + emit statusMessage(QString("%1 ").arg(i) + isPlural(i, GEN_TRASH)); + emit isTrashEmpty(); + } else { + emit statusMessage(tr(fqloraGeneralStatus[GEN_NOTAG]) + tr(fqloraTagStatus[STAT_TRASH])); + } + } + + void FQTermImageFlow::recoverImages() { + + QString trashPath = trashSource(); + QDir trashDir(trashPath); + + if (!trashDir.exists()) { + trashDir.mkdir(trashPath); + } else if (trashDir.count() > 2) { + + int action = -1;; + QFileInfoList toRecover = sortedList(trashPath); + + if (!toRecover.isEmpty()) { + + QMessageBox box; + box.setWindowModality(Qt::NonModal); + box.setWindowTitle("Take action"); + box.setIconPixmap(QPixmap(iconPath("emblem-info.png"))); + box.setTextFormat(Qt::RichText); + box.setText(QString("<b>%1</b> ").arg(toRecover.count()) + isPlural(toRecover.count(), GEN_INTRASH)); + QPushButton *cancelButton = box.addButton(QMessageBox::Cancel); + QPushButton *recoverButton = box.addButton(tr("Recover"), QMessageBox::ApplyRole); + recoverButton->setIcon(QIcon(iconPath("button-recover.png"))); + QPushButton *deleteButton = box.addButton(tr("Delete"), QMessageBox::ApplyRole); + deleteButton->setIcon(QIcon(iconPath("button-delete.png"))); + box.setDefaultButton(cancelButton); + box.exec(); + + if (box.clickedButton() == cancelButton) { + emit statusMessage(tr(fqloraGeneralStatus[GEN_CANCEL])); + return; + } else if (box.clickedButton() == recoverButton) { + action = 1; + } else if (box.clickedButton() == deleteButton) { + action = 0; + } + + int i; + QFile imageFile; + QString poolPath = poolSource(); + + for (i = 0; i < toRecover.count(); i++) { + if (action == 1) { + QFile::rename(toRecover[i].absoluteFilePath(), poolPath + toRecover[i].fileName()); + } else if (action == 0) { + imageFile.setFileName(toRecover[i].absoluteFilePath()); + imageFile.remove(); + } + } + + if (action == 1) { + loadImages(STAT_RECOVER); + emit statusMessage(QString("%1 ").arg(i) + isPlural(i, GEN_RECOVER)); + } else if (action == 0) { + emit statusMessage(QString("%1 ").arg(i) + isPlural(i, GEN_DELETE)); + } + } + } else { + + emit statusMessage(tr(fqloraGeneralStatus[GEN_NORECOVER])); + } + + emit isTrashEmpty(); + } + + + void FQTermImageFlow::showStatusMessage(const QString &message) { + + if (statusBar_) { + statusBar_->showMessage(message, 3000); + } + } + + QFileInfoList FQTermImageFlow::sortedList(const QString &path) { + + QDir sortPath(path); + + if (!sortPath.exists()) { + sortPath.mkdir(path); + } + + QStringList filters; + QList<QByteArray> formats = QImageReader::supportedImageFormats(); + for (QList<QByteArray>::iterator it = formats.begin(); + it != formats.end(); + ++it) { + QString filter("*."); + filter.append(it->data()); + filters << filter; + } + sortPath.setNameFilters(filters); + + return (sortPath.entryInfoList(QDir::Files | QDir::Readable | QDir::NoSymLinks, QDir::Time)); + } + + // FQTermImageFlow events. + void FQTermImageFlow::showEvent(QShowEvent *event) { + + emit isTrashEmpty(); + + if (imageFlow_->count() <= 0) { + loadImages(STAT_UNKNOWN); + move((desktopSize().width() - width()) / 2.0, (desktopSize().height() - height()) / 2.0); + } else { + // TODO: insert new images + loadImages(STAT_ALL); + } + } + + void FQTermImageFlow::closeEvent(QCloseEvent *event) { + + hide(); + } + + class ImageMenu::Private { + public: + int emblemStatus; + bool dustbinStatus; + bool saveStatus; + bool clearStatus; + + QString tipMessage; + + QRect rectLike; + QRect rectTrash; + QRect rectNew; + QRect rectRecover; + QRect rectEmblems; + + QRect rectClear; + QRect rectSave; + QRect rectDustbin; + + QPixmap pixmapLike, pixmapLikeGray; + QPixmap pixmapTrash, pixmapTrashGray; + QPixmap pixmapNew, pixmapNewGray; + QPixmap pixmapRecover, pixmapRecoverGray; + + QPixmap pixmapClear, pixmapClearGray; + QPixmap pixmapSave, pixmapSaveGray; + QPixmap pixmapDustbin, pixmapDustbinGray; + }; + + //ImageMenu + ImageMenu::ImageMenu(QWidget *parent) + : fh(new ImageMenu::Private) { + + setAutoFillBackground(true); + setBackgroundRole(QPalette::Shadow); + setFocusPolicy(Qt::NoFocus); + setMouseTracking(true); + setFixedHeight(60); + + fh->emblemStatus = -2; + fh->dustbinStatus = false; + fh->saveStatus = false; + fh->clearStatus = false; + + fh->tipMessage = ""; + + fh->rectLike = QRect(50, 14, 32, 32); + fh->rectTrash = QRect(100, 14, 32, 32); + fh->rectNew = QRect(150, 14, 32, 32); + fh->rectRecover = QRect(200, 14, 32, 32); + fh->rectEmblems = QRect(50, 14, 232, 32); + + fh->rectClear = QRect(300, 14, 32, 32); + fh->rectSave = QRect(350, 14, 32, 32); + fh->rectDustbin = QRect(400, 14, 32, 32); + + fh->pixmapLike = QPixmap(iconPath("emblem-like.png")); + fh->pixmapLikeGray = QPixmap(iconPath("emblem-like-gray.png")); + + fh->pixmapTrash = QPixmap(iconPath("emblem-trash.png")); + fh->pixmapTrashGray = QPixmap(iconPath("emblem-trash-gray.png")); + + fh->pixmapNew = QPixmap(iconPath("emblem-new.png")); + fh->pixmapNewGray = QPixmap(iconPath("emblem-new-gray.png")); + + fh->pixmapRecover = QPixmap(iconPath("emblem-recover.png")); + fh->pixmapRecoverGray = QPixmap(iconPath("emblem-recover-gray.png")); + + fh->pixmapClear = QPixmap(iconPath("clear-state.png")); + fh->pixmapClearGray = QPixmap(iconPath("clear-state-gray.png")); + + fh->pixmapSave = QPixmap(iconPath("save-state.png")); + fh->pixmapSaveGray = QPixmap(iconPath("save-state-gray.png")); + + fh->pixmapDustbin = QPixmap(iconPath("trash-state.png")); + fh->pixmapDustbinGray = QPixmap(iconPath("trash-state-gray.png")); + } + + ImageMenu::~ImageMenu() { + + delete fh; + fh = NULL; + } + + void ImageMenu::updateEmblems(const int status) { + + if (fh->emblemStatus != status) { + update(fh->rectEmblems); + } + + fh->emblemStatus = status; + } + + void ImageMenu::updateClear(const bool hasOrNot) { + + if (fh->clearStatus != hasOrNot) { + update(fh->rectClear); + } + + fh->clearStatus = hasOrNot; + } + + void ImageMenu::updateSave(const bool hasOrNot) { + + if (fh->saveStatus != hasOrNot) { + update(fh->rectSave); + } + + fh->saveStatus = hasOrNot; + } + + void ImageMenu::updateDustbin(const bool fullOrNot) { + + if (fh->dustbinStatus != fullOrNot) { + update(fh->rectDustbin); + } + + fh->dustbinStatus = fullOrNot; + } + + void ImageMenu::paintEvent(QPaintEvent *event) { + + QPainter p(this); + + p.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing); + + if (fh->emblemStatus == STAT_LIKE) { + p.drawPixmap(fh->rectLike, fh->pixmapLike); + } else { + p.drawPixmap(fh->rectLike, fh->pixmapLikeGray); + } + + if (fh->emblemStatus == STAT_TRASH) { + p.drawPixmap(fh->rectTrash, fh->pixmapTrash); + } else { + p.drawPixmap(fh->rectTrash, fh->pixmapTrashGray); + } + + if (fh->emblemStatus == STAT_NEW) { + p.drawPixmap(fh->rectNew, fh->pixmapNew); + } else { + p.drawPixmap(fh->rectNew, fh->pixmapNewGray); + } + + if (fh->emblemStatus == STAT_RECOVER) { + p.drawPixmap(fh->rectRecover, fh->pixmapRecover); + } else { + p.drawPixmap(fh->rectRecover, fh->pixmapRecoverGray); + } + + if (fh->clearStatus == true) { + p.drawPixmap(fh->rectClear, fh->pixmapClear); + } else { + p.drawPixmap(fh->rectClear, fh->pixmapClearGray); + } + + if (fh->saveStatus == true) { + p.drawPixmap(fh->rectSave, fh->pixmapSave); + } else { + p.drawPixmap(fh->rectSave, fh->pixmapSaveGray); + } + + if (fh->dustbinStatus == true) { + p.drawPixmap(fh->rectDustbin, fh->pixmapDustbin); + } else { + p.drawPixmap(fh->rectDustbin, fh->pixmapDustbinGray); + } + + p.end(); + } + + void ImageMenu::mouseReleaseEvent(QMouseEvent *event) { + + if (event->button() == Qt::LeftButton + || event->button() == Qt::RightButton) { + + if (fh->rectLike.contains(event->pos())) { + emit toggleFlowStatus(STAT_LIKE); + } + + if (fh->rectTrash.contains(event->pos())) { + emit toggleFlowStatus(STAT_TRASH); + } + + if (fh->rectClear.contains(event->pos())) { + emit clearImages(); + } + + if (fh->rectSave.contains(event->pos())) { + emit saveImages(); + } + + if (fh->rectDustbin.contains(event->pos())) { + emit recoverImages(); + } + } + } + + // ImageFlow: this subclasses PictureFlow + class ImageFlow::Private { + public: + int emblemStatus; + int likeCount; + int clearCount; + + QList<QByteArray> itemsTitles; + QHash<QByteArray, qint64> itemsTitleKeyPairs; + QList<ImageFlowItem> items; + }; + + ImageFlow::~ImageFlow() { + + delete m; + m = NULL; + } + + // construct an emptry pictureflow. + ImageFlow::ImageFlow(QWidget *parent) + : PictureFlow(parent), m(new ImageFlow::Private) { + + // initial setup + setFocusPolicy(Qt::StrongFocus); + setZoomFactor(120); + setSlideCount(0); + m->emblemStatus = -1; + m->likeCount = 0; + m->clearCount = 0; + } + + const ImageFlowItem& ImageFlow::operator[](int index) const { + + return (m->items[index]); + } + + ImageFlowItem& ImageFlow::operator[](int index) { + + return (m->items[index]); + } + + const ImageFlowItem& ImageFlow::at(int index) const { + + return (m->items[index]); + } + + void ImageFlow::add(const ImageFlowItem &item) { + + QByteArray title = item.info().fileName().toLocal8Bit(); + + m->items.append(item); + m->itemsTitles.append(title); + m->itemsTitleKeyPairs.insert(title, item.key()); + + // set the status pixmap + int index = m->items.indexOf(item); + m->items[index].setStatus(item.status()); + + int count = m->items.count(); + setSlideCount(count); + setSlide(count - 1, item.image()); + } + + QList<QByteArray>& ImageFlow::itemsTitles() const { + + return (m->itemsTitles); + } + + void ImageFlow::clear() { + + m->items.clear(); + setSlideCount(0); + setCurrentSlide(0); + PictureFlow::clear(); + } + + int ImageFlow::count() const { + + return (m->items.count()); + } + + int ImageFlow::size() const { + + return (m->items.size()); + } + + QFileInfoList& ImageFlow::digest(const int status) { + + int i; + int count = m->items.size(); + static QFileInfoList result; + + result.clear(); + + for (i = 0; i < count; i++) { + switch (status) { + case STAT_ALL: + result.append(m->items[i].info()); + break; + default: + if (m->items[i].status() == status) { + result.append(m->items[i].info()); + } + break; + } + } + + return result; + } + + void ImageFlow::strip(const int status) { + + int i; + int count = m->items.count(); + QList<int> dirtyIndexes; + + // We cannot delete items in a loop because + // items count will change while deleting. + // A better method is to use another list + // to record 'dirty' items, and by looping this + // dirty list, we can correctly delete those + // dirty items successfully. + for (i = 0; i < count; i++) { + if (m->items[i].status() == status) { + dirtyIndexes.append(i); + } + } + + if (!dirtyIndexes.isEmpty()) { + + for (i = 0; i < dirtyIndexes.count(); i++) { + // Note: dirtyIndexes[i] - i: the actual + // position of the dirty item. + m->items.removeAt(dirtyIndexes[i] - i); + } + + dirtyIndexes.clear(); + reorder(sort(STAT_ALL)); + + for (i = 0; i < m->items.count(); i++) { + setSlide(i, m->items[i].image()); + } + + setSlideCount(i); + setCurrentSlide(0); + + switch(status) { + case STAT_LIKE: + m->likeCount = 0; + emit saveStatus(false); + emit emblemStatus(STAT_UNKNOWN); + break; + case STAT_TRASH: + m->clearCount = 0; + emit clearStatus(false); + emit emblemStatus(STAT_UNKNOWN); + break; + default: + break; + } + } + } + + QList<qint64> ImageFlow::sort(const int status) { + + int i; + int count = m->items.count(); + QList<qint64> itemKeys; + + switch (status) { + case STAT_TITLE: + qStableSort(m->itemsTitles.begin(), m->itemsTitles.end(), qLess<QByteArray>()); + for (i = 0; i < m->itemsTitles.count(); i++) { + itemKeys.append(m->itemsTitleKeyPairs.value(m->itemsTitles[i])); + } + break; + default: + for (i = 0; i < count; i++) { + if (m->items[i].status() == status) { + itemKeys.prepend(m->items[i].key()); + } else { + itemKeys.append(m->items[i].key()); + } + } + break; + } + + // this might be unnecessary here. + return itemKeys; + } + + bool ImageFlow::reorder(const QList<qint64>& itemsKey) { + + int items_count = m->items.size(); + + if (itemsKey.size() != items_count) { + + return (false); + } + + // Collect Items Key + QList<qint64> currentItemsKey; + for (int i = 0; i < items_count; i++) { + + currentItemsKey.append(m->items.at(i).key()); + } + + if (currentItemsKey == itemsKey) { + // if identical, we don't sort. + return (false); + } + + // Swap Items + for (int i=0; i < items_count; i++) { + + int index = currentItemsKey.indexOf(itemsKey.at(i)); + if (i == index) { + continue; + } + + QImage imgA = m->items[i].image(); + QImage imgB = m->items[index].image(); + + setSlide(index, imgA); + setSlide(i, imgB); + + m->items.swap(i, index); + currentItemsKey.swap(i, index); + } + + update(); + rehash(); + return(true); + } + + void ImageFlow::rehash(void) { + + int count = m->items.count(); + + if (count <= 0) { + return; + } + + int i; + + m->itemsTitles.clear(); + m->itemsTitleKeyPairs.clear(); + + qint64 k; + QByteArray b; + + for (i = 0; i < count; i++) { + k = m->items[i].key(); + b = m->items[i].info().fileName().toLocal8Bit(); + m->itemsTitles.append(b); + m->itemsTitleKeyPairs.insert(b, k); + } + } + + void ImageFlow::toggleStatus(const int status) { + + int index = currentSlide(); + int count = m->items.count(); + + if (index >= 0 && index < count) { + + setUpdatesEnabled(false); + if (m->items[index].status() != status) { + + switch (status) { + case STAT_LIKE: + m->likeCount++; + if (m->items[index].status() == STAT_TRASH) { + m->clearCount--; + } + emit saveStatus(true); + break; + case STAT_TRASH: + m->clearCount++; + if (m->items[index].status() == STAT_LIKE) { + m->likeCount--; + } + emit clearStatus(true); + break; + default: + break; + } + + m->items[index].setStatus(status); + emit statusMessage(tr("Tagged as ") + tr(fqloraTagStatus[status])); + + } else { + + switch (status) { + case STAT_LIKE: + m->likeCount--; + break; + case STAT_TRASH: + m->clearCount--; + break; + default: + break; + } + + m->items[index].setStatus(STAT_UNKNOWN); + emit statusMessage("Tag cleared"); + } + + if (m->likeCount <= 0) { + emit saveStatus(false); + } else { + emit saveStatus(true); + } + + if (m->clearCount <= 0) { + emit clearStatus(false); + } else { + emit clearStatus(true); + } + + setUpdatesEnabled(true); + } + } + + void ImageFlow::setCurrentImage(const int index) { + + int count = size(); + + if (count > 0 && index > 0 && index < count) { + + setCurrentSlide(index); + } + } + +// events + void ImageFlow::paintEvent(QPaintEvent *event) { + + PictureFlow::paintEvent(event); + + if (slideCount() < 1) { + return; + } + + QPainter p(this); + + // White Pen for File Info + p.setPen(Qt::gray); + + int cw = width() / 2; + int wh = height(); + + ImageFlowItem& item = m->items[currentSlide()]; + + // Draw File Name if it's not empty + QString title = item.info().fileName(); + if (!title.isEmpty()) { + + p.setFont(QFont(p.font().family(), p.font().pointSize() + 1, QFont::Bold)); + p.drawText(cw - (QFontMetrics(p.font()).width(title) / 2), wh - 20, title); + } + + p.end(); + + if (m->emblemStatus != item.status()) { + emit emblemStatus(item.status()); + } + + m->emblemStatus = item.status(); + } + + // ImageFlowItem + class ImageFlowItem::Private { + public: + QString filePath; + QFileInfo info; + QString comment; + QImage image; + int status; + qint64 key; + + }; + + ImageFlowItem::~ImageFlowItem() { + + delete m; + m = NULL; + } + + // constructs an empty item + ImageFlowItem::ImageFlowItem(QObject *parent) + : QObject(parent), m(new ImageFlowItem::Private) { + + m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment); + } + + ImageFlowItem::ImageFlowItem(const ImageFlowItem &item) + : QObject(item.parent()), m(new ImageFlowItem::Private) { + + operator=(item); + } + + // constructs an item with a given image + ImageFlowItem::ImageFlowItem(const QImage &image, QObject *parent) + : QObject(parent), m(new ImageFlowItem::Private) { + + m->image = image; + m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment); + } + + // constructs an image with given image and title + ImageFlowItem::ImageFlowItem(const QImage &image, const QFileInfo &info, QObject *parent) + : QObject(parent), m(new ImageFlowItem::Private) { + + m->image = image; + m->info = info; + m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment); + } + + // constructs an image with given image, title and comment + ImageFlowItem::ImageFlowItem(const QImage &image, const QFileInfo &info, const QString &comment, QObject *parent) + : QObject(parent), m(new ImageFlowItem::Private) { + + m->image = image; + m->info = info; + m->comment = comment; + m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment); + } + + // constructs an image with given image, title, type, size, time and state + ImageFlowItem::ImageFlowItem(const QImage &image, const QFileInfo &info, const QString& comment, const int status, QObject *parent) + : QObject(parent), m(new ImageFlowItem::Private) { + + m->image = image; + m->info = info; + m->comment = comment; + m->status = status; + + m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment); + } + + // funcs and slots + ImageFlowItem& ImageFlowItem::operator=(const ImageFlowItem &item) { + + m->info = item.m->info; + m->comment = item.m->comment; + m->key = item.m->key; + + if (item.m->filePath.isEmpty()) { + m->image = item.m->image; + } else { + setImage(item.m->filePath, m->key); + } + + return (*this); + } + + bool ImageFlowItem::operator==(const ImageFlowItem& item) const { + + return (item.m->key == m->key); + } + + bool ImageFlowItem::operator!=(const ImageFlowItem& item) const { + + return (item.m->key != m->key); + } + + const QString& ImageFlowItem::comment() const { + + return (m->comment); + } + + const QImage& ImageFlowItem::image() const { + + return (m->image); + } + + int ImageFlowItem::status(void) const { + + return (m->status); + } + + const QFileInfo& ImageFlowItem::info(void) const { + + return (m->info); + } + + qint64 ImageFlowItem::key() const { + + return (m->key); + } + + void ImageFlowItem::setInfo(const QFileInfo& info) { + + m->info = info; + m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment); + } + + void ImageFlowItem::setComment(const QString &comment) { + + m->comment = comment; + m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment); + } + + void ImageFlowItem::setImage(const QImage &image) { + + m->image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); + m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment); + } + + void ImageFlowItem::setImage(const QString &filePath, int size) { + + m->filePath = filePath; + m->key = size; + + QTimer::singleShot(1000, this, SLOT(loadImage())); + } + + void ImageFlowItem::setStatus(const int status) { + + m->status = status; + } + + void ImageFlowItem::loadImage() { + + int imageHeight = m->key; + + if (!m->image.load(m->filePath)) { + QFileIconProvider iconProvider; + m->image = iconProvider.icon(QFileInfo(m->filePath)).pixmap(imageHeight).toImage(); + } else { + m->image = resizeImage(m->image, imageHeight); + } + + m->filePath.clear(); + m->key = qHash(QString::number(m->image.cacheKey()) + m->info.fileName() + m->comment); + } + + QImage ImageFlowItem::resizeImage(const QImage &image, int size) { + + if (size == image.width() && size == image.height()) { + return image; + } + + double scaleWidth = size / (double)image.width(); + double scaleHeight = size / (double)image.height(); + double smaller = qMin(scaleWidth, scaleHeight); + + int w = (int) qRound(smaller * image.width()); + int h = (int) qRound(smaller * image.height()); + + return (image.scaled(w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + } + + // original viewer + void FQTermImageOrigin::onChange(const QModelIndex & index) { + + if (!model_->isDir(index)) { + + if (!isHidden()) + canvas_->hide(); + + QString exifInfo = QString::fromStdString(exifExtractor_->extractExifInfo(model_->filePath(tree_->currentIndex()).toLocal8Bit().data())); + bool resized = false; + + if (exifInfo != "") { + + if (!isExifTableShown_) { + adjustLayout(true); + isExifTableShown_ = true; + resized = true; + } + + updateExifInfo(); + } else { + + if (isExifTableShown_) { + adjustLayout(false); + isExifTableShown_ = false; + resized = true; + } + } + + QString path = QDir::toNativeSeparators(model_->filePath(index)); + + if (path.endsWith(QDir::separator())) + path.chop(1); + + canvas_->loadImage(path, !resized); + + // canvas_->autoAdjust(); + if (!isHidden()) + canvas_->show(); + } + } + + FQTermImageOrigin::~FQTermImageOrigin() { + delete menuBar_; + delete canvas_; + delete tree_; + delete model_; + } + + FQTermImageOrigin::FQTermImageOrigin(FQTermConfig * config, QWidget *parent, + Qt::WindowFlags wflag) : + FQTermImage(parent, wflag), + config_(config), + isExifTableShown_(false) { + + setWindowTitle(tr("FQTerm Image Viewer")); + ItemDelegate* itemDelegate = new ItemDelegate; + exifExtractor_ = new ExifExtractor; + exifTable_ = new ExifTable(this); + exifTable_->setTextFormat(Qt::RichText); + exifTable_->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + canvas_ = new FQTermCanvas(config, this, 0); + canvas_->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + model_ = new ImageViewerDirModel; + tree_ = new QTreeView; + + + tree_->setModel(model_); + tree_->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + adjustItemSize(); + tree_->setItemDelegate(itemDelegate); + tree_->setColumnWidth(0, 150); + tree_->setColumnWidth(1, 0); + + tree_->hideColumn(0); + + tree_->setUniformRowHeights(true); + tree_->setWordWrap(true); + //tree_->header()->setResizeMode(0, QHeaderView::Fixed); + //tree_->header()->setResizeMode(1, QHeaderView::ResizeToContents); + //tree_->header()->resizeSection(0, 150); + //tree_->header()->resizeSection(1, 1); + comboBox_ = new QComboBox(this); + comboBox_->addItem(tr("Sort by name"), QDir::Name); + comboBox_->addItem(tr("Sort by time"), QDir::Time); + comboBox_->addItem(tr("Sort by size"), QDir::Size); + comboBox_->addItem(tr("Sort by type"), QDir::Type); + + FQ_VERIFY(connect(comboBox_, SIGNAL(currentIndexChanged(int)), this, SLOT(sortFileList(int)))); + + comboBox_->setCurrentIndex(1); + + layout_ = new QGridLayout; + menuBar_ = new QMenuBar(this); + menuBar_->addMenu(canvas_->menu()); + menuBar_->resize(1,1); + + canvas_->ToolBar()->addAction( + QIcon(getPath(RESOURCE) + ICON_SOURCE + "prev.png"), tr("Previous"), + this, SLOT(previous())); + canvas_->ToolBar()->addAction( + QIcon(getPath(RESOURCE) + ICON_SOURCE + "next.png"), tr("Next"), + this, SLOT(next())); + + layout_->addWidget(tree_, 0, 0, 12, 1); + layout_->addWidget(comboBox_, 12, 0, 1, 1); + layout_->addWidget(canvas_, 0, 1, 12, 10); + // layout_->addWidget(exifTable_, 10, 1, 2, 10); + layout_->addWidget(canvas_->ToolBar(), 12, 1, 1, 10, Qt::AlignHCenter); + layout_->setColumnMinimumWidth(0, tree_->columnWidth(0) + 150); + setLayout(layout_); + + /* + FQ_VERIFY(connect(tree_, SIGNAL(clicked(const QModelIndex &)), + this, SLOT(onChange(const QModelIndex &)))); + */ + FQ_VERIFY(connect(tree_, SIGNAL(activated(const QModelIndex &)), + this, SLOT(onChange(const QModelIndex &)))); + FQ_VERIFY(connect(tree_->selectionModel(), + SIGNAL(selectionChanged(const QItemSelection&, + const QItemSelection&)), + this, SLOT(selectionChanged(const QItemSelection&, + const QItemSelection&)))); + FQ_VERIFY(connect(exifTable_, SIGNAL(showExifDetails()), + this, SLOT(showFullExifInfo()))); + } + + void FQTermImageOrigin::scrollTo(const QString& filename) { + + QString path = QFileInfo(filename).absolutePath(); + model_->refresh(); + tree_->setRootIndex(model_->index(path)); + canvas_->loadImage(filename); + + if (canvas_->isHidden() && !isHidden()) { + canvas_->show(); + } + + const QModelIndex& index = model_->index(filename); + tree_->scrollTo(index); + tree_->setCurrentIndex(index); + } + + void FQTermImageOrigin::updateImage(const QString& filename) { + + static int i = 0; + if (++i == 10) { + model_->refresh(model_->index(filename)); + i = 0; + } + canvas_->updateImage(filename); + } + + void FQTermImageOrigin::previous() { + + const QModelIndex& index = tree_->indexAbove(tree_->currentIndex()); + if (index.isValid()) { + tree_->setCurrentIndex(index); + canvas_->loadImage(QDir::toNativeSeparators(model_->filePath(index))); + } + } + + void FQTermImageOrigin::next() { + + const QModelIndex& index = tree_->indexBelow(tree_->currentIndex()); + if (index.isValid()) { + tree_->setCurrentIndex(index); + canvas_->loadImage(QDir::toNativeSeparators(model_->filePath(index))); + } + } + + void FQTermImageOrigin::adjustItemSize() { + + QFontMetrics fm(font()); + ItemDelegate::size_.setWidth(qMax(128, fm.width("WWWWWWWW.WWW"))); + ItemDelegate::size_.setHeight(fm.height() + 150); + } + + void FQTermImageOrigin::selectionChanged(const QItemSelection & selected, + const QItemSelection & deselected) { + + onChange(tree_->selectionModel()->currentIndex()); + } + + void FQTermImageOrigin::sortFileList(int index) { + + model_->setSorting(QDir::SortFlag(comboBox_->itemData(index).toInt())); + QString poolPath = config_->getItemValue("preference", "pool"); + + if (poolPath.isEmpty()) { + poolPath = getPath(USER_CONFIG) + "pool/"; + } + + tree_->setRootIndex(model_->index(poolPath)); + } + + void FQTermImageOrigin::showFullExifInfo() { + + QString exifInfo = QString::fromStdString(exifExtractor_->extractExifInfo(model_->filePath(tree_->currentIndex()).toLocal8Bit().data())); + QString comment; + + if ((*exifExtractor_)["UserComment"].length() > 8) { + + QString commentEncoding = QString::fromStdString((*exifExtractor_)["UserComment"].substr(0, 8)); + + if (commentEncoding.startsWith("UNICODE")) { + //UTF-16 + QTextCodec* c = QTextCodec::codecForName("UTF-16"); + comment = c->toUnicode((*exifExtractor_)["UserComment"].substr(8).c_str()); + } else if (commentEncoding.startsWith("JIS")) { + //JIS X 0208 + QTextCodec* c = QTextCodec::codecForName("JIS X 0208"); + comment = c->toUnicode((*exifExtractor_)["UserComment"].substr(8).c_str()); + } else { + comment = QString::fromStdString((*exifExtractor_)["UserComment"].substr(8)); + } + } + + + QTextEdit* info = new QTextEdit; + info->setText(exifInfo + tr("Comment : ") + comment + "\n"); + info->setWindowFlags(Qt::Dialog); + info->setAttribute(Qt::WA_DeleteOnClose); + info->setAttribute(Qt::WA_ShowModal); + // info->setLineWrapMode(QTextEdit::NoWrap); + info->setReadOnly(true); + QFontMetrics fm(font()); + info->resize(fm.width("Orientation : 1st row - 1st col : top - left side "), fm.height() * 20); + info->show(); + } + + void FQTermImageOrigin::adjustLayout(bool withExifTable) { + + if (withExifTable) { + + layout_->addWidget(canvas_, 0, 1, 11, 10); + layout_->addWidget(exifTable_, 11, 1, 1, 10, Qt::AlignHCenter); + if (!isHidden() && exifTable_->isHidden()) { + exifTable_->show(); + } + + layout_->addWidget(canvas_->ToolBar(), 12, 1, 1, 10, Qt::AlignHCenter); + } else { + layout_->addWidget(canvas_, 0, 1, 12, 10); + layout_->removeWidget(exifTable_); + exifTable_->hide(); + layout_->addWidget(canvas_->ToolBar(), 12, 1, 1, 10, Qt::AlignHCenter); + } + } + + void FQTermImageOrigin::updateExifInfo() { + + exifTable_->clear(); + + QString exifInfoToShow = "<table border=\"1\"><tr><td>" + + tr("Model") + " : " + QString::fromStdString((*exifExtractor_)["Model"]) + "</td><td>" + + QString::fromStdString((*exifExtractor_)["DateTime"]) + "</td><td>" + + QString::fromStdString((*exifExtractor_)["Flash"]) + "</td>" + + "</tr><tr><td>" + + tr("ExposureTime") + " : " + QString::fromStdString((*exifExtractor_)["ExposureTime"]) + "</td><td>" + + tr("FNumber") + " : " + QString::fromStdString((*exifExtractor_)["FNumber"]) + "</td><td>" + + tr("ISO") + " : " + QString::fromStdString((*exifExtractor_)["ISOSpeedRatings"]) + "</td>" + + "</tr><tr><td>" + + tr("FocalLength") + " : " + QString::fromStdString((*exifExtractor_)["FocalLength"]) + "</td><td>" + + tr("MeteringMode") + " : " + QString::fromStdString((*exifExtractor_)["MeteringMode"]) + "</td><td>" + + tr("ExposureBias") + " : " + QString::fromStdString((*exifExtractor_)["ExposureBiasValue"]) + "</td></tr></tabel>"; + + exifTable_->setText(exifInfoToShow); + if (!isHidden() && exifTable_->isHidden()) { + exifTable_->show(); + } + } + + void FQTermImageOrigin::closeEvent( QCloseEvent *clse ) { + + hide(); + clse->ignore(); + return ; + } + + ImageViewerDirModel::ImageViewerDirModel(QObject *parent /*= 0*/) + : QDirModel(parent) { + + //insertColumn(1); + QStringList nameFilterList; + QList<QByteArray> formats = QImageReader::supportedImageFormats(); + for (QList<QByteArray>::iterator it = formats.begin(); + it != formats.end(); + ++it) { + QString filter("*."); + filter.append(it->data()); + nameFilterList << filter; + } + setNameFilters(nameFilterList); + setFilter(QDir::Files); + } + + int ImageViewerDirModel::columnCount(const QModelIndex &/*parent*/) const { + + return 2; + } + + QVariant ImageViewerDirModel::headerData( + int section, Qt::Orientation orientation, int role) const { + //if (section == 0) return QVariant(); + if (role == Qt::DisplayRole) { + // if (section == 1) { + return QString(tr("Image Preview")); + //} + } + return QDirModel::headerData(section, orientation, role); + } + + QVariant ImageViewerDirModel::data(const QModelIndex &index, int role) const { + //if (index.column() == 0) return QVariant(); + if (role == Qt::DecorationRole) { + if (isDir(index)) { + return QVariant(); + } + + QString path = QDir::toNativeSeparators(filePath(index)); + if (path.endsWith(QDir::separator())) + path.chop(1); + + QPixmap pixmap; + bool res = pixmap.load(path); + if (!res) { + QList<QByteArray> formats = QImageReader::supportedImageFormats(); + for (QList<QByteArray>::iterator it = formats.begin(); + !res && it != formats.end(); + ++it) { + res = pixmap.load(path, it->data()); + } + } + + if (pixmap.height() > 128 || pixmap.width() > 128) { + return pixmap.scaled(128, 128, + Qt::KeepAspectRatio, Qt::SmoothTransformation); + } + + return pixmap; + } else if (role == Qt::DisplayRole) { + return fileName(index); + }/* + else if (role == Qt::TextAlignmentRole) { + return Qt::Qt::AlignBottom; + }*/ + return QVariant(); + } + + QSize ItemDelegate::size_; + + void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & option, + const QModelIndex & index ) const { + //if (index.column() == 0) return; + QStyleOptionViewItemV3 opt = setOptions(index, option); + + // prepare + painter->save(); + + // get the data and the rectangles + const QPixmap& pixmap + = qvariant_cast<QPixmap>(index.data(Qt::DecorationRole)); + QRect decorationRect = QRect(opt.rect.topLeft(), pixmap.size()); + decorationRect.moveTo(decorationRect.left(), decorationRect.top() + 10); + const QString& text = index.data(Qt::DisplayRole).toString(); + QFontMetrics fm(painter->font()); + QRect displayRect = QRect(decorationRect.bottomLeft(), + QSize(fm.width(text),fm.height())); + + QRect checkRect; + Qt::CheckState checkState = Qt::Unchecked; + QVariant value = index.data(Qt::CheckStateRole); + + if (value.isValid()) { + checkState = static_cast<Qt::CheckState>(value.toInt()); + checkRect = check(opt, opt.rect, value); + } + + // do the layout + + // doLayout(opt, &checkRect, &decorationRect, &displayRect, false); + + // draw the item + + drawBackground(painter, opt, index); + painter->drawPixmap(decorationRect, pixmap); + painter->drawText(displayRect, text); + + drawFocus(painter, opt, displayRect); + + // done + painter->restore(); + } + + void ExifTable::mouseReleaseEvent(QMouseEvent *pEvent) { + + if (pEvent->button() == Qt::LeftButton) { + emit(showExifDetails()); + } + } + + ExifTable::ExifTable(QWidget *parent) : QLabel(parent) { + + } + + FQTermImage::FQTermImage( QWidget * parent, Qt::WindowFlags f ) : QWidget(parent, f) { + } + +} // namespace FQTerm + +#include "imageviewer.moc" diff --git a/src/ui/imageviewer.h b/src/ui/imageviewer.h new file mode 100644 index 0000000..ba98559 --- /dev/null +++ b/src/ui/imageviewer.h @@ -0,0 +1,336 @@ + +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef IMAGE_VIERWER_H +#define IMAGE_VIERWER_H + +#include <QDesktopWidget> +#include <QDirModel> +#include <QLabel> +#include <QPainter> +#include <QPixmapCache> +#include <QScrollArea> +#include <QStatusBar> +#include <QToolButton> +#include <QToolBar> +#include <QLayout> +#include <QItemDelegate> +#include <QItemSelection> + +class QString; +class QPushButton; +class QVBoxLayout; +class QHBoxLayout; +class QMenuBar; +class QTreeView; +class QComboBox; + +#include "pictureflow.h" + +namespace FQTerm { + +#define DISP_MARGIN (10.0) // show a margin +#define PIXMAP_CACHESIZE (5120) // in KBytes +#define ZOOMIN_FACTOR (1.15) +#define ZOOMOUT_FACTOR (0.85) +#define ROTLEFT_DEG (-90.0) +#define ROTRIGHT_DEG (90.0) +#define IMG_CHUNK (16384) // in bytes + +#define IMAGE_BROWSER_NAME "FQLora [Image Companion for FQTerm]" +#define ICON_SOURCE "pic/ViewerButtons/" +#define POOL_SOURCE "pool/" +#define SHADOW_SOURCE "shadow-cache/" +#define TRASH_SOURCE ".Trash/" + +#define EMBLEM_LIKE "emblem-like.png" +#define EMBLEM_NEW "emblem-new.png" +#define EMBLEM_RECOVER "emblem-recover.png" +#define EMBLEM_TRASH "emblem-trash.png" +#define EMBLEM_TITLE "emblem-title.png" + + class FQTermConfig; + class FQTermFileDialog; + + + class FQTermImage : public QWidget { + Q_OBJECT; + public: + FQTermImage(QWidget * parent, Qt::WindowFlags f); + virtual void adjustItemSize() = 0; + virtual void scrollTo(const QString &) = 0; + virtual void updateImage(const QString &) = 0; + }; + + class ImageFlow; + class ImageMenu; + class ImageFlowItem; + + class FQTermImageFlow: public FQTermImage { + Q_OBJECT; + + public: + FQTermImageFlow(FQTermConfig *, QWidget *, Qt::WindowFlags); + ~FQTermImageFlow(); + + /* don't modify the funcs below */ + /* they are for API compatibiliy */ + void adjustItemSize(); + void scrollTo(const QString &); + void updateImage(const QString &); + /*********************************/ + + public slots: + void saveImages(void); + void clearImages(void); + void trashAllImages(void); + void recoverImages(void); + void showStatusMessage(const QString &message); + + private: + ImageFlow *imageFlow_; + ImageMenu *imageMenu_; + QStatusBar *statusBar_; + FQTermConfig *config_; + + QFileInfoList sortedList(const QString &path); + const QString& poolSource(void) const; + const QString& trashSource(void) const; + + private slots: + void loadImages(const int status); + void reshuffleImages(const int status); + void checkTrashState(void); + + signals: + void statusMessage(const QString &message); + void isTrashEmpty(void); + void trashStatus(const bool fullOrNot); + void saveStatus(const bool hasOrNot); + void clearStatus(const bool hasOrNot); + + protected: + void showEvent(QShowEvent *event); + void closeEvent(QCloseEvent *event); + }; + + class ImageMenu: public QLabel { + Q_OBJECT; + + public: + ImageMenu(QWidget *parent = 0); + ~ImageMenu(); + + public slots: + void updateEmblems(const int status); + void updateDustbin(const bool fullOrNot); + void updateSave(const bool hasOrNot); + void updateClear(const bool hasOrNot); + + signals: + void toggleFlowStatus(const int status); + void recoverImages(void); + void saveImages(void); + void clearImages(void); + + private: + class Private; + Private *fh; + + protected: + void paintEvent(QPaintEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + }; + + class ImageFlow: public PictureFlow { + Q_OBJECT; + Q_PROPERTY(QList<QByteArray> itemsTitles READ itemsTitles); + + public: + ImageFlow(QWidget *parent); + ~ImageFlow(); + + const ImageFlowItem& operator[](int index) const; + ImageFlowItem& operator[](int index); + const ImageFlowItem& at(int index) const; + + QList<QByteArray>& itemsTitles(void) const; + + QFileInfoList& digest(const int status); + void strip(const int status); + QList<qint64> sort(const int status); + bool reorder(const QList<qint64>& itemsKey); + + public slots: + void add(const ImageFlowItem &item); + void clear(void); + int count(void) const; + int size(void) const; + void rehash(void); + void toggleStatus(const int status); + void setCurrentImage(const int index); + + private: + class Private; + Private *m; + + signals: + void statusMessage(const QString &message); + void emblemStatus(const int status); + void saveStatus(const bool hasOrNot); + void clearStatus(const bool hasOrNot); + void titlesChanged(QList<QByteArray> &titles); + + protected: + void paintEvent(QPaintEvent *event); + }; + + class ImageFlowItem: public QObject { + Q_OBJECT; + + Q_PROPERTY(qint64 key READ key); + Q_PROPERTY(int status READ status WRITE setStatus); + Q_PROPERTY(QImage image READ image WRITE setImage); + Q_PROPERTY(QFileInfo info READ info WRITE setInfo); + Q_PROPERTY(QString comment READ comment WRITE setComment); + + public: + ImageFlowItem(QObject *parent = 0); + ImageFlowItem(const ImageFlowItem &item); + ImageFlowItem(const QImage &image, QObject *parent = 0); + ImageFlowItem(const QImage &image, const QFileInfo &info, QObject *parent = 0); + ImageFlowItem(const QImage &image, const QFileInfo &info, const int state, QObject *parent = 0); + ImageFlowItem(const QImage &image, const QFileInfo &info, const QString &comment, QObject *parent = 0); + ImageFlowItem(const QImage &image, const QFileInfo &info, const QString& comment, const int status, QObject *parent = 0); + ~ImageFlowItem(); + + const QFileInfo& info(void) const; + const QString& comment(void) const; + const QImage& image(void) const; + int status(void) const; + qint64 key(void) const; + + ImageFlowItem& operator=(const ImageFlowItem &item); + bool operator==(const ImageFlowItem &item) const; + bool operator!=(const ImageFlowItem &item) const; + + public slots: + void setStatus(const int status); + void setInfo(const QFileInfo &info); + void setComment(const QString &comment); + void setImage(const QImage &image); + void setImage(const QString &filePath, int size); + + private slots: + void loadImage(void); + + private: + QImage resizeImage(const QImage &image, int size); + class Private; + Private *m; + + }; + +/////////////////////////////////////////////////////// +//////// the origin image viewer ////////////////////// +/////////////////////////////////////////////////////// + + class FQTermCanvas; + class ExifExtractor; + + class ItemDelegate : public QItemDelegate { + public: + ItemDelegate() { + size_ = QSize(250,200); + } + + QSize sizeHint (const QStyleOptionViewItem & option, const QModelIndex & index) const { + //if (index.column() == 0) return QSize(1, 1); + return size_; + } + + void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const; + static QSize size_; + }; + + class ExifTable : public QLabel { + Q_OBJECT; + + public: + ExifTable(QWidget *parent); + + signals: + void showExifDetails(); + + protected: + void mouseReleaseEvent(QMouseEvent *pEvent); + }; + + class ImageViewerDirModel : public QDirModel { + public: + ImageViewerDirModel(QObject *parent = 0); + + int columnCount(const QModelIndex & = QModelIndex()) const; + QVariant headerData ( int section, Qt::Orientation orientation, int role) const; + QVariant data(const QModelIndex &index, int role) const; + }; + + + class FQTermImageOrigin: public FQTermImage { + Q_OBJECT; + + public: + FQTermImageOrigin(FQTermConfig * config, QWidget *parent, Qt::WindowFlags wflag); + ~FQTermImageOrigin(); + void scrollTo(const QString& filename); + void updateImage(const QString& filename); + + public slots: + void onChange(const QModelIndex & index); + void next(); + void previous(); + void adjustItemSize(); + void selectionChanged(const QItemSelection & selected, const QItemSelection & deselected); + void sortFileList(int index); + void showFullExifInfo(); + void adjustLayout(bool withExifTable); + void updateExifInfo(); + + protected: + void closeEvent(QCloseEvent *clse); + + private: + FQTermCanvas* canvas_; + QTreeView* tree_; + ImageViewerDirModel* model_; + QMenuBar* menuBar_; + QComboBox* comboBox_; + FQTermConfig* config_; + ExifExtractor* exifExtractor_; + ExifTable* exifTable_; + QGridLayout* layout_; + bool isExifTableShown_; + }; + + +} // namespace FQTerm + +#endif // IMAGE_VIERWER_H diff --git a/src/ui/iplookup.cpp b/src/ui/iplookup.cpp new file mode 100644 index 0000000..e84c126 --- /dev/null +++ b/src/ui/iplookup.cpp @@ -0,0 +1,56 @@ +/*************************************************************************** +* 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. * +***************************************************************************/ + +#include "iplookup.h" +#include "fqterm_ip_location.h" +#include "fqterm.h" +namespace FQTerm { + + + +IPLookupDialog::~IPLookupDialog(){ + +} + +IPLookupDialog::IPLookupDialog( QWidget *parent_ /*= 0*/, Qt::WFlags fl /*= 0*/ ) : QDialog(parent_, fl) { + ui_.setupUi(this); + FQ_VERIFY(connect(ui_.lookupPushButton, SIGNAL(clicked()), this, SLOT(onLookup()))); + FQ_VERIFY(connect(ui_.finishedPushButton, SIGNAL(clicked()), this, SLOT(onFinished()))); +} + +void IPLookupDialog::onLookup() { + QString country, city; + QString ip = ui_.ipLineEdit->text(); + FQTermIPLocation *ipLocation = FQTermIPLocation::getInstance(); + if (ipLocation == NULL) { + ui_.addressLineEdit->setText(QApplication::translate("IPLookupDialog", "IP database file does NOT exist", 0, QApplication::UnicodeUTF8)); + } else if (!ipLocation->getLocation(ip, country, city)) { + ui_.addressLineEdit->setText(QApplication::translate("IPLookupDialog", "Invalid IP", 0, QApplication::UnicodeUTF8)); + } else { + ui_.addressLineEdit->setText(country + " " + city); + } +} + +void IPLookupDialog::onFinished() { + done(0); +} +} //namespace FQTerm + +#include "iplookup.moc"
\ No newline at end of file diff --git a/src/ui/iplookup.h b/src/ui/iplookup.h new file mode 100644 index 0000000..4f38a5a --- /dev/null +++ b/src/ui/iplookup.h @@ -0,0 +1,43 @@ +/*************************************************************************** +* 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. * +***************************************************************************/ + +#ifndef __FQTERM_IPLOOKUP__ +#define __FQTERM_IPLOOKUP__ + +#include <QDialog> +#include "ui_iplookup.h" +namespace FQTerm { + +class IPLookupDialog : public QDialog { + Q_OBJECT; +public: + IPLookupDialog(QWidget *parent_ = 0, Qt::WFlags fl = 0); + ~IPLookupDialog(); + +protected slots: + void onLookup(); + void onFinished(); +private: + Ui::IPLookupDialog ui_; +}; + +} //namespace FQTerm + +#endif //__FQTERM_IPLOOKUP__
\ No newline at end of file diff --git a/src/ui/iplookup.ui b/src/ui/iplookup.ui new file mode 100644 index 0000000..507a456 --- /dev/null +++ b/src/ui/iplookup.ui @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>IPLookupDialog</class>
+ <widget class="QDialog" name="IPLookupDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>319</width>
+ <height>112</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>IP Lookup</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>IP Address</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="ipLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Physical Address</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="addressLineEdit">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="lookupPushButton">
+ <property name="text">
+ <string>Lookup</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="finishedPushButton">
+ <property name="text">
+ <string>Finished</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/ui/keydialog.cpp b/src/ui/keydialog.cpp new file mode 100644 index 0000000..2e3aadb --- /dev/null +++ b/src/ui/keydialog.cpp @@ -0,0 +1,285 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include <QFileDialog> + +#include "fqterm_config.h" +#include "fqterm_path.h" +#include "fqterm_trace.h" + +#include "keydialog.h" + +namespace FQTerm { + +/* + * Constructs a keyDialog as a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +keyDialog::keyDialog(FQTermConfig * config, QWidget *parent, Qt::WFlags fl) + : QDialog(parent, fl), + keyButtonGroup_(this), + config_(config) { + ui_.setupUi(this); + + keyButtonGroup_.addButton(ui_.radioButton1, 0); + keyButtonGroup_.addButton(ui_.radioButton2, 1); + keyButtonGroup_.addButton(ui_.radioButton3, 2); + + connectSlots(); + + loadName(); +} + +keyDialog::~keyDialog() { + // no need to delete child widgets, Qt does it all for us +} + + +void keyDialog::connectSlots() { + FQ_VERIFY(connect(ui_.nameListWidget, SIGNAL(currentRowChanged(int)), + this, SLOT(onNamechange(int)))); + FQ_VERIFY(connect(ui_.addButton, SIGNAL(clicked()), this, SLOT(onAdd()))); + FQ_VERIFY(connect(ui_.deleteButton, SIGNAL(clicked()), this, SLOT(onDelete()))); + FQ_VERIFY(connect(ui_.updateButton, SIGNAL(clicked()), this, SLOT(onUpdate()))); + FQ_VERIFY(connect(ui_.closeButton, SIGNAL(clicked()), this, SLOT(onClose()))); + FQ_VERIFY(connect(ui_.upButton, SIGNAL(clicked()), this, SLOT(onUp()))); + FQ_VERIFY(connect(ui_.downButton, SIGNAL(clicked()), this, SLOT(onDown()))); + FQ_VERIFY(connect(ui_.leftButton, SIGNAL(clicked()), this, SLOT(onLeft()))); + FQ_VERIFY(connect(ui_.rightButton, SIGNAL(clicked()), this, SLOT(onRight()))); + FQ_VERIFY(connect(ui_.enterButton, SIGNAL(clicked()), this, SLOT(onEnter()))); +// FQ_VERIFY(connect(&keyButtonGroup_, SIGNAL(buttonClicked(int)), this, SLOT(onSelect(int)))); + FQ_VERIFY(connect(ui_.scriptButton, SIGNAL(clicked()), this, SLOT(onChooseScript()))); + FQ_VERIFY(connect(ui_.programButton, SIGNAL(clicked()), this, SLOT(onProgram()))); + +} + +void keyDialog::onNamechange(int item) { + loadKey(item); +} + +void keyDialog::onAdd() { + QString strTmp = config_->getItemValue("key", "num"); + int num = strTmp.toInt(); + + strTmp.setNum(num + 1); + config_->setItemValue("key", "num", strTmp); + + QString strValue; + switch (keyButtonGroup_.checkedId()) { + case 0: + strValue = "0" + ui_.keyEdit->text(); + break; + case 1: + strValue = "1" + ui_.scriptEdit->text(); + break; + case 2: + strValue = "2" + ui_.programEdit->text(); + break; + } + strTmp = QString("key%1").arg(num); + config_->setItemValue("key", strTmp, strValue); + + strTmp = QString("name%1").arg(num); + config_->setItemValue("key", strTmp, ui_.nameEdit->text()); + + strTmp = QString("shortcut%1").arg(num); + config_->setItemValue("key", strTmp, ui_.shortcutEdit->text()); + + ui_.nameListWidget->addItem(ui_.nameEdit->text()); + ui_.nameListWidget->setCurrentRow(ui_.nameListWidget->count() -1); +} + +void keyDialog::onDelete() { + QString strTmp = config_->getItemValue("key", "num"); + int num = strTmp.toInt(); + if (num == 0) { + return ; + } + strTmp.setNum(num -1); + config_->setItemValue("key", "num", strTmp); + + int index = ui_.nameListWidget->currentRow(); + QString strItem1, strItem2; + for (int i = index; i < num -1; i++) { + strItem1 = QString("key%1").arg(i); + strItem2 = QString("key%1").arg(i + 1); + config_->setItemValue("key", strItem1, config_->getItemValue("key", strItem2)); + strItem1 = QString("name%1").arg(i); + strItem2 = QString("name%1").arg(i + 1); + config_->setItemValue("key", strItem1, config_->getItemValue("key", strItem2)); + } + + ui_.nameListWidget->takeItem(index); + ui_.nameListWidget->setCurrentRow(qMin(index, ui_.nameListWidget->count() -1)); +} + +void keyDialog::onUpdate() { + int index = ui_.nameListWidget->currentRow(); + if (index < 0) { + return ; + } + + QString strValue; + switch (keyButtonGroup_.checkedId()) { + case 0: + strValue = "0" + ui_.keyEdit->text(); + break; + case 1: + strValue = "1" + ui_.scriptEdit->text(); + break; + case 2: + strValue = "2" + ui_.programEdit->text(); + break; + } + + QString strTmp; + + strTmp = QString("key%1").arg(index); + config_->setItemValue("key", strTmp, strValue); + + strTmp = QString("name%1").arg(index); + config_->setItemValue("key", strTmp, ui_.nameEdit->text()); + + strTmp = QString("shortcut%1").arg(index); + config_->setItemValue("key", strTmp, ui_.shortcutEdit->text()); + + ui_.nameListWidget->item(index)->setText(ui_.nameEdit->text()); +} + +void keyDialog::onClose() { + config_->save(getPath(USER_CONFIG) + "fqterm.cfg"); + done(1); +} + +void keyDialog::onUp() { + ui_.keyEdit->insert("^[[A"); +} + +void keyDialog::onDown() { + ui_.keyEdit->insert("^[[B"); +} + +void keyDialog::onLeft() { + ui_.keyEdit->insert("^[[D"); +} + +void keyDialog::onRight() { + ui_.keyEdit->insert("^[[C"); +} + +void keyDialog::onEnter() { + ui_.keyEdit->insert("^M"); +} + +// void keyDialog::onSelect(int id) +// { +// switch(id) +// { +// case 0: // key +// ui.keyEdit->setEnabled(true); +// ui.scriptEdit->setEnabled(false); +// ui.scriptButton->setEnabled(false); +// ui.programEdit->setEnabled(false); +// ui.programButton->setEnabled(false); +// break; +// case 1: // script +// ui.keyEdit->setEnabled(false); +// ui.scriptEdit->setEnabled(true); +// ui.scriptButton->setEnabled(true); +// ui.programEdit->setEnabled(false); +// ui.programButton->setEnabled(false); +// break; +// case 2: // program +// ui.scriptEdit->setEnabled(false); +// ui.scriptButton->setEnabled(false); +// ui.keyEdit->setEnabled(false); +// ui.programEdit->setEnabled(true); +// ui.programButton->setEnabled(true); +// break; +// } +// } +void keyDialog::onChooseScript() { + QString script = QFileDialog::getOpenFileName( + this, "Select a script", QDir::currentPath(), "JavaScript File (*.js)"); + if (!script.isEmpty()) { + ui_.scriptEdit->setText(script); + } +} + +void keyDialog::onProgram() { + QString program = QFileDialog::getOpenFileName( + this, "Select a program", QDir::currentPath(), "*"); + if (!program.isNull()) { + ui_.programEdit->setText(program); + } +} + +void keyDialog::loadName() { + QString strTmp = config_->getItemValue("key", "num"); + int num = strTmp.toInt(); + for (int i = 0; i < num; i++) { + strTmp = QString("name%1").arg(i); + ui_.nameListWidget->addItem(config_->getItemValue("key", strTmp)); + } + if (num > 0) { + ui_.nameListWidget->setCurrentRow(0); + } else { + ui_.radioButton1->setChecked(true); + //onSelect(0); + } +} + +void keyDialog::loadKey(int n) { + QString strTmp = config_->getItemValue("key", "num"); + if (n >= strTmp.toInt()) { + return ; + } + + QString strItem; + + strItem = QString("name%1").arg(n); + ui_.nameEdit->setText(config_->getItemValue("key", strItem)); + + strItem = QString("key%1").arg(n); + strTmp = config_->getItemValue("key", strItem); + if (strTmp[0] == '0') { + ui_.keyEdit->setText(strTmp.mid(1)); + ui_.radioButton1->setChecked(true); + //onSelect(0); + } else if (strTmp[0] == '1') { + ui_.scriptEdit->setText(strTmp.mid(1)); + ui_.radioButton2->setChecked(true); + //onSelect(7); + } else if (strTmp[0] == '2') { + ui_.programEdit->setText(strTmp.mid(1)); + ui_.radioButton3->setChecked(true); + //onSelect(6); + } + strItem = QString("shortcut%1").arg(n); + strTmp = config_->getItemValue("key", strItem); + ui_.shortcutEdit->setText(strTmp); +} + +} // namespace FQTerm + +#include "keydialog.moc" diff --git a/src/ui/keydialog.h b/src/ui/keydialog.h new file mode 100644 index 0000000..fa087c3 --- /dev/null +++ b/src/ui/keydialog.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef FQTERM_KEY_DIALOG_H +#define FQTERM_KEY_DIALOG_H + +#include "ui_keydialog.h" + +namespace FQTerm { + +class FQTermConfig; + +class keyDialog: public QDialog { + Q_OBJECT; + public: + keyDialog(FQTermConfig *, QWidget *parent_ = 0, Qt::WFlags fl = 0); + ~keyDialog(); + + protected: + void connectSlots(); + void loadKey(int); + void loadName(); + + protected slots: + void onNamechange(int); + void onClose(); + void onAdd(); + void onDelete(); + void onUpdate(); + void onChooseScript(); + void onProgram(); + void onUp(); + void onDown(); + void onLeft(); + void onRight(); + void onEnter(); + // void onSelect(int); + private: + Ui::keyDialog ui_; + QButtonGroup keyButtonGroup_; + FQTermConfig * config_; +}; + +} // namespace FQTerm + +#endif // FQTERM_KEY_DIALOG_H diff --git a/src/ui/keydialog.ui b/src/ui/keydialog.ui new file mode 100644 index 0000000..34b8124 --- /dev/null +++ b/src/ui/keydialog.ui @@ -0,0 +1,665 @@ +<ui version="4.0" > + <class>keyDialog</class> + <widget class="QDialog" name="keyDialog" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>545</width> + <height>463</height> + </rect> + </property> + <property name="windowTitle" > + <string>Key Setup</string> + </property> + <layout class="QGridLayout" > + <item row="0" column="0" colspan="10" > + <layout class="QHBoxLayout" > + <item> + <widget class="QPushButton" name="addButton" > + <property name="text" > + <string>Add</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="deleteButton" > + <property name="text" > + <string>Delete</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="updateButton" > + <property name="text" > + <string>Update</string> + </property> + </widget> + </item> + <item> + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="closeButton" > + <property name="text" > + <string>Close</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="1" column="0" colspan="10" > + <widget class="QListWidget" name="nameListWidget" /> + </item> + <item row="2" column="0" > + <widget class="QLabel" name="textLabel1" > + <property name="text" > + <string>Name</string> + </property> + </widget> + </item> + <item row="2" column="3" colspan="4" > + <widget class="QLineEdit" name="nameEdit" /> + </item> + <item row="3" column="0" colspan="2" > + <widget class="QLabel" name="shortcutLabel" > + <property name="text" > + <string>Short Cut</string> + </property> + </widget> + </item> + <item row="3" column="3" colspan="4" > + <widget class="QLineEdit" name="shortcutEdit" /> + </item> + <item row="4" column="0" colspan="10" > + <widget class="QGroupBox" name="groupBox" > + <property name="title" > + <string>Define</string> + </property> + <layout class="QGridLayout" > + <item row="0" column="0" > + <widget class="QRadioButton" name="radioButton1" > + <property name="text" > + <string>Key</string> + </property> + </widget> + </item> + <item row="0" column="1" colspan="8" > + <widget class="QLineEdit" name="keyEdit" /> + </item> + <item row="1" column="0" colspan="3" > + <widget class="QLabel" name="textLabel3" > + <property name="text" > + <string>General Keys</string> + </property> + </widget> + </item> + <item row="1" column="3" > + <widget class="QPushButton" name="upButton" > + <property name="text" > + <string>Up</string> + </property> + </widget> + </item> + <item row="1" column="4" > + <widget class="QPushButton" name="downButton" > + <property name="text" > + <string>Down</string> + </property> + </widget> + </item> + <item row="1" column="5" > + <widget class="QPushButton" name="leftButton" > + <property name="text" > + <string>Left</string> + </property> + </widget> + </item> + <item row="1" column="6" colspan="2" > + <widget class="QPushButton" name="rightButton" > + <property name="text" > + <string>Right</string> + </property> + </widget> + </item> + <item row="1" column="8" > + <widget class="QPushButton" name="enterButton" > + <property name="text" > + <string>Enter</string> + </property> + </widget> + </item> + <item row="2" column="0" > + <widget class="QRadioButton" name="radioButton2" > + <property name="text" > + <string>Script</string> + </property> + </widget> + </item> + <item row="2" column="2" colspan="5" > + <widget class="QLineEdit" name="scriptEdit" /> + </item> + <item row="2" column="7" colspan="2" > + <widget class="QPushButton" name="scriptButton" > + <property name="text" > + <string>Browse...</string> + </property> + </widget> + </item> + <item row="3" column="0" colspan="2" > + <widget class="QRadioButton" name="radioButton3" > + <property name="text" > + <string>Program</string> + </property> + </widget> + </item> + <item row="3" column="2" colspan="5" > + <widget class="QLineEdit" name="programEdit" /> + </item> + <item row="3" column="7" colspan="2" > + <widget class="QPushButton" name="programButton" > + <property name="text" > + <string>Browse...</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11" /> + <resources/> + <connections> + <connection> + <sender>radioButton1</sender> + <signal>toggled(bool)</signal> + <receiver>keyEdit</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>69</x> + <y>230</y> + </hint> + <hint type="destinationlabel" > + <x>109</x> + <y>230</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton1</sender> + <signal>toggled(bool)</signal> + <receiver>upButton</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>66</x> + <y>230</y> + </hint> + <hint type="destinationlabel" > + <x>151</x> + <y>266</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton1</sender> + <signal>toggled(bool)</signal> + <receiver>downButton</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>20</x> + <y>237</y> + </hint> + <hint type="destinationlabel" > + <x>234</x> + <y>267</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton1</sender> + <signal>toggled(bool)</signal> + <receiver>leftButton</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>69</x> + <y>230</y> + </hint> + <hint type="destinationlabel" > + <x>299</x> + <y>263</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton1</sender> + <signal>toggled(bool)</signal> + <receiver>rightButton</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>50</x> + <y>230</y> + </hint> + <hint type="destinationlabel" > + <x>359</x> + <y>265</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton1</sender> + <signal>toggled(bool)</signal> + <receiver>enterButton</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>64</x> + <y>230</y> + </hint> + <hint type="destinationlabel" > + <x>417</x> + <y>264</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton1</sender> + <signal>toggled(bool)</signal> + <receiver>scriptEdit</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>20</x> + <y>246</y> + </hint> + <hint type="destinationlabel" > + <x>124</x> + <y>314</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton1</sender> + <signal>toggled(bool)</signal> + <receiver>scriptButton</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>41</x> + <y>230</y> + </hint> + <hint type="destinationlabel" > + <x>362</x> + <y>293</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton1</sender> + <signal>toggled(bool)</signal> + <receiver>programEdit</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>20</x> + <y>245</y> + </hint> + <hint type="destinationlabel" > + <x>111</x> + <y>354</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton1</sender> + <signal>toggled(bool)</signal> + <receiver>programButton</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>64</x> + <y>230</y> + </hint> + <hint type="destinationlabel" > + <x>409</x> + <y>343</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton2</sender> + <signal>toggled(bool)</signal> + <receiver>keyEdit</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>20</x> + <y>296</y> + </hint> + <hint type="destinationlabel" > + <x>101</x> + <y>230</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton2</sender> + <signal>toggled(bool)</signal> + <receiver>upButton</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>85</x> + <y>290</y> + </hint> + <hint type="destinationlabel" > + <x>142</x> + <y>284</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton2</sender> + <signal>toggled(bool)</signal> + <receiver>downButton</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>20</x> + <y>307</y> + </hint> + <hint type="destinationlabel" > + <x>205</x> + <y>277</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton2</sender> + <signal>toggled(bool)</signal> + <receiver>leftButton</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>21</x> + <y>290</y> + </hint> + <hint type="destinationlabel" > + <x>299</x> + <y>277</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton2</sender> + <signal>toggled(bool)</signal> + <receiver>rightButton</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>25</x> + <y>290</y> + </hint> + <hint type="destinationlabel" > + <x>359</x> + <y>284</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton2</sender> + <signal>toggled(bool)</signal> + <receiver>enterButton</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>81</x> + <y>290</y> + </hint> + <hint type="destinationlabel" > + <x>419</x> + <y>266</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton2</sender> + <signal>toggled(bool)</signal> + <receiver>scriptEdit</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>76</x> + <y>290</y> + </hint> + <hint type="destinationlabel" > + <x>119</x> + <y>290</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton2</sender> + <signal>toggled(bool)</signal> + <receiver>scriptButton</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>82</x> + <y>290</y> + </hint> + <hint type="destinationlabel" > + <x>341</x> + <y>290</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton2</sender> + <signal>toggled(bool)</signal> + <receiver>programEdit</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>20</x> + <y>294</y> + </hint> + <hint type="destinationlabel" > + <x>113</x> + <y>354</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton2</sender> + <signal>toggled(bool)</signal> + <receiver>programButton</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>83</x> + <y>305</y> + </hint> + <hint type="destinationlabel" > + <x>346</x> + <y>354</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton3</sender> + <signal>toggled(bool)</signal> + <receiver>keyEdit</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>20</x> + <y>339</y> + </hint> + <hint type="destinationlabel" > + <x>116</x> + <y>248</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton3</sender> + <signal>toggled(bool)</signal> + <receiver>upButton</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>20</x> + <y>349</y> + </hint> + <hint type="destinationlabel" > + <x>173</x> + <y>271</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton3</sender> + <signal>toggled(bool)</signal> + <receiver>downButton</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>96</x> + <y>349</y> + </hint> + <hint type="destinationlabel" > + <x>200</x> + <y>284</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton3</sender> + <signal>toggled(bool)</signal> + <receiver>leftButton</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>20</x> + <y>349</y> + </hint> + <hint type="destinationlabel" > + <x>299</x> + <y>270</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton3</sender> + <signal>toggled(bool)</signal> + <receiver>rightButton</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>20</x> + <y>349</y> + </hint> + <hint type="destinationlabel" > + <x>359</x> + <y>275</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton3</sender> + <signal>toggled(bool)</signal> + <receiver>enterButton</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>90</x> + <y>349</y> + </hint> + <hint type="destinationlabel" > + <x>419</x> + <y>277</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton3</sender> + <signal>toggled(bool)</signal> + <receiver>scriptEdit</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>77</x> + <y>349</y> + </hint> + <hint type="destinationlabel" > + <x>269</x> + <y>312</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton3</sender> + <signal>toggled(bool)</signal> + <receiver>scriptButton</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>98</x> + <y>333</y> + </hint> + <hint type="destinationlabel" > + <x>346</x> + <y>309</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton3</sender> + <signal>toggled(bool)</signal> + <receiver>programEdit</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>72</x> + <y>349</y> + </hint> + <hint type="destinationlabel" > + <x>128</x> + <y>349</y> + </hint> + </hints> + </connection> + <connection> + <sender>radioButton3</sender> + <signal>toggled(bool)</signal> + <receiver>programButton</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>73</x> + <y>335</y> + </hint> + <hint type="destinationlabel" > + <x>342</x> + <y>335</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/ui/msgdialog.cpp b/src/ui/msgdialog.cpp new file mode 100644 index 0000000..1db7495 --- /dev/null +++ b/src/ui/msgdialog.cpp @@ -0,0 +1,43 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include <stdio.h> + +#include "msgdialog.h" + +msgDialog::msgDialog(QWidget *parent, Qt::WFlags fl) + : QDialog(parent, fl) { + ui_.setupUi(this); + // signals and slots connections + //QVERIFY(connect( okButton, SIGNAL( clicked() ), this, SLOT( accept() ) )); +} + +/* + * Destroys the object and frees any allocated resources + */ +msgDialog::~msgDialog() { + // no need to delete child widgets, Qt does it all for us +} + +void msgDialog::setMessageText(const QString& message) { + ui_.msgBrowser->setPlainText(message); +} + +#include "msgdialog.moc" diff --git a/src/ui/msgdialog.h b/src/ui/msgdialog.h new file mode 100644 index 0000000..e3c5185 --- /dev/null +++ b/src/ui/msgdialog.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef FQTERM_MSGDIALOG_H +#define FQTERM_MSGDIALOG_H + +#include "ui_msgdialog.h" + +class msgDialog: public QDialog { + Q_OBJECT; +public: + msgDialog(QWidget *parent = 0, Qt::WFlags fl = 0); + ~msgDialog(); + void setMessageText(const QString& message); + Ui::msgDialog ui_; +}; + +#endif // FQTERM_MSGDIALOG_H diff --git a/src/ui/msgdialog.ui b/src/ui/msgdialog.ui new file mode 100644 index 0000000..93ff1c4 --- /dev/null +++ b/src/ui/msgdialog.ui @@ -0,0 +1,86 @@ +<ui version="4.0" > + <class>msgDialog</class> + <widget class="QDialog" name="msgDialog" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>586</width> + <height>393</height> + </rect> + </property> + <property name="windowTitle" > + <string>Messages Viewer</string> + </property> + <layout class="QGridLayout" > + <property name="margin" > + <number>9</number> + </property> + <property name="spacing" > + <number>6</number> + </property> + <item row="0" column="0" colspan="3" > + <widget class="QTextBrowser" name="msgBrowser" /> + </item> + <item row="1" column="0" > + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType" > + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="2" > + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType" > + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="1" > + <widget class="QPushButton" name="okButton" > + <property name="text" > + <string>OK</string> + </property> + </widget> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11" /> + <resources/> + <connections> + <connection> + <sender>okButton</sender> + <signal>clicked()</signal> + <receiver>msgDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel" > + <x>311</x> + <y>403</y> + </hint> + <hint type="destinationlabel" > + <x>396</x> + <y>403</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/ui/osdmessage.cpp b/src/ui/osdmessage.cpp new file mode 100644 index 0000000..1b0883f --- /dev/null +++ b/src/ui/osdmessage.cpp @@ -0,0 +1,210 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include <QPaintEvent> +#include <QCursor> +#include <QTimer> +#include <QApplication> +#include <QPainter> +#include <QBitmap> +#include <QPalette> + +#include "fqterm_trace.h" +#include "fqterm_path.h" + +#include "osdmessage.h" + +namespace FQTerm { + +PageViewMessage::PageViewMessage(QWidget *parent_) + : QWidget(parent_), + timer_(0), + message_() { + setFocusPolicy(Qt::NoFocus); + //setBackgroundMode( Qt::NoBackground ); + QPalette palette; + palette.setColor(backgroundRole(), qApp->palette().color(QPalette::Active, + QPalette::Background)); + setPalette(palette); + // setPaletteBackgroundColor(qApp->palette().color(QPalette::Active, QPalette::Background)); + setCursor(QCursor(Qt::ArrowCursor)); + move(10, 10); + resize(0, 0); + hide(); +} + +// give to Caesar what Caesar owns: code taken from Amarok's osd.h/.cpp +// "redde (reddite, pl.) cesari quae sunt cesaris", just btw. ;) +void PageViewMessage::display(const QString &message, Icon icon, int durationMs, QPoint pos, PageViewMessage::Alignment ali) +{ + displayImpl(message, icon, false, durationMs, pos, ali); +} + +void PageViewMessage::display(const QString &message, QPoint pos, Icon icon) +{ + displayImpl(message, icon, false, 4000, pos, TopLeft); +} + +QRect PageViewMessage::displayCheck(const QString &message, Icon icon) +{ + return displayImpl(message, icon, true); +} + +QRect PageViewMessage::displayImpl(const QString &message, Icon icon, bool check, int durationMs, QPoint pos, Alignment ali) +{ + //FIXME: add a option in fqterm too. + /* + if ( !KpdfSettings::showOSD() ) + { + hide(); + return; + } + */ + // determine text rectangle + + if (!isHidden() && message == message_) { + timer_->setSingleShot(true); + timer_->start(durationMs); + return QRect(QPoint(0, 0), size()); + } + message_ = message; + QRect textRect = fontMetrics().boundingRect(message); + textRect.translate(-textRect.left(), -textRect.top()); + textRect.adjust(0, 0, 2, 2); + int width = textRect.width(), height = textRect.height(), textXOffset = 0, + shadowOffset = message.isRightToLeft() ? -1: 1; + + // load icon (if set) and update geometry + // [FQTerm], we don't have a icon at this time. + + QPixmap symbol; + if (icon != None) { + switch (icon) { + //case Find: + //symbol = SmallIcon( "viewmag" ); + //break; + case Error: + symbol = QPixmap(getPath(RESOURCE) + "pic/messagebox_critical.png"); + break; + case Warning: + symbol = QPixmap(getPath(RESOURCE) + "pic/messagebox_warning.png"); + break; + default: + symbol = QPixmap(getPath(RESOURCE) + "pic/messagebox_info.png"); + break; + } + textXOffset = 2+symbol.width(); + width += textXOffset; + height = qMax(height, symbol.height()); + } + + QRect geometry(0, 0, width + 10, height + 8); + + if (check) + return geometry; + + // resize pixmap, mask and widget + static QPixmap mask; + mask = QPixmap(geometry.size()); + pixmap_ = QPixmap(geometry.size()); + resize(geometry.size()); + + switch(ali) + { + case TopLeft: + move(pos); + break; + case TopRight: + move(pos - geometry.topRight()); + break; + case BottomLeft: + move(pos - geometry.bottomLeft()); + break; + case BottomRight: + move(pos - geometry.bottomRight()); + break; + } + + // create and set transparency mask + QPainter maskPainter(&mask); + mask.fill(Qt::black); + maskPainter.setBrush(Qt::white); + maskPainter.drawRoundRect(geometry, 1600 / geometry.width(), 1600 / + geometry.height()); + setMask(mask.createHeuristicMask()); + + // draw background + QPainter bufferPainter(&pixmap_); + bufferPainter.setPen(Qt::black); + bufferPainter.setBrush(palette().brush(QPalette::Window)); + bufferPainter.drawRoundRect(geometry, 1600 / geometry.width(), 1600 / + geometry.height()); + + // draw icon if present + if (!symbol.isNull()) { + bufferPainter.drawPixmap(5, 4, symbol, 0, 0, symbol.width(), symbol.height()); + } + + // draw shadow and text + int yText = geometry.height() - height / 2; + bufferPainter.setPen(palette().color(QPalette::Window).dark(115)); + bufferPainter.drawText(5+textXOffset + shadowOffset, yText + 1, message); + bufferPainter.setPen(palette().color(QPalette::WindowText)); + bufferPainter.drawText(5+textXOffset, yText, message); + + // show widget and schedule a repaint + show(); + update(); + + // close the message window after given mS + if (durationMs > 0) { + if (!timer_) { + timer_ = new QTimer(this); + timer_->setSingleShot(true); + FQ_VERIFY(connect(timer_, SIGNAL(timeout()), SLOT(hide()))); + } + timer_->start(durationMs); + } else if (timer_) { + timer_->stop(); + } + + return QRect(QPoint(0, 0), size()); +} + +void PageViewMessage::paintEvent(QPaintEvent *e) { + QPainter p(this); + p.drawPixmap(e->rect().topLeft(), pixmap_, e->rect()); +} + +void PageViewMessage::mousePressEvent(QMouseEvent * /*e*/) { + if (timer_) { + timer_->stop(); + } + hide(); +} + +void PageViewMessage::hideEvent( QHideEvent * event ) { + emit hideAt(geometry ()); + QWidget::hideEvent(event); +} + +} // namespace FQTerm + +#include "osdmessage.moc" diff --git a/src/ui/osdmessage.h b/src/ui/osdmessage.h new file mode 100644 index 0000000..fe29d4d --- /dev/null +++ b/src/ui/osdmessage.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef FQTERM_OSD_MESSAGE_H +#define FQTERM_OSD_MESSAGE_H + +#include <QPixmap> +#include <QWidget> +#include <QHideEvent> + +namespace FQTerm { + +/** + * A widget that displays messages in the top-left corner. + */ +class PageViewMessage: public QWidget { + Q_OBJECT; + public: + PageViewMessage(QWidget *parent_); + + enum Alignment { + TopLeft, TopRight, BottomLeft, BottomRight + }; + enum Icon { + None, Info, Warning, Error, Find + }; + void display(const QString &message, Icon icon = Info, int durationMs = 4000, + QPoint pos = QPoint(10, 10), Alignment ali = TopLeft); + void display(const QString &message, QPoint pos, Icon icon = Info); + QRect displayCheck(const QString &message, Icon icon = Info); + public slots: + void showText(const QString &message){ + display(message); + } + protected: + void paintEvent(QPaintEvent *e); + void mousePressEvent(QMouseEvent *e); + QRect displayImpl(const QString &message, Icon icon = Info, + bool check = false, int durationMs = 4000, + QPoint pos = QPoint(10, 10), Alignment ali = TopLeft); + void hideEvent(QHideEvent * event); + private: + QPixmap pixmap_; + QTimer *timer_; + QString message_; +signals: + void hideAt(const QRect& rect); +}; + +} // namespace FQTerm + +#endif // FQTERM_OSD_MESSAGE_H diff --git a/src/ui/overlayWidget.cpp b/src/ui/overlayWidget.cpp new file mode 100644 index 0000000..74f0659 --- /dev/null +++ b/src/ui/overlayWidget.cpp @@ -0,0 +1,84 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include <QPoint> +#include <QFrame> +#include <QResizeEvent> +#include <QEvent> + +#include "overlayWidget.h" + +namespace FQTerm { + +OverlayWidget::OverlayWidget(QWidget *parent, QWidget *anchor) + : QFrame(parent->parentWidget()->parentWidget()), + anchor_(anchor), + parent_(parent) { + parent->installEventFilter(this); + + hide(); +} + +void OverlayWidget::reposition() { + setMaximumSize(parentWidget()->size()); + adjustSize(); + + // p is in the alignWidget's coordinates + QPoint p; + + p.setX(anchor_->width() - width()); + p.setY(-height()); + + // Position in the toplevelwidget's coordinates + QPoint pTopLevel = anchor_->mapTo(topLevelWidget(), p); + + // Position in the widget's parentWidget coordinates + QPoint pParent = parentWidget()->mapFrom(topLevelWidget(), pTopLevel); + // keep it on the screen + if (pParent.x() < 0) { + pParent.rx() = 0; + } + + // Move 'this' to that position. + move(pParent); +} + +bool OverlayWidget::eventFilter(QObject *o, QEvent *e) { + if (e->type() == QEvent::Move || e->type() == QEvent::Resize) { + reposition(); + } + + return QFrame::eventFilter(o, e); +} + +void OverlayWidget::resizeEvent(QResizeEvent *ev) { + reposition(); + QFrame::resizeEvent(ev); +} + +bool OverlayWidget::event(QEvent *e) { + if (e->type() == QEvent::ChildAdded) { + adjustSize(); + } + + return QFrame::event(e); +} + +} diff --git a/src/ui/overlayWidget.h b/src/ui/overlayWidget.h new file mode 100644 index 0000000..edab3f6 --- /dev/null +++ b/src/ui/overlayWidget.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef FQTERMOVERLAYWIDGET_H +#define FQTERMOVERLAYWIDGET_H + +#include <QFrame> +#include <QResizeEvent> +#include <QEvent> +#include <QHBoxLayout> + +namespace FQTerm { +class OverlayWidget: public QFrame { + public: + /** + * The widget is parented to the toplevelwidget of alignWidget, + * this could be an issue if that widget has an autoAdd Layout + */ + OverlayWidget(QWidget *parent, QWidget *anchor); + virtual void reposition(); + + protected: + virtual void resizeEvent(QResizeEvent*); + virtual bool eventFilter(QObject *, QEvent*); + virtual bool event(QEvent*); + + private: + QWidget *anchor_; + QWidget *parent_; +}; + +} // namespace FQTerm + +#endif // FQTERMOVERLAYWIDGET_H diff --git a/src/ui/pictureflow.cpp b/src/ui/pictureflow.cpp new file mode 100644 index 0000000..cd749f0 --- /dev/null +++ b/src/ui/pictureflow.cpp @@ -0,0 +1,1201 @@ + +/*************************************************************************** + * 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. * + ***************************************************************************/ + +/* + PictureFlow - animated image show widget + http://pictureflow.googlecode.com + + Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include "pictureflow.h" + +#include <QBasicTimer> +#include <QMouseEvent> +#include <QCache> +#include <QImage> +#include <QKeyEvent> +#include <QPainter> +#include <QPixmap> +#include <QTimer> +#include <QVector> +#include <QWidget> + +// uncomment this to enable bilinear filtering for texture mapping +// gives much better rendering, at the cost of memory space +// #define PICTUREFLOW_BILINEAR_FILTER + +// for fixed-point arithmetic, we need minimum 32-bit long +// long long (64-bit) might be useful for multiplication and division +typedef long PFreal; +#define PFREAL_SHIFT 10 +#define PFREAL_FACTOR (1 << PFREAL_SHIFT) +#define PFREAL_ONE (1 << PFREAL_SHIFT) +#define PFREAL_HALF (PFREAL_ONE >> 1) + +inline PFreal fmul(PFreal a, PFreal b) +{ + return ((long long)(a))*((long long)(b)) >> PFREAL_SHIFT; +} + +inline PFreal fdiv(PFreal num, PFreal den) +{ + long long p = (long long)(num) << (PFREAL_SHIFT*2); + long long q = p / (long long)den; + long long r = q >> PFREAL_SHIFT; + + return r; +} + +#define IANGLE_MAX 1024 +#define IANGLE_MASK 1023 + +// warning: regenerate the table if IANGLE_MAX and PFREAL_SHIFT are changed! +static const PFreal sinTable[IANGLE_MAX] = { + 3, 9, 15, 21, 28, 34, 40, 47, + 53, 59, 65, 72, 78, 84, 90, 97, + 103, 109, 115, 122, 128, 134, 140, 147, + 153, 159, 165, 171, 178, 184, 190, 196, + 202, 209, 215, 221, 227, 233, 239, 245, + 251, 257, 264, 270, 276, 282, 288, 294, + 300, 306, 312, 318, 324, 330, 336, 342, + 347, 353, 359, 365, 371, 377, 383, 388, + 394, 400, 406, 412, 417, 423, 429, 434, + 440, 446, 451, 457, 463, 468, 474, 479, + 485, 491, 496, 501, 507, 512, 518, 523, + 529, 534, 539, 545, 550, 555, 561, 566, + 571, 576, 581, 587, 592, 597, 602, 607, + 612, 617, 622, 627, 632, 637, 642, 647, + 652, 656, 661, 666, 671, 675, 680, 685, + 690, 694, 699, 703, 708, 712, 717, 721, + 726, 730, 735, 739, 743, 748, 752, 756, + 760, 765, 769, 773, 777, 781, 785, 789, + 793, 797, 801, 805, 809, 813, 816, 820, + 824, 828, 831, 835, 839, 842, 846, 849, + 853, 856, 860, 863, 866, 870, 873, 876, + 879, 883, 886, 889, 892, 895, 898, 901, + 904, 907, 910, 913, 916, 918, 921, 924, + 927, 929, 932, 934, 937, 939, 942, 944, + 947, 949, 951, 954, 956, 958, 960, 963, + 965, 967, 969, 971, 973, 975, 977, 978, + 980, 982, 984, 986, 987, 989, 990, 992, + 994, 995, 997, 998, 999, 1001, 1002, 1003, + 1004, 1006, 1007, 1008, 1009, 1010, 1011, 1012, + 1013, 1014, 1015, 1015, 1016, 1017, 1018, 1018, + 1019, 1019, 1020, 1020, 1021, 1021, 1022, 1022, + 1022, 1023, 1023, 1023, 1023, 1023, 1023, 1023, + 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1022, + 1022, 1022, 1021, 1021, 1020, 1020, 1019, 1019, + 1018, 1018, 1017, 1016, 1015, 1015, 1014, 1013, + 1012, 1011, 1010, 1009, 1008, 1007, 1006, 1004, + 1003, 1002, 1001, 999, 998, 997, 995, 994, + 992, 990, 989, 987, 986, 984, 982, 980, + 978, 977, 975, 973, 971, 969, 967, 965, + 963, 960, 958, 956, 954, 951, 949, 947, + 944, 942, 939, 937, 934, 932, 929, 927, + 924, 921, 918, 916, 913, 910, 907, 904, + 901, 898, 895, 892, 889, 886, 883, 879, + 876, 873, 870, 866, 863, 860, 856, 853, + 849, 846, 842, 839, 835, 831, 828, 824, + 820, 816, 813, 809, 805, 801, 797, 793, + 789, 785, 781, 777, 773, 769, 765, 760, + 756, 752, 748, 743, 739, 735, 730, 726, + 721, 717, 712, 708, 703, 699, 694, 690, + 685, 680, 675, 671, 666, 661, 656, 652, + 647, 642, 637, 632, 627, 622, 617, 612, + 607, 602, 597, 592, 587, 581, 576, 571, + 566, 561, 555, 550, 545, 539, 534, 529, + 523, 518, 512, 507, 501, 496, 491, 485, + 479, 474, 468, 463, 457, 451, 446, 440, + 434, 429, 423, 417, 412, 406, 400, 394, + 388, 383, 377, 371, 365, 359, 353, 347, + 342, 336, 330, 324, 318, 312, 306, 300, + 294, 288, 282, 276, 270, 264, 257, 251, + 245, 239, 233, 227, 221, 215, 209, 202, + 196, 190, 184, 178, 171, 165, 159, 153, + 147, 140, 134, 128, 122, 115, 109, 103, + 97, 90, 84, 78, 72, 65, 59, 53, + 47, 40, 34, 28, 21, 15, 9, 3, + -4, -10, -16, -22, -29, -35, -41, -48, + -54, -60, -66, -73, -79, -85, -91, -98, + -104, -110, -116, -123, -129, -135, -141, -148, + -154, -160, -166, -172, -179, -185, -191, -197, + -203, -210, -216, -222, -228, -234, -240, -246, + -252, -258, -265, -271, -277, -283, -289, -295, + -301, -307, -313, -319, -325, -331, -337, -343, + -348, -354, -360, -366, -372, -378, -384, -389, + -395, -401, -407, -413, -418, -424, -430, -435, + -441, -447, -452, -458, -464, -469, -475, -480, + -486, -492, -497, -502, -508, -513, -519, -524, + -530, -535, -540, -546, -551, -556, -562, -567, + -572, -577, -582, -588, -593, -598, -603, -608, + -613, -618, -623, -628, -633, -638, -643, -648, + -653, -657, -662, -667, -672, -676, -681, -686, + -691, -695, -700, -704, -709, -713, -718, -722, + -727, -731, -736, -740, -744, -749, -753, -757, + -761, -766, -770, -774, -778, -782, -786, -790, + -794, -798, -802, -806, -810, -814, -817, -821, + -825, -829, -832, -836, -840, -843, -847, -850, + -854, -857, -861, -864, -867, -871, -874, -877, + -880, -884, -887, -890, -893, -896, -899, -902, + -905, -908, -911, -914, -917, -919, -922, -925, + -928, -930, -933, -935, -938, -940, -943, -945, + -948, -950, -952, -955, -957, -959, -961, -964, + -966, -968, -970, -972, -974, -976, -978, -979, + -981, -983, -985, -987, -988, -990, -991, -993, + -995, -996, -998, -999, -1000, -1002, -1003, -1004, + -1005, -1007, -1008, -1009, -1010, -1011, -1012, -1013, + -1014, -1015, -1016, -1016, -1017, -1018, -1019, -1019, + -1020, -1020, -1021, -1021, -1022, -1022, -1023, -1023, + -1023, -1024, -1024, -1024, -1024, -1024, -1024, -1024, + -1024, -1024, -1024, -1024, -1024, -1024, -1024, -1023, + -1023, -1023, -1022, -1022, -1021, -1021, -1020, -1020, + -1019, -1019, -1018, -1017, -1016, -1016, -1015, -1014, + -1013, -1012, -1011, -1010, -1009, -1008, -1007, -1005, + -1004, -1003, -1002, -1000, -999, -998, -996, -995, + -993, -991, -990, -988, -987, -985, -983, -981, + -979, -978, -976, -974, -972, -970, -968, -966, + -964, -961, -959, -957, -955, -952, -950, -948, + -945, -943, -940, -938, -935, -933, -930, -928, + -925, -922, -919, -917, -914, -911, -908, -905, + -902, -899, -896, -893, -890, -887, -884, -880, + -877, -874, -871, -867, -864, -861, -857, -854, + -850, -847, -843, -840, -836, -832, -829, -825, + -821, -817, -814, -810, -806, -802, -798, -794, + -790, -786, -782, -778, -774, -770, -766, -761, + -757, -753, -749, -744, -740, -736, -731, -727, + -722, -718, -713, -709, -704, -700, -695, -691, + -686, -681, -676, -672, -667, -662, -657, -653, + -648, -643, -638, -633, -628, -623, -618, -613, + -608, -603, -598, -593, -588, -582, -577, -572, + -567, -562, -556, -551, -546, -540, -535, -530, + -524, -519, -513, -508, -502, -497, -492, -486, + -480, -475, -469, -464, -458, -452, -447, -441, + -435, -430, -424, -418, -413, -407, -401, -395, + -389, -384, -378, -372, -366, -360, -354, -348, + -343, -337, -331, -325, -319, -313, -307, -301, + -295, -289, -283, -277, -271, -265, -258, -252, + -246, -240, -234, -228, -222, -216, -210, -203, + -197, -191, -185, -179, -172, -166, -160, -154, + -148, -141, -135, -129, -123, -116, -110, -104, + -98, -91, -85, -79, -73, -66, -60, -54, + -48, -41, -35, -29, -22, -16, -10, -4 +}; + +// this is the program the generate the above table +#if 0 +#include <stdio.h> +#include <math.h> + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#define PFREAL_ONE 1024 +#define IANGLE_MAX 1024 + +int main(int, char**) +{ + FILE*f = fopen("table.c","wt"); + fprintf(f,"PFreal sinTable[] = {\n"); + for(int i = 0; i < 128; ++i) + { + for(int j = 0; j < 8; ++j) + { + int iang = j+i*8; + double ii = (double)iang + 0.5; + double angle = ii * 2 * M_PI / IANGLE_MAX; + double sinAngle = sin(angle); + fprintf(f,"%6d, ", (int)(floor(PFREAL_ONE*sinAngle))); + } + fprintf(f,"\n"); + } + fprintf(f,"};\n"); + fclose(f); + + return 0; +} +#endif + +inline PFreal fsin(int iangle) +{ + while(iangle < 0) + iangle += IANGLE_MAX; + return sinTable[iangle & IANGLE_MASK]; +} + +inline PFreal fcos(int iangle) +{ + // quarter phase shift + return fsin(iangle + (IANGLE_MAX >> 2)); +} + +namespace FQTerm { + +struct SlideInfo +{ + int slideIndex; + int angle; + PFreal cx; + PFreal cy; +}; + +class PictureFlowPrivate +{ +public: + PictureFlowPrivate(PictureFlow* widget); + + int slideCount() const; + void setSlideCount(int count); + + QSize slideSize() const; + void setSlideSize(QSize size); + + int zoomFactor() const; + void setZoomFactor(int z); + + QImage slide(int index) const; + void setSlide(int index, const QImage& image); + + int currentSlide() const; + void setCurrentSlide(int index); + + void showPrevious(); + void showNext(); + void showSlide(int index); + + void resize(int w, int h); + + void render(); + void startAnimation(); + void updateAnimation(); + + QImage buffer; + QBasicTimer animateTimer; + QVector<QRect> slidesRect; + +private: + PictureFlow* widget; + + int slideWidth; + int slideHeight; + int zoom; + + QVector<QImage> slideImages; + int centerIndex; + + SlideInfo centerSlide; + QVector<SlideInfo> leftSlides; + QVector<SlideInfo> rightSlides; + + QVector<PFreal> rays; + int itilt; + int spacing; + PFreal offsetX; + PFreal offsetY; + + QImage blankSurface; + QCache<int, QImage> surfaceCache; + QTimer triggerTimer; + + int slideFrame; + int step; + int target; + int fade; + + void recalc(int w, int h); + QRect renderSlide(const SlideInfo &slide, int alpha=256, int col1=-1, int col=-1); + QImage* surface(int slideIndex); + void triggerRender(); + void resetSlides(); +}; + +PictureFlowPrivate::PictureFlowPrivate(PictureFlow* w) +{ + widget = w; + + slideWidth = 200; + slideHeight = 200; + zoom = 100; + + centerIndex = 0; + + slideFrame = 0; + step = 0; + target = 0; + fade = 256; + + triggerTimer.setSingleShot(true); + triggerTimer.setInterval(0); + QObject::connect(&triggerTimer, SIGNAL(timeout()), widget, SLOT(render())); + + recalc(200, 200); + resetSlides(); +} + +int PictureFlowPrivate::slideCount() const +{ + return slideImages.count(); +} + +void PictureFlowPrivate::setSlideCount(int count) +{ + slideImages.resize(count); + surfaceCache.clear(); + resetSlides(); + triggerRender(); +} + +QSize PictureFlowPrivate::slideSize() const +{ + return QSize(slideWidth, slideHeight); +} + +void PictureFlowPrivate::setSlideSize(QSize size) +{ + slideWidth = size.width(); + slideHeight = size.height(); + recalc(buffer.width(), buffer.height()); + triggerRender(); +} + +int PictureFlowPrivate::zoomFactor() const +{ + return zoom; +} + +void PictureFlowPrivate::setZoomFactor(int z) +{ + if(z <= 0) + return; + + zoom = z; + recalc(buffer.width(), buffer.height()); + triggerRender(); +} + +QImage PictureFlowPrivate::slide(int index) const +{ + return slideImages[index]; +} + +void PictureFlowPrivate::setSlide(int index, const QImage& image) +{ + if((index >= 0) && (index < slideImages.count())) + { + slideImages[index] = image; + surfaceCache.remove(index); + triggerRender(); + } +} + +int PictureFlowPrivate::currentSlide() const +{ + return centerIndex; +} + +void PictureFlowPrivate::setCurrentSlide(int index) +{ + step = 0; + centerIndex = qBound(index, 0, slideImages.count()-1); + target = centerIndex; + slideFrame = index << 16; + resetSlides(); + triggerRender(); +} + +void PictureFlowPrivate::showPrevious() +{ + if(step >= 0) + { + if(centerIndex > 0) + { + target = centerIndex - 1; + startAnimation(); + } + } + else + { + target = qMax(0, centerIndex - 2); + } +} + +void PictureFlowPrivate::showNext() +{ + if(step <= 0) + { + if(centerIndex < slideImages.count()-1) + { + target = centerIndex + 1; + startAnimation(); + } + } + else + { + target = qMin(centerIndex + 2, slideImages.count()-1); + } +} + +void PictureFlowPrivate::showSlide(int index) +{ + index = qMax(index, 0); + index = qMin(slideImages.count()-1, index); + + target = index; + startAnimation(); +} + +void PictureFlowPrivate::resize(int w, int h) +{ + recalc(w, h); + resetSlides(); + triggerRender(); +} + + +// adjust slides so that they are in "steady state" position +void PictureFlowPrivate::resetSlides() +{ + centerSlide.angle = 0; + centerSlide.cx = 0; + centerSlide.cy = 0; + centerSlide.slideIndex = centerIndex; + + leftSlides.clear(); + leftSlides.resize(6); + for(int i = 0; i < leftSlides.count(); ++i) + { + SlideInfo& si = leftSlides[i]; + si.angle = itilt; + si.cx = -(offsetX + spacing*i*PFREAL_ONE); + si.cy = offsetY; + si.slideIndex = centerIndex-1-i; + } + + rightSlides.clear(); + rightSlides.resize(6); + for(int i = 0; i < rightSlides.count(); ++i) + { + SlideInfo& si = rightSlides[i]; + si.angle = -itilt; + si.cx = offsetX + spacing*i*PFREAL_ONE; + si.cy = offsetY; + si.slideIndex = centerIndex+1+i; + } +} + +#define BILINEAR_STRETCH_HOR 4 +#define BILINEAR_STRETCH_VER 4 + +static QImage scaleImage (QImage image, int w, int h) { + // I don't have to scale it + if (w == image.width() && h == image.height()) + return(image); + + QImage output(w, h, QImage::Format_ARGB32_Premultiplied); + output.fill(0); + + double scaleHeight = w / (double) image.height(); + double scaleWidth = h / (double) image.width(); + + double s = qMin(scaleWidth, scaleHeight); + + int sw = (int) qRound(s * image.width()); + int sh = (int) qRound(s * image.height()); + + // Scale Image + QImage imgScaled = image.scaled(sw, sh, Qt::KeepAspectRatio, Qt::SmoothTransformation); + + int _x = (w - sw) / 2; + int _y = (h - sh); + + for (int x = 0; x < imgScaled.width(); ++x) { + for (int y = 0; y < imgScaled.height(); ++y) { + output.setPixel(x + _x, y + _y, imgScaled.pixel(x, y)); + } + } + + return(output); +} + +static QImage prepareSurface(QImage img, int w, int h) +{ + img = scaleImage(img, w, h); + + // slightly larger, to accomodate for the reflection + int hs = h * 2; + int hofs = h / 3; + + // offscreen buffer: black is sweet + QImage result(hs, w, QImage::Format_RGB32); + result.fill(0); + + // transpose the image, this is to speed-up the rendering + // because we process one column at a time + // (and much better and faster to work row-wise, i.e in one scanline) + for(int x = 0; x < w; x++) + for(int y = 0; y < h; y++) + result.setPixel(hofs + y, x, img.pixel(x, y)); + + // create the reflection + int ht = hs - h - hofs; + int hte = ht; + for(int x = 0; x < w; x++) + for(int y = 0; y < ht; y++) + { + QRgb color = img.pixel(x, img.height()-y-1); + int a = qAlpha(color); + int r = qRed(color) * a / 256 * (hte - y) / hte * 3/5; + int g = qGreen(color) * a / 256 * (hte - y) / hte * 3/5; + int b = qBlue(color) * a / 256 * (hte - y) / hte * 3/5; + result.setPixel(h+hofs+y, x, qRgb(r, g, b)); + } + +#ifdef PICTUREFLOW_BILINEAR_FILTER + int hh = BILINEAR_STRETCH_VER*hs; + int ww = BILINEAR_STRETCH_HOR*w; + result = scaleImage(result, hh, ww); +#endif + + return result; +} + + +// get transformed image for specified slide +// if it does not exist, create it and place it in the cache +QImage* PictureFlowPrivate::surface(int slideIndex) +{ + if(slideIndex < 0) + return 0; + if(slideIndex >= slideImages.count()) + return 0; + + if(surfaceCache.contains(slideIndex)) + return surfaceCache[slideIndex]; + + QImage img = widget->slide(slideIndex); + if(img.isNull()) + { + if(blankSurface.isNull()) + { + blankSurface = QImage(slideWidth, slideHeight, QImage::Format_RGB32); + + QPainter painter(&blankSurface); + QPoint p1(slideWidth*4/10, 0); + QPoint p2(slideWidth*6/10, slideHeight); + QLinearGradient linearGrad(p1, p2); + linearGrad.setColorAt(0, Qt::black); + linearGrad.setColorAt(1, Qt::white); + painter.setBrush(linearGrad); + painter.fillRect(0, 0, slideWidth, slideHeight, QBrush(linearGrad)); + + painter.setPen(QPen(QColor(64,64,64), 4)); + painter.setBrush(QBrush()); + painter.drawRect(2, 2, slideWidth-3, slideHeight-3); + painter.end(); + blankSurface = prepareSurface(blankSurface, slideWidth, slideHeight); + } + return &blankSurface; + } + + surfaceCache.insert(slideIndex, new QImage(prepareSurface(img, slideWidth, slideHeight))); + return surfaceCache[slideIndex]; +} + + +// Schedules rendering the slides. Call this function to avoid immediate +// render and thus cause less flicker. +void PictureFlowPrivate::triggerRender() +{ + triggerTimer.start(); +} + +// Render the slides. Updates only the offscreen buffer. +void PictureFlowPrivate::render() +{ + buffer.fill(Qt::black); + + int nleft = leftSlides.count(); + int nright = rightSlides.count(); + + QRect r = renderSlide(centerSlide); + int c1 = r.left(); + int c2 = r.right(); + + if(step == 0) + { + slidesRect.clear(); + slidesRect.resize(11); + + // no animation, boring plain rendering + for(int index = 0; index < nleft-1; index++) + { + int alpha = (index < nleft-2) ? 256 : 128; + QRect rs = renderSlide(leftSlides[index], alpha, 0, c1-1); + slidesRect[index] = rs; + if(!rs.isEmpty()) + c1 = rs.left(); + } + slidesRect[5] = r; + for(int index = 0; index < nright-1; index++) + { + int alpha = (index < nright-2) ? 256 : 128; + QRect rs = renderSlide(rightSlides[index], alpha, c2+1, buffer.width()); + slidesRect[6 + index] = rs; + if(!rs.isEmpty()) + c2 = rs.right(); + } + } + else + { + // the first and last slide must fade in/fade out + for(int index = 0; index < nleft; index++) + { + int alpha = 256; + if(index == nleft-1) + alpha = (step > 0) ? 0 : 128-fade/2; + if(index == nleft-2) + alpha = (step > 0) ? 128-fade/2 : 256-fade/2; + if(index == nleft-3) + alpha = (step > 0) ? 256-fade/2 : 256; + QRect rs = renderSlide(leftSlides[index], alpha, 0, c1-1); + if(!rs.isEmpty()) + c1 = rs.left(); + } + for(int index = 0; index < nright; index++) + { + int alpha = (index < nright-2) ? 256 : 128; + if(index == nright-1) + alpha = (step > 0) ? fade/2 : 0; + if(index == nright-2) + alpha = (step > 0) ? 128+fade/2 : fade/2; + if(index == nright-3) + alpha = (step > 0) ? 256 : 128+fade/2; + QRect rs = renderSlide(rightSlides[index], alpha, c2+1, buffer.width()); + if(!rs.isEmpty()) + c2 = rs.right(); + } + } +} + +// Renders a slide to offscreen buffer. Returns a rect of the rendered area. +// alpha=256 means normal, alpha=0 is fully black, alpha=128 half transparent +// col1 and col2 limit the column for rendering. +QRect PictureFlowPrivate::renderSlide(const SlideInfo &slide, int alpha, +int col1, int col2) +{ + QImage* src = surface(slide.slideIndex); + if(!src) + return QRect(); + + QRect rect(0, 0, 0, 0); + +#ifdef PICTUREFLOW_BILINEAR_FILTER + int sw = src->height() / BILINEAR_STRETCH_HOR; + int sh = src->width() / BILINEAR_STRETCH_VER; +#else + int sw = src->height(); + int sh = src->width(); +#endif + int h = buffer.height(); + int w = buffer.width(); + + if(col1 > col2) + { + int c = col2; + col2 = col1; + col1 = c; + } + + col1 = (col1 >= 0) ? col1 : 0; + col2 = (col2 >= 0) ? col2 : w-1; + col1 = qMin(col1, w-1); + col2 = qMin(col2, w-1); + + int distance = h * 100 / zoom; + PFreal sdx = fcos(slide.angle); + PFreal sdy = fsin(slide.angle); + PFreal xs = slide.cx - slideWidth * sdx/2; + PFreal ys = slide.cy - slideWidth * sdy/2; + PFreal dist = distance * PFREAL_ONE; + + int xi = qMax((PFreal)0, ((w*PFREAL_ONE/2) + fdiv(xs*h, dist+ys)) >> PFREAL_SHIFT); + if(xi >= w) + return rect; + + bool flag = false; + rect.setLeft(xi); + + for(int x = qMax(xi, col1); x <= col2; x++) + { + PFreal hity = 0; + PFreal fk = rays[x]; + if(sdy) + { + fk = fk - fdiv(sdx,sdy); + hity = -fdiv((rays[x]*distance - slide.cx + slide.cy*sdx/sdy), fk); + } + + dist = distance*PFREAL_ONE + hity; + if(dist < 0) + continue; + + PFreal hitx = fmul(dist, rays[x]); + PFreal hitdist = fdiv(hitx - slide.cx, sdx); + +#ifdef PICTUREFLOW_BILINEAR_FILTER + int column = sw*BILINEAR_STRETCH_HOR/2 + (hitdist*BILINEAR_STRETCH_HOR >> PFREAL_SHIFT); + if(column >= sw*BILINEAR_STRETCH_HOR) + break; +#else + int column = sw/2 + (hitdist >> PFREAL_SHIFT); + if(column >= sw) + break; +#endif + if(column < 0) + continue; + + rect.setRight(x); + if(!flag) + rect.setLeft(x); + flag = true; + + int y1 = h/2; + int y2 = y1+ 1; + QRgb* pixel1 = (QRgb*)(buffer.scanLine(y1)) + x; + QRgb* pixel2 = (QRgb*)(buffer.scanLine(y2)) + x; + QRgb pixelstep = pixel2 - pixel1; + +#ifdef PICTUREFLOW_BILINEAR_FILTER + int center = (sh*BILINEAR_STRETCH_VER/2); + int dy = dist*BILINEAR_STRETCH_VER / h; +#else + int center = (sh/2); + int dy = dist / h; +#endif + int p1 = center*PFREAL_ONE - dy/2; + int p2 = center*PFREAL_ONE + dy/2; + + const QRgb *ptr = (const QRgb*)(src->scanLine(column)); + if(alpha == 256) + while((y1 >= 0) && (y2 < h) && (p1 >= 0)) + { + *pixel1 = ptr[p1 >> PFREAL_SHIFT]; + *pixel2 = ptr[p2 >> PFREAL_SHIFT]; + p1 -= dy; + p2 += dy; + y1--; + y2++; + pixel1 -= pixelstep; + pixel2 += pixelstep; + } + else + while((y1 >= 0) && (y2 < h) && (p1 >= 0)) + { + QRgb c1 = ptr[p1 >> PFREAL_SHIFT]; + QRgb c2 = ptr[p2 >> PFREAL_SHIFT]; + + int r1 = qRed(c1) * alpha/256; + int g1 = qGreen(c1) * alpha/256; + int b1 = qBlue(c1) * alpha/256; + int r2 = qRed(c2) * alpha/256; + int g2 = qGreen(c2) * alpha/256; + int b2 = qBlue(c2) * alpha/256; + + *pixel1 = qRgb(r1, g1, b1); + *pixel2 = qRgb(r2, g2, b2); + p1 -= dy; + p2 += dy; + y1--; + y2++; + pixel1 -= pixelstep; + pixel2 += pixelstep; + } + } + + rect.setTop(0); + rect.setBottom(h-1); + return rect; +} + +// Updates look-up table and other stuff necessary for the rendering. +// Call this when the viewport size or slide dimension is changed. +void PictureFlowPrivate::recalc(int ww, int wh) +{ + int w = (ww+1)/2; + int h = (wh+1)/2; + buffer = QImage(ww, wh, QImage::Format_RGB32); + buffer.fill(0); + + rays.resize(w*2); + + for(int i = 0; i < w; ++i) + { + PFreal gg = (PFREAL_HALF + i * PFREAL_ONE) / (2*h); + rays[w-i-1] = -gg; + rays[w+i] = gg; + } + + + itilt = 70 * IANGLE_MAX / 360; // approx. 70 degrees tilted + + offsetX = slideWidth/2 * (PFREAL_ONE-fcos(itilt)); + offsetY = slideWidth/2 * fsin(itilt); + offsetX += slideWidth * PFREAL_ONE; + offsetY += slideWidth * PFREAL_ONE / 4; + spacing = 40; + + surfaceCache.clear(); + blankSurface = QImage(); +} + +void PictureFlowPrivate::startAnimation() +{ +#if 1 + if(!animateTimer.isActive()) + { + step = (target < centerSlide.slideIndex) ? -1 : 1; + animateTimer.start(30, widget); + } +#else + if (animateTimer.isActive()) + animateTimer.stop(); + + step = (target < centerSlide.slideIndex) ? -1 : 1; + animateTimer.start(30, widget); +#endif +} + +// Updates the animation effect. Call this periodically from a timer. +void PictureFlowPrivate::updateAnimation() +{ + if(!animateTimer.isActive()) + return; + if(step == 0) + return; + + int speed = 16384; + + // deaccelerate when approaching the target + if(true) + { + const int max = 2 * 65536; + + int fi = slideFrame; + fi -= (target << 16); + if(fi < 0) + fi = -fi; + fi = qMin(fi, max); + + int ia = IANGLE_MAX * (fi-max/2) / (max*2); + speed = 512 + 16384 * (PFREAL_ONE+fsin(ia))/PFREAL_ONE; + } + + slideFrame += speed*step; + + int index = slideFrame >> 16; + int pos = slideFrame & 0xffff; + int neg = 65536 - pos; + int tick = (step < 0) ? neg : pos; + PFreal ftick = (tick * PFREAL_ONE) >> 16; + + // the leftmost and rightmost slide must fade away + fade = pos / 256; + + if(step < 0) + index++; + if(centerIndex != index) + { + centerIndex = index; + slideFrame = index << 16; + centerSlide.slideIndex = centerIndex; + for(int i = 0; i < leftSlides.count(); ++i) + leftSlides[i].slideIndex = centerIndex-1-i; + for(int i = 0; i < rightSlides.count(); ++i) + rightSlides[i].slideIndex = centerIndex+1+i; + } + + centerSlide.angle = (step * tick * itilt) >> 16; + centerSlide.cx = -step * fmul(offsetX, ftick); + centerSlide.cy = fmul(offsetY, ftick); + + if(centerIndex == target) + { + resetSlides(); + animateTimer.stop(); + triggerRender(); + step = 0; + fade = 256; + return; + } + + for(int i = 0; i < leftSlides.count(); ++i) + { + SlideInfo& si = leftSlides[i]; + si.angle = itilt; + si.cx = -(offsetX + spacing*i*PFREAL_ONE + step*spacing*ftick); + si.cy = offsetY; + } + + for(int i = 0; i < rightSlides.count(); ++i) + { + SlideInfo& si = rightSlides[i]; + si.angle = -itilt; + si.cx = offsetX + spacing*i*PFREAL_ONE - step*spacing*ftick; + si.cy = offsetY; + } + + if(step > 0) + { + PFreal ftick = (neg * PFREAL_ONE) >> 16; + rightSlides[0].angle = -(neg * itilt) >> 16; + rightSlides[0].cx = fmul(offsetX, ftick); + rightSlides[0].cy = fmul(offsetY, ftick); + } + else + { + PFreal ftick = (pos * PFREAL_ONE) >> 16; + leftSlides[0].angle = (pos * itilt) >> 16; + leftSlides[0].cx = -fmul(offsetX, ftick); + leftSlides[0].cy = fmul(offsetY, ftick); + } + + // must change direction ? + if(target < index) if(step > 0) + step = -1; + if(target > index) if(step < 0) + step = 1; + + triggerRender(); +} + +// ----------------------------------------- + +PictureFlow::PictureFlow(QWidget* parent): QWidget(parent) +{ + d = new PictureFlowPrivate(this); + + setAttribute(Qt::WA_StaticContents, true); + setAttribute(Qt::WA_OpaquePaintEvent, true); + setAttribute(Qt::WA_NoSystemBackground, true); +} + +PictureFlow::~PictureFlow() +{ + delete d; +} + +int PictureFlow::slideCount() const +{ + return d->slideCount(); +} + +void PictureFlow::setSlideCount(int count) +{ + d->setSlideCount(count); +} + +QSize PictureFlow::slideSize() const +{ + return d->slideSize(); +} + +void PictureFlow::setSlideSize(QSize size) +{ + d->setSlideSize(size); +} + +int PictureFlow::zoomFactor() const +{ + return d->zoomFactor(); +} + +void PictureFlow::setZoomFactor(int z) +{ + d->setZoomFactor(z); +} + +QImage PictureFlow::slide(int index) const +{ + return d->slide(index); +} + +void PictureFlow::setSlide(int index, const QImage& image) +{ + d->setSlide(index, image); +} + +void PictureFlow::setSlide(int index, const QPixmap& pixmap) +{ + d->setSlide(index, pixmap.toImage()); +} + +int PictureFlow::currentSlide() const +{ + return d->currentSlide(); +} + +void PictureFlow::setCurrentSlide(int index) +{ + d->setCurrentSlide(index); +} + +void PictureFlow::clear() +{ + d->setSlideCount(0); +} + +void PictureFlow::render() +{ + d->render(); + update(); +} + +void PictureFlow::showPrevious() +{ + d->showPrevious(); +} + +void PictureFlow::showNext() +{ + d->showNext(); +} + +void PictureFlow::showSlide(int index) +{ + d->showSlide(index); +} + +void PictureFlow::showSlideAt (int x, int y) { + if (d->slidesRect[5].contains(x, y)) + return; + + if (x < d->slidesRect[5].x()) { + for (int i=0; i < 5; ++i) { + if (d->slidesRect[i].contains(x, y)) { + showSlide(d->currentSlide() - (i + 1)); + return; + } + } + } else { + for (int i=6; i < 11; ++i) { + if (d->slidesRect[i].contains(x, y)) { + showSlide(d->currentSlide() + (i - 5)); + return; + } + } + } +} + +void PictureFlow::keyPressEvent(QKeyEvent* event) +{ + + switch (event->key()) { + case Qt::Key_Left: + if(event->modifiers() == Qt::AltModifier) { + showSlide(currentSlide() - 5); + } else { + showPrevious(); + } + event->accept(); + return; + case Qt::Key_Right: + if(event->modifiers() == Qt::AltModifier) { + showSlide(currentSlide() + 5); + } else { + showNext(); + } + event->accept(); + return; + case Qt::Key_Up: + showSlide(currentSlide() + 10); + event->accept(); + return; + case Qt::Key_Down: + showSlide(currentSlide() - 10); + event->accept(); + return; + default: + break; + } + + event->ignore(); +} + +void PictureFlow::mouseReleaseEvent (QMouseEvent *event) { + showSlideAt(event->x(), event->y()); +} + +void PictureFlow::mouseMoveEvent (QMouseEvent *event) { + showSlideAt(event->x(), event->y()); +} + +void PictureFlow::wheelEvent (QWheelEvent *event) { + int numDegrees = event->delta() / 8; + int numSteps = numDegrees / 15; + + d->showSlide(d->currentSlide() + numSteps); + event->accept(); +} + +void PictureFlow::paintEvent(QPaintEvent* event) +{ + Q_UNUSED(event); + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing, false); + painter.drawImage(QPoint(0,0), d->buffer); +} + +void PictureFlow::resizeEvent(QResizeEvent* event) +{ + d->resize(width(), height()); + QWidget::resizeEvent(event); +} + +void PictureFlow::timerEvent(QTimerEvent* event) +{ + if(event->timerId() == d->animateTimer.timerId()) + d->updateAnimation(); + else + QWidget::timerEvent(event); +} + +} // namespace FQTerm + +#include "pictureflow.moc" diff --git a/src/ui/pictureflow.h b/src/ui/pictureflow.h new file mode 100644 index 0000000..c9cf5aa --- /dev/null +++ b/src/ui/pictureflow.h @@ -0,0 +1,198 @@ + +/*************************************************************************** + * 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. * + ***************************************************************************/ + +/* + PictureFlow - animated image show widget + http://pictureflow.googlecode.com + + Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef PICTUREFLOW_H +#define PICTUREFLOW_H + +#include <QWidget> + +namespace FQTerm { + +class PictureFlowPrivate; + +/*! + Class PictureFlow implements an image show widget with animation effect + like Apple's CoverFlow (in iTunes and iPod). Images are arranged in form + of slides, one main slide is shown at the center with few slides on + the left and right sides of the center slide. When the next or previous + slide is brought to the front, the whole slides flow to the right or + the right with smooth animation effect; until the new slide is finally + placed at the center. + + */ +class PictureFlow : public QWidget +{ +Q_OBJECT + + Q_PROPERTY(int slideCount READ slideCount WRITE setSlideCount) + Q_PROPERTY(int currentSlide READ currentSlide WRITE setCurrentSlide) + Q_PROPERTY(QSize slideSize READ slideSize WRITE setSlideSize) + Q_PROPERTY(int zoomFactor READ zoomFactor WRITE setZoomFactor) + +public: + /*! + Creates a new PictureFlow widget. + */ + PictureFlow(QWidget* parent = 0); + + /*! + Destroys the widget. + */ + ~PictureFlow(); + + /*! + Returns the total number of slides. + */ + int slideCount() const; + + /*! + Sets the total number of slides. + */ + void setSlideCount(int count); + + /*! + Returns the dimension of each slide (in pixels). + */ + QSize slideSize() const; + + /*! + Sets the dimension of each slide (in pixels). + */ + void setSlideSize(QSize size); + + /*! + Sets the zoom factor (in percent). + */ + void setZoomFactor(int zoom); + + /*! + Returns the zoom factor (in percent). + */ + int zoomFactor() const; + + /*! + Returns QImage of specified slide. + This function will be called only whenever necessary, e.g. the 100th slide + will not be retrived when only the first few slides are visible. + */ + virtual QImage slide(int index) const; + + /*! + Sets an image for specified slide. If the slide already exists, + it will be replaced. + */ + virtual void setSlide(int index, const QImage& image); + + /*! + Sets a pixmap for specified slide. If the slide already exists, + it will be replaced. + */ + virtual void setSlide(int index, const QPixmap& pixmap); + + /*! + Returns the index of slide currently shown in the middle of the viewport. + */ + int currentSlide() const; + +signals: + void slideSelected (int index); + +public slots: + + /*! + Sets slide to be shown in the middle of the viewport. No animation + effect will be produced, unlike using showSlide. + */ + void setCurrentSlide(int index); + + /*! + Clears images of all slides. + */ + void clear(); + + /*! + Rerender the widget. Normally this function will be automatically invoked + whenever necessary, e.g. during the transition animation. + */ + void render(); + + /*! + Shows previous slide using animation effect. + */ + void showPrevious(); + + /*! + Shows next slide using animation effect. + */ + void showNext(); + + /*! + Go to specified slide using animation effect. + */ + void showSlide(int index); + + + /*! + Go to slide at specified position using animation effect. + */ + void showSlideAt(int x, int y); + +protected: + void mouseReleaseEvent (QMouseEvent *event); + void mouseMoveEvent (QMouseEvent *event); + void wheelEvent (QWheelEvent *event); + void paintEvent(QPaintEvent *event); + void keyPressEvent(QKeyEvent *event); + void resizeEvent(QResizeEvent *event); + void timerEvent(QTimerEvent *event); + +private: + PictureFlowPrivate* d; +}; + +} // namespace FQTerm + +#endif // PICTUREFLOW_H diff --git a/src/ui/popupMessage.cpp b/src/ui/popupMessage.cpp new file mode 100644 index 0000000..6b89b38 --- /dev/null +++ b/src/ui/popupMessage.cpp @@ -0,0 +1,316 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include <QVBoxLayout> +#include <QPixmap> +#include <QHBoxLayout> +#include <QTimerEvent> +#include <QLabel> +#include <QMessageBox> +#include <QTimer> +#include <QFont> +#include <QPushButton> +#include <QPainter> + +#include "popupMessage.h" +#include "fqterm_trace.h" + +namespace FQTerm { + +PopupMessage::PopupMessage(QWidget *parent_, QWidget *anchor, int timeout) + : OverlayWidget(parent_, anchor), + anchor_(anchor), + parent_(parent_), + maskEffect_(Slide), + dissolveSize_(0), + dissolveDelta_(-1), + offset_(0), + counter_(0), + stage_(1), + timeout_(timeout), + isCounterShown_(true) { + setFrameStyle(QFrame::Panel | QFrame::Raised); + setFrameShape(QFrame::StyledPanel); + // overrideWindowFlags( Qt::WX11BypassWM ); + + QHBoxLayout *hbox; + QLabel *label; + QLabel *alabel; + //KActiveLabel *alabel; + + layout_ = new QVBoxLayout(this); //, 9 /*margin*/, 6 /*spacing*/ ); + layout_->setMargin(9); + layout_->setSpacing(6); + + hbox = new QHBoxLayout; //( layout_, 12 ); + hbox->setMargin(12); + + layout_->addLayout(hbox); + + hbox->addWidget(countDownFrame_ = new QFrame(this)); //, "counterVisual" ) ); + countDownFrame_->setObjectName("counterVisual"); + countDownFrame_->setFixedWidth(fontMetrics().width("X")); + countDownFrame_->setFrameStyle(QFrame::Plain | QFrame::Box); + QPalette tmp_palette; + tmp_palette.setColor(countDownFrame_->foregroundRole(), palette().color + (QPalette::Window).dark()); + countDownFrame_->setPalette(tmp_palette); + // m_countdownFrame->setPaletteForegroundColor( paletteBackgroundColor().dark() ); + + label = new QLabel(this); //, "image" ); + label->setObjectName("image"); + hbox->addWidget(label); + label->hide(); + + alabel = new QLabel("Details of the tasks: ", this); //, "label"); + alabel->setObjectName("label"); + //alabel = new KActiveLabel( this, "label" ); + //alabel->setTextFormat( Qt::RichText ); + alabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); + + hbox->addWidget(alabel); + + hbox = new QHBoxLayout; + + layout_->addLayout(hbox); + + hbox->addItem(new QSpacerItem(4, 4, QSizePolicy::Expanding, + QSizePolicy::Preferred)); + //FIXME: add icon + QPushButton *tmp_button = new QPushButton("Close", this); + tmp_button->setObjectName("closeButton"); + hbox->addWidget(tmp_button); //, "closeButton" ) ); + + FQ_VERIFY(connect(findChild < QPushButton * > ("closeButton"), SIGNAL(clicked()), + SLOT(close()))); +} + +void PopupMessage::addWidget(QWidget *widget) { + layout_->addWidget(widget); + adjustSize(); +} + +void PopupMessage::showCloseButton(const bool show) { + findChild < QPushButton * > ("closeButton")->setShown(show); + adjustSize(); +} + +void PopupMessage::showCounter(const bool show) { + isCounterShown_ = show; + findChild < QFrame * > ("counterVisual")->setShown(show); + adjustSize(); +} + +void PopupMessage::setText(const QString &text) { + findChild < QLabel * > ("label")->setText(text); + adjustSize(); +} + +void PopupMessage::setImage(const QString &location_) { + findChild < QLabel * > ("image")->setPixmap(QPixmap(location_)); + adjustSize(); +} + + +//////////////////////////////////////////////////////////////////////// +// Public Slots +//////////////////////////////////////////////////////////////////////// + +void PopupMessage::close() { //SLOT + stage_ = 3; + killTimer(timerId_); + timerId_ = startTimer(6); +} + +void PopupMessage::display() { //SLOT + dissolveSize_ = 24; + dissolveDelta_ = -1; + + if (maskEffect_ == Dissolve) { + // necessary to create the mask + maskBitmap_ = QBitmap(width(), height()); + // make the mask empty and hence will not show widget with show() called below + dissolveMask(); + timerId_ = startTimer(1000 / 30); + } else { + timerId_ = startTimer(6); + } + show(); +} + +//////////////////////////////////////////////////////////////////////// +// Protected +//////////////////////////////////////////////////////////////////////// + +void PopupMessage::timerEvent(QTimerEvent*) { + switch (maskEffect_) { + case Plain: + plainMask(); + break; + + case Slide: + slideMask(); + break; + + case Dissolve: + dissolveMask(); + break; + } +} + +void PopupMessage::countDown() { + if (!timeout_) { + killTimer(timerId_); + return ; + } + + QFrame * &h = countDownFrame_; + + if (counter_ < h->height() - 3) { + QPainter(h).fillRect(2, 2, h->width() - 4, counter_, palette().color + (QPalette::Active, QPalette::Highlight)); + } + + if (!testAttribute(Qt::WA_UnderMouse)) { + counter_++; + } + + if (counter_ > h->height()) { + stage_ = 3; + killTimer(timerId_); + timerId_ = startTimer(6); + } else { + killTimer(timerId_); + timerId_ = startTimer(timeout_ / h->height()); + } +} + +void PopupMessage::dissolveMask() { + if (stage_ == 1) { + //repaint( false ); + QPainter maskPainter(&maskBitmap_); + + maskBitmap_.fill(Qt::black); + + maskPainter.setBrush(Qt::white); + maskPainter.setPen(Qt::white); + maskPainter.drawRect(maskBitmap_.rect()); + + dissolveSize_ += dissolveDelta_; + + if (dissolveSize_ > 0) { + //maskPainter.setCompositionMode( Qt::EraseROP ); + //FIXME: QRubberBand + + int x, y, s; + const int size = 16; + + for (y = 0; y < height() + size; y += size) { + x = width(); + s = dissolveSize_ * x / 128; + + for (; x > size; x -= size, s -= 2) { + if (s < 0) { + break; + } + + maskPainter.drawEllipse(x - s / 2, y - s / 2, s, s); + } + } + } else if (dissolveSize_ < 0) { + dissolveDelta_ = 1; + killTimer(timerId_); + + if (timeout_) { + timerId_ = startTimer(40); + stage_ = 2; + } + } + + setMask(maskBitmap_); + } else if (stage_ == 2) { + countDown(); + } else { + deleteLater(); + } +} + + +void PopupMessage::plainMask() { + switch (stage_) { + case 1: + // Raise + killTimer(timerId_); + if (timeout_) { + timerId_ = startTimer(40); + stage_ = 2; + } + + break; + + case 2: + // Counter + countDown(); + break; + + case 3: + // Lower/Remove + deleteLater(); + } +} + + +void PopupMessage::slideMask() { + switch (stage_) { + case 1: + //raise + move(0, parent_->y() - offset_); + + offset_++; + if (offset_ > height()) { + killTimer(timerId_); + + if (timeout_) { + timerId_ = startTimer(40); + stage_ = 2; + } + } + + break; + + case 2: + //fill in pause timer bar + countDown(); + break; + + case 3: + //lower + offset_--; + move(0, parent_->y() - offset_); + + if (offset_ < 0) { + deleteLater(); + } + } +} + +} // namespace FQTerm + +#include "popupMessage.moc" diff --git a/src/ui/popupMessage.h b/src/ui/popupMessage.h new file mode 100644 index 0000000..1877b1c --- /dev/null +++ b/src/ui/popupMessage.h @@ -0,0 +1,116 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +//WARNING this is not meant for use outside this unit! + + +#ifndef FQTERM_POPUP_MESSAGE_H +#define FQTERM_POPUP_MESSAGE_H + +#include "overlayWidget.h" + +// #include <qbitmap.h> +// #include <qlayout.h> +// #include <qpixmap.h> +//Added by qt3to4: +#include <QVBoxLayout> +#include <QTimerEvent> +#include <QFrame> +#include <QBitmap> +#include <QPixmap> + +namespace FQTerm { +/** + * @class PopupMessage + * @short Widget that animates itself into a position relative to an anchor widget + */ +class PopupMessage: public OverlayWidget { + Q_OBJECT; + public: + /** + * @param anchor : which widget to tie the popup widget to. + * @param timeout : how long to wait before auto closing. A value of 0 means close + * only on pressing the closeButton or close() is called. + */ + PopupMessage(QWidget *parent_, QWidget *anchor, int timeout = 5000 + /*milliseconds*/); + + enum MaskEffect { + Plain, Slide, Dissolve + }; + + void addWidget(QWidget *widget); + void showCloseButton(const bool show); + void showCounter(const bool show); + void setImage(const QString &location_); + void setMaskEffect(const MaskEffect type) { + maskEffect_ = type; + } + void setText(const QString &text); + void setTimeout(const int time) { + timeout_ = time; + } + + public slots: + void close(); + void display(); + + protected: + void timerEvent(QTimerEvent*); + void countDown(); + + /** + * @short Gradually show widget by dissolving from background + */ + void dissolveMask(); + + /** + * @short instantly display widget + */ + void plainMask(); + + /** + * @short animation to slide the widget into view + */ + void slideMask(); + + private: + QVBoxLayout *layout_; + QFrame *countDownFrame_; + QWidget *anchor_; + QWidget *parent_; + QBitmap maskBitmap_; + MaskEffect maskEffect_; + + int dissolveSize_; + int dissolveDelta_; + + int offset_; + int counter_; + int stage_; + int timeout_; + int timerId_; + + bool isCounterShown_; +}; + +} // namespace FQTerm + +#endif // FQTERM_POPUP_MESSAGE_H diff --git a/src/ui/popwidget.cpp b/src/ui/popwidget.cpp new file mode 100644 index 0000000..1c702ed --- /dev/null +++ b/src/ui/popwidget.cpp @@ -0,0 +1,177 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include "popwidget.h" + +#include <QPixmap> +#include <QApplication> +#include <QDesktopWidget> +#include <QTimer> +#include <QLabel> + +#include <QMouseEvent> +#include <QPalette> + +namespace FQTerm { + +extern QString pathLib; + +popWidget::popWidget(FQTermWindow *win, QWidget *parent_, const char *name, + Qt::WFlags f) + : QWidget(parent_, f) { + // QPixmap pxm(QPixmap(pathLib+"pic/popwidget.png") ); + // if(!pxm.isNull()) + // { + // resize(pxm.width(), pxm.height()); + // QPalette palette; + // palette.setBrush(backgroundRole(), QBrush(pxm)); + // setPalette(palette); + // //setBackgroundPixmap(pxm); + // } + // else + // { + // resize(200, 120); + // } + // + // label_ = new QLabel(this); + // label_->setGeometry( QRect( 5, height()/3, width()-10, height()*2/3 ) ); + // label_->setAlignment( Qt::AlignTop ); + // label_->setWordWrap(true); + // if(!pxm.isNull()){ + // QPalette palette; + // palette.setBrush(label_->backgroundRole(), QBrush(pxm)); + // label_->setPalette(palette); + // // label_->setBackgroundPixmap(pxm); + // } + // else { + // QPalette palette; + // palette.setColor(label_->backgroundRole(), QColor(249,250,229)); + // label_->setPalette(palette); + // //label_->setBackgroundColor(QColor(249,250,229)); + // } + // //label_->setBackgroundOrigin( ParentOrigin ); + // label_->setFont(QFont(qApp->font().family(), 12)); + // + // pTimer = new QTimer(this); + // QVERIFY(connect(pTimer, SIGNAL(timeout()), this, SLOT(showTimer()))); + // + // stateID = -1; + // + // stepID_ = 2; + // + // intervalID_ = 500/(height()/stepID_); + // + // setFocusPolicy(Qt::NoFocus); + // + // termWindow_ = win; + // + // hide(); + // + // Display *dsp = QX11Info::display(); + // int screen = DefaultScreen(dsp); + // Window root = RootWindow(dsp, screen); + // + // WId winid = this->winId(); + // + // XEvent ev; + // memset(&ev, 0, sizeof(ev)); + // + // ev.xclient.type = ClientMessage; + // ev.xclient.termWindow_ = winid; + // ev.xclient.message_type = XInternAtom (dsp, "_NET_WM_DESKTOP", False ); + // ev.xclient.format = 32; + // ev.xclient.data.l[0] = -1; + // ev.xclient.data.l[1] = 0l; + // ev.xclient.data.l[2] = 0l; + // ev.xclient.data.l[3] = 0l; + // ev.xclient.data.l[4] = 0l; + // + // XSendEvent(dsp, root, False, SubstructureRedirectMask|SubstructureNotifyMask, &ev); + // XSync(dsp, False); +} + +popWidget::~popWidget() { + // delete pTimer; +} + +void popWidget::mousePressEvent(QMouseEvent *me) { + // QWidgetList list = QApplication::topLevelWidgets(); + // + // //((FQTermFrame *)qApp->mainWidget())->popupFocusIn(termWindow_); + // + // if(stateID==1) + // { + // stateID = 2; + // pTimer->setInterval(intervalID_); + // } +} + + +void popWidget::popup() { + // pTimer->start(intervalID_); + // stateID = 0; + // + // desktopRectangle_ = qApp->desktop()->rect(); + // position_ = QPoint( desktopRectangle_.width()-width()-5, desktopRectangle_.height()-5 ); + // move(position_); + // + // if(!isVisible()) + // show(); +} + +void popWidget::setText(const QString &str) { + // label_->setText(str); +} + +void popWidget::showTimer() { + // switch(stateID) + // { + // case 0: // popup + // if(position_.y()+height()+5>desktopRectangle_.height()) + // position_.setY( position_.y() - stepID_ ); + // else + // { + // stateID = 1; + // pTimer->setInterval(5000); + // } + // break; + // case 1: // wait + // stateID = 2; + // pTimer->setInterval(intervalID_); + // break; + // case 2: // hiding + // if(position_.y()<desktopRectangle_.height()) + // position_.setY( position_.y() + stepID_ ); + // else + // { + // stateID = -1; + // pTimer->stop(); + // } + // break; + // default: + // + // break; + // } + // move(position_); +} + +} // namespace FQTerm + +#include "popwidget.moc" diff --git a/src/ui/popwidget.h b/src/ui/popwidget.h new file mode 100644 index 0000000..2a02c7d --- /dev/null +++ b/src/ui/popwidget.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef FQTERM_POP_WIDGET_H +#define FQTERM_POP_WIDGET_H + +#include <QWidget> +//Added by qt3to4: +#include <QMouseEvent> +#include <QLabel> + +class QTimer; +class QLabel; + +namespace FQTerm { + +class FQTermWindow; + +class popWidget: public QWidget { + Q_OBJECT; + public: + // #if (QT_VERSION>=310) + // popWidget(FQTermWindow * win, QWidget *parent = 0, const char *name=0, WFlags f=WStyle_Splash); + // #else + popWidget(FQTermWindow *win, QWidget *parent_ = 0, const char *name = 0, + Qt::WFlags f = Qt::WindowStaysOnTopHint + | Qt::X11BypassWindowManagerHint + | Qt::Tool); + // #endif + ~popWidget(); + + void popup(); + void setText(const QString &); + + public slots: + void showTimer(); + + protected: + QTimer *pTimer; + int stateID; // -1 hide, 0 popup, 1 wait, 2 hiding + QPoint position_; + QRect desktopRectangle_; + int stepID_; + int intervalID_; + QLabel *label_; + FQTermWindow *termWindow_; + + void mousePressEvent(QMouseEvent*); +}; + +} // namespace FQTerm + +#endif // FQTERM_POP_WIDGET_H diff --git a/src/ui/prefdialog.cpp b/src/ui/prefdialog.cpp new file mode 100644 index 0000000..9f01a08 --- /dev/null +++ b/src/ui/prefdialog.cpp @@ -0,0 +1,332 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include <QCloseEvent> +#include <QComboBox> +#include <QFileDialog> + +#include "fqterm_config.h" +#include "fqterm_path.h" +#include "fqterm_trace.h" + +#include "prefdialog.h" +#include "soundconf.h" + +namespace FQTerm { + +/* + * Constructs a prefDialog which is a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +prefDialog::prefDialog(FQTermConfig * config, QWidget *parent, Qt::WFlags fl) + : QDialog(parent, fl), + soundButtonGroup_(this), + verticalSettingButtonGroup_(this), + config_(config){ + ui_.setupUi(this); + fileDialog_ = new FQTermFileDialog(config_); + soundButtonGroup_.addButton(ui_.noneRadioButton, 0); + soundButtonGroup_.addButton(ui_.beepRadioButton, 1); + soundButtonGroup_.addButton(ui_.fileRadioButton, 2); + verticalSettingButtonGroup_.addButton(ui_.topRadioButton, 0); + verticalSettingButtonGroup_.addButton(ui_.middleRadioButton, 1); + verticalSettingButtonGroup_.addButton(ui_.bottomRadioButton, 2); + + connectSlots(); + + loadSetting(); + +} + +/* + * Destroys the object and frees any allocated resources + */ +prefDialog::~prefDialog() { + // no need to delete child widgets, Qt does it all for us + delete fileDialog_; +} + +void prefDialog::connectSlots() { + FQ_VERIFY(connect(ui_.okPushButton, SIGNAL(clicked()), this, SLOT(onOK()))); + FQ_VERIFY(connect(ui_.cancelPushButton, SIGNAL(clicked()), this, SLOT(onCancel()))); + FQ_VERIFY(connect(ui_.selectsoundPushButton, SIGNAL(clicked()), this, SLOT(onSound()))); + FQ_VERIFY(connect(ui_.choosehttpPushButton, SIGNAL(clicked()), this, SLOT(onHttp()))); + //FQ_VERIFY(connect(ButtonGroup1 , SIGNAL(clicked(int)), this, SLOT(onBeep(int)) )); + FQ_VERIFY(connect(ui_.browsePushButton, SIGNAL(clicked()), this, SLOT(onBrowse()))); + FQ_VERIFY(connect(ui_.imagePushButton, SIGNAL(clicked()), this, SLOT(onImage()))); + FQ_VERIFY(connect(ui_.poolPushButton, SIGNAL(clicked()), this, SLOT(onPool()))); + FQ_VERIFY(connect(ui_.styleSheetPushButton, SIGNAL(clicked()), this, SLOT(onStyleSheet()))); + FQ_VERIFY(connect(ui_.editorPushButton, SIGNAL(clicked()), this, SLOT(onEditor()))); +} + +void prefDialog::loadSetting() { + + QString strTmp; + + strTmp = config_->getItemValue("preference", "displayoffset"); + ui_.displayOffsetSlider->setSliderPosition(strTmp.toInt()); + + strTmp = config_->getItemValue("preference", "xim"); + ui_.ximComboBox->setCurrentIndex(strTmp.toInt()); + + strTmp = config_->getItemValue("preference", "wordwrap"); + ui_.wordLineEdit3->setText(strTmp); + + strTmp = config_->getItemValue("preference", "smartww"); + ui_.smartCheckBox->setChecked(strTmp != "0"); + + strTmp = config_->getItemValue("preference", "wheel"); + ui_.wheelCheckBox->setChecked(strTmp != "0"); + + strTmp = config_->getItemValue("preference", "url"); + ui_.urlCheckBox->setChecked(strTmp != "0"); + + strTmp = config_->getItemValue("preference", "logmsg"); + ui_.saveCheckBox->setChecked(strTmp != "0"); + + strTmp = config_->getItemValue("preference", "blinktab"); + ui_.blinkCheckBox->setChecked(strTmp != "0"); + + strTmp = config_->getItemValue("preference", "warn"); + ui_.warnCheckBox->setChecked(strTmp != "0"); + + strTmp = config_->getItemValue("preference", "beep"); + qobject_cast<QRadioButton *>(soundButtonGroup_.button(strTmp.toInt()))->setChecked(true); + + strTmp = config_->getItemValue("preference", "vsetting"); + qobject_cast<QRadioButton *>(verticalSettingButtonGroup_.button(strTmp.toInt()))->setChecked(true); + + strTmp = config_->getItemValue("preference", "enq"); + ui_.enqCheckBox->setChecked(strTmp != "0"); + + //ButtonGroup1->find(strTmp.toInt()))->setChecked(true); + + // if(strTmp.toInt()!=2) + // { + // wavefileLineEdit->setEnabled(false); + // selectsoundPushButton->setEnabled(false); + // } + + strTmp = config_->getItemValue("preference", "wavefile"); + ui_.wavefileLineEdit->setText(strTmp); + + strTmp = config_->getItemValue("preference", "antialias"); + ui_.aacheckBox->setChecked(strTmp != "0"); + + + strTmp = config_->getItemValue("preference", "tray"); + ui_.trayCheckBox->setChecked(strTmp != "0"); + + strTmp = config_->getItemValue("preference", "clearpool"); + ui_.clearCheckBox->setChecked(strTmp == "1"); + + strTmp = config_->getItemValue("preference", "pool"); + if (strTmp.isEmpty()) { + strTmp = getPath(USER_CONFIG) + "pool/"; + } + ui_.poolLineEdit->setText(strTmp); + + strTmp = config_->getItemValue("preference", "http"); + ui_.httpLineEdit->setText(strTmp); + + strTmp = config_->getItemValue("preference", "zmodem"); + if (strTmp.isEmpty()) { + strTmp = getPath(USER_CONFIG) + "zmodem/"; + } + ui_.zmodemLineEdit->setText(strTmp); + + strTmp = config_->getItemValue("preference", "image"); + ui_.imageLineEdit->setText(strTmp); + + strTmp = config_->getItemValue("preference", "qssfile"); + ui_.styleSheetLineEdit->setText(strTmp); + + strTmp = config_->getItemValue("preference", "editor"); + ui_.editorLineEdit->setText(strTmp); + + strTmp = config_->getItemValue("preference", "editorarg"); + ui_.editorArgLineEdit->setText(strTmp); + + strTmp = config_->getItemValue("preference", "asciienhance"); + ui_.asciiEnhanceCheckBox->setChecked(strTmp == "1"); +} + +void prefDialog::saveSetting() { + + QString strTmp; + + strTmp.setNum(ui_.displayOffsetSlider->sliderPosition()); + config_->setItemValue("preference", "displayoffset", strTmp); + + strTmp.setNum(ui_.ximComboBox->currentIndex()); + config_->setItemValue("preference", "xim", strTmp); + + + config_->setItemValue("preference", "wordwrap", ui_.wordLineEdit3->text()); + + strTmp.setNum(ui_.smartCheckBox->isChecked() ? 1 : 0); + config_->setItemValue("preference", "smartww", strTmp); + + strTmp.setNum(ui_.wheelCheckBox->isChecked() ? 1 : 0); + config_->setItemValue("preference", "wheel", strTmp); + + strTmp.setNum(ui_.urlCheckBox->isChecked() ? 1 : 0); + config_->setItemValue("preference", "url", strTmp); + + strTmp.setNum(ui_.saveCheckBox->isChecked() ? 1 : 0); + config_->setItemValue("preference", "logmsg", strTmp); + + strTmp.setNum(ui_.blinkCheckBox->isChecked() ? 1 : 0); + config_->setItemValue("preference", "blinktab", strTmp); + + strTmp.setNum(ui_.warnCheckBox->isChecked() ? 1 : 0); + config_->setItemValue("preference", "warn", strTmp); + + strTmp.setNum(ui_.aacheckBox->isChecked() ? 1 : 0); + config_->setItemValue("preference", "antialias", strTmp); + + strTmp.setNum(ui_.trayCheckBox->isChecked() ? 1 : 0); + config_->setItemValue("preference", "tray", strTmp); + + strTmp.setNum(ui_.enqCheckBox->isChecked() ? 1 : 0); + config_->setItemValue("preference", "enq", strTmp); + + strTmp.setNum(soundButtonGroup_.checkedId()); + config_->setItemValue("preference", "beep", strTmp); + + strTmp.setNum(verticalSettingButtonGroup_.checkedId()); + config_->setItemValue("preference", "vsetting", strTmp); + + if (strTmp == "2") { + config_->setItemValue("preference", "wavefile", ui_.wavefileLineEdit->text()); + } + + strTmp.setNum(ui_.clearCheckBox->isChecked() ? 1 : 0); + config_->setItemValue("preference", "clearpool", strTmp); + + strTmp.setNum(ui_.asciiEnhanceCheckBox->isChecked() ? 1 : 0); + config_->setItemValue("preference", "asciienhance", strTmp); + + strTmp = ui_.poolLineEdit->text(); + if (strTmp.isEmpty()) { + strTmp = getPath(USER_CONFIG) + "pool/"; + } + config_->setItemValue("preference", "pool", strTmp); + + strTmp = ui_.zmodemLineEdit->text(); + if (strTmp.isEmpty()) { + strTmp = getPath(USER_CONFIG) + "zmodem/"; + } + config_->setItemValue("preference", "zmodem", strTmp); + config_->setItemValue("preference", "http", ui_.httpLineEdit->text()); + config_->setItemValue("preference", "image", ui_.imageLineEdit->text()); + + config_->setItemValue("preference", "qssfile", ui_.styleSheetLineEdit->text().trimmed()); + + config_->setItemValue("preference", "editor", ui_.editorLineEdit->text()); + config_->setItemValue("preference", "editorarg", ui_.editorArgLineEdit->text()); + + config_->save(getPath(USER_CONFIG) + "fqterm.cfg"); +} + +void prefDialog::closeEvent(QCloseEvent*) { + reject(); +} + +void prefDialog::onOK() { + saveSetting(); + done(1); +} + +void prefDialog::onCancel() { + done(0); +} + +void prefDialog::onSound() { + soundConf soundconf(config_, this); + if (soundconf.exec() == 1) { + loadSetting(); + } + +} + +void prefDialog::onHttp() { + QString http = fileDialog_->getOpenName("Choose a WWW browser", "*"); + if (!http.isEmpty()) { + ui_.httpLineEdit->setText(http); + } + +} + +// void prefDialog::onBeep( int id ) +// { +// if(id==2) +// { +// ui.wavefileLineEdit->setEnabled(true); +// ui.selectsoundPushButton->setEnabled(true); +// } +// else if(id==0 || id==1 ) +// { +// ui.wavefileLineEdit->setEnabled(false); +// ui.selectsoundPushButton->setEnabled(false); +// } +// } + +void prefDialog::onBrowse() { + QString dir = fileDialog_->getExistingDirectory("Choose a directory", ui_.zmodemLineEdit->text()); + if (!dir.isEmpty()) { + ui_.zmodemLineEdit->setText(dir); + } +} + +void prefDialog::onImage() { + QString image = fileDialog_->getOpenName("Choose an Image Viewer", "*"); + if (!image.isEmpty()) { + ui_.imageLineEdit->setText(image); + } +} + +void prefDialog::onPool() { + QString pool = fileDialog_->getExistingDirectory("Choose a directory", ui_.poolLineEdit->text()); + if (!pool.isEmpty()) { + ui_.poolLineEdit->setText(pool); + } +} + +void prefDialog::onStyleSheet() +{ + QString qssFile = fileDialog_->getOpenName("Choose a QSS File", "Qt Style Sheets (*.qss *.QSS)"); + if (!qssFile.isEmpty()) { + ui_.styleSheetLineEdit->setText(qssFile); + } +} + +void prefDialog::onEditor() { + QString editor = fileDialog_->getOpenName("Choose a directory", ui_.editorLineEdit->text()); + if (!editor.isEmpty()) { + ui_.editorLineEdit->setText(editor); + } +} +} // namespace FQTerm + +#include "prefdialog.moc" diff --git a/src/ui/prefdialog.h b/src/ui/prefdialog.h new file mode 100644 index 0000000..99e58c6 --- /dev/null +++ b/src/ui/prefdialog.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef FQTERM_PREF_DIALOG_H +#define FQTERM_PREF_DIALOG_H + +#include "ui_prefdialog.h" +#include "fqterm_filedialog.h" + +class QCloseEvnt; + +namespace FQTerm { + +class FQTermConfig; + +class prefDialog: public QDialog { + Q_OBJECT; + public: + prefDialog(FQTermConfig *, QWidget *parent_ = 0, Qt::WFlags fl = 0); + ~prefDialog(); + + protected slots: + void onOK(); + void onCancel(); + void onSound(); + void onHttp(); + // void onBeep(int); + void onBrowse(); + void onImage(); + void onPool(); + void onStyleSheet(); + void onEditor(); + protected: + void closeEvent(QCloseEvent*); + void connectSlots(); + void loadSetting(); + void saveSetting(); + + private: + Ui::prefDialog ui_; + QButtonGroup soundButtonGroup_; + QButtonGroup verticalSettingButtonGroup_; + FQTermConfig * config_; + FQTermFileDialog *fileDialog_; +}; + +} // namespace FQTerm + +#endif // FQTERM_PREF_DIALOG_H diff --git a/src/ui/prefdialog.ui b/src/ui/prefdialog.ui new file mode 100644 index 0000000..9aaf484 --- /dev/null +++ b/src/ui/prefdialog.ui @@ -0,0 +1,644 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>prefDialog</class> + <widget class="QDialog" name="prefDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>619</width> + <height>584</height> + </rect> + </property> + <property name="windowTitle"> + <string>Preference</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0" colspan="3"> + <layout class="QHBoxLayout"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>11</number> + </property> + <item> + <widget class="QLabel" name="TextLabel1_2"> + <property name="text"> + <string>Paste Word-Wrap At</string> + </property> + </widget> + </item> + <item> + <spacer> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLineEdit" name="wordLineEdit3"/> + </item> + <item> + <widget class="QCheckBox" name="smartCheckBox"> + <property name="text"> + <string>Enable Smart Word-Wrap</string> + </property> + </widget> + </item> + <item> + <spacer> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <spacer> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="1" column="0" rowspan="2"> + <layout class="QVBoxLayout"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>0</number> + </property> + <item> + <widget class="QCheckBox" name="wheelCheckBox"> + <property name="text"> + <string>Alternative Mouse Wheel Control</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="urlCheckBox"> + <property name="text"> + <string>Detect URL When Mouse Move</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="saveCheckBox"> + <property name="text"> + <string>Save Message To File</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="blinkCheckBox"> + <property name="text"> + <string>Blink Tab When Receive Message</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="warnCheckBox"> + <property name="text"> + <string>Warn When Exit Connected</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="aacheckBox"> + <property name="text"> + <string>AntiAlias</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="trayCheckBox"> + <property name="text"> + <string>Show As Tray When Close</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="clearCheckBox"> + <property name="text"> + <string>Clear ZModem And HTTP Directory When Exit</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="enqCheckBox"> + <property name="text"> + <string>Reply when ENQ received</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="asciiEnhanceCheckBox"> + <property name="text"> + <string>ASCII Art Enhance Mode</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="1" column="1" rowspan="2" colspan="2"> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + </widget> + </item> + <item row="2" column="2"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Sound When Receive Messages</string> + </property> + <layout class="QGridLayout"> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <item row="0" column="0"> + <widget class="QRadioButton" name="noneRadioButton"> + <property name="text"> + <string>None</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QRadioButton" name="beepRadioButton"> + <property name="text"> + <string>Beep</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QRadioButton" name="fileRadioButton"> + <property name="text"> + <string>Sound File</string> + </property> + </widget> + </item> + <item row="1" column="0" colspan="2"> + <widget class="QLineEdit" name="wavefileLineEdit"/> + </item> + <item row="1" column="2"> + <widget class="QPushButton" name="selectsoundPushButton"> + <property name="text"> + <string>Configure</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <layout class="QHBoxLayout"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>11</number> + </property> + <item> + <widget class="QLabel" name="TextLabel1"> + <property name="text"> + <string>Input Method</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="ximComboBox"> + <item> + <property name="text"> + <string>GBK</string> + </property> + </item> + <item> + <property name="text"> + <string>BIG5</string> + </property> + </item> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Display Offset</string> + </property> + </widget> + </item> + <item> + <widget class="QSlider" name="displayOffsetSlider"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="tickPosition"> + <enum>QSlider::TicksBelow</enum> + </property> + <property name="tickInterval"> + <number>5</number> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QGroupBox" name="verticalDisplayGroupBox"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>40</height> + </size> + </property> + <property name="title"> + <string>Vertical Display</string> + </property> + <widget class="QRadioButton" name="topRadioButton"> + <property name="geometry"> + <rect> + <x>11</x> + <y>15</y> + <width>84</width> + <height>18</height> + </rect> + </property> + <property name="text"> + <string>Top</string> + </property> + </widget> + <widget class="QRadioButton" name="middleRadioButton"> + <property name="geometry"> + <rect> + <x>123</x> + <y>15</y> + <width>84</width> + <height>18</height> + </rect> + </property> + <property name="text"> + <string>Middle</string> + </property> + </widget> + <widget class="QRadioButton" name="bottomRadioButton"> + <property name="geometry"> + <rect> + <x>234</x> + <y>15</y> + <width>84</width> + <height>18</height> + </rect> + </property> + <property name="text"> + <string>Bottom</string> + </property> + </widget> + </widget> + </item> + <item> + <spacer> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::MinimumExpanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>287</width> + <height>28</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="3" column="0" colspan="3"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QLabel" name="textLabel1"> + <property name="text"> + <string>Zmodem Directory</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="textLabel1_3"> + <property name="text"> + <string>HTTP Directory</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="textLabel9"> + <property name="text"> + <string>StyleSheet File</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="TextLabel3"> + <property name="text"> + <string>HTTP Browser</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="textLabel1_2"> + <property name="text"> + <string>Image Viewer</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="textLabel1_4"> + <property name="text"> + <string>Editor & Args</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0" colspan="2"> + <widget class="QLineEdit" name="zmodemLineEdit"/> + </item> + <item row="1" column="0" colspan="2"> + <widget class="QLineEdit" name="poolLineEdit"/> + </item> + <item row="2" column="0" colspan="2"> + <widget class="QLineEdit" name="styleSheetLineEdit"/> + </item> + <item row="3" column="0" colspan="2"> + <widget class="QLineEdit" name="httpLineEdit"/> + </item> + <item row="4" column="0" colspan="2"> + <widget class="QLineEdit" name="imageLineEdit"/> + </item> + <item row="5" column="0"> + <widget class="QLineEdit" name="editorLineEdit"/> + </item> + <item row="5" column="1"> + <widget class="QLineEdit" name="editorArgLineEdit"/> + </item> + </layout> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QPushButton" name="browsePushButton"> + <property name="text"> + <string>Browse</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="poolPushButton"> + <property name="text"> + <string>Browse</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="styleSheetPushButton"> + <property name="text"> + <string>Browse</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="choosehttpPushButton"> + <property name="text"> + <string>Choose</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="imagePushButton"> + <property name="text"> + <string>Choose</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="editorPushButton"> + <property name="text"> + <string>Choose</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item row="4" column="0" colspan="3"> + <widget class="Line" name="Line1"> + <property name="frameShape"> + <enum>QFrame::HLine</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Sunken</enum> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="5" column="0" colspan="3"> + <layout class="QHBoxLayout"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>11</number> + </property> + <item> + <spacer> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="okPushButton"> + <property name="text"> + <string>OK</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="cancelPushButton"> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11"/> + <tabstops> + <tabstop>wordLineEdit3</tabstop> + <tabstop>smartCheckBox</tabstop> + <tabstop>wheelCheckBox</tabstop> + <tabstop>urlCheckBox</tabstop> + <tabstop>saveCheckBox</tabstop> + <tabstop>blinkCheckBox</tabstop> + <tabstop>warnCheckBox</tabstop> + <tabstop>aacheckBox</tabstop> + <tabstop>trayCheckBox</tabstop> + <tabstop>clearCheckBox</tabstop> + <tabstop>noneRadioButton</tabstop> + <tabstop>beepRadioButton</tabstop> + <tabstop>fileRadioButton</tabstop> + <tabstop>selectsoundPushButton</tabstop> + <tabstop>wavefileLineEdit</tabstop> + <tabstop>ximComboBox</tabstop> + <tabstop>zmodemLineEdit</tabstop> + <tabstop>browsePushButton</tabstop> + <tabstop>poolLineEdit</tabstop> + <tabstop>poolPushButton</tabstop> + <tabstop>httpLineEdit</tabstop> + <tabstop>choosehttpPushButton</tabstop> + <tabstop>imageLineEdit</tabstop> + <tabstop>imagePushButton</tabstop> + <tabstop>okPushButton</tabstop> + <tabstop>cancelPushButton</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>noneRadioButton</sender> + <signal>toggled(bool)</signal> + <receiver>wavefileLineEdit</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>290</x> + <y>95</y> + </hint> + <hint type="destinationlabel"> + <x>290</x> + <y>125</y> + </hint> + </hints> + </connection> + <connection> + <sender>noneRadioButton</sender> + <signal>toggled(bool)</signal> + <receiver>selectsoundPushButton</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>360</x> + <y>80</y> + </hint> + <hint type="destinationlabel"> + <x>420</x> + <y>120</y> + </hint> + </hints> + </connection> + <connection> + <sender>beepRadioButton</sender> + <signal>toggled(bool)</signal> + <receiver>wavefileLineEdit</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>393</x> + <y>90</y> + </hint> + <hint type="destinationlabel"> + <x>366</x> + <y>129</y> + </hint> + </hints> + </connection> + <connection> + <sender>beepRadioButton</sender> + <signal>toggled(bool)</signal> + <receiver>selectsoundPushButton</receiver> + <slot>setDisabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>413</x> + <y>92</y> + </hint> + <hint type="destinationlabel"> + <x>449</x> + <y>125</y> + </hint> + </hints> + </connection> + <connection> + <sender>fileRadioButton</sender> + <signal>toggled(bool)</signal> + <receiver>wavefileLineEdit</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>467</x> + <y>97</y> + </hint> + <hint type="destinationlabel"> + <x>380</x> + <y>126</y> + </hint> + </hints> + </connection> + <connection> + <sender>fileRadioButton</sender> + <signal>toggled(bool)</signal> + <receiver>selectsoundPushButton</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>502</x> + <y>86</y> + </hint> + <hint type="destinationlabel"> + <x>493</x> + <y>128</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/ui/progressBar.cpp b/src/ui/progressBar.cpp new file mode 100644 index 0000000..9da0479 --- /dev/null +++ b/src/ui/progressBar.cpp @@ -0,0 +1,100 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include <QLabel> +#include <QPixmap> +#include <QProgressBar> +#include <QPushButton> + +#include "fqterm_trace.h" +#include "fqterm_path.h" +#include "progressBar.h" + +namespace FQTerm { + +ProgressBar::ProgressBar(QWidget *parent, QLabel *label) + : QProgressBar(parent), + label_(label), + isFinished_(false) { + //DEBUG_FUNC_INFO + setMaximum(100); + label_->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + abortButton_ = new QPushButton("Abort", parent); + abortButton_->setObjectName("Abort"); + abortButton_->hide(); + //m_abort->setText( tr("Abort") ); + abortButton_->setIcon(QPixmap(getPath(RESOURCE) + "pic/messagebox_critical.png")); + label_->show(); + show(); +} + +ProgressBar::~ProgressBar() { + //DEBUG_FUNC_INFO +} + +ProgressBar &ProgressBar::setDescription(const QString &text) { + description_ = text; + label_->setText(text); + + return *this; +} + +ProgressBar &ProgressBar::setStatus(const QString &text) { + QString s = description_; + s += " ["; + s += text; + s += ']'; + + label_->setText(s); + parentWidget()->adjustSize(); + + return *this; +} + +ProgressBar &ProgressBar::setAbortSlot(QObject *receiver, const char *slot) { + FQ_VERIFY(connect(abortButton_, SIGNAL(clicked()), receiver, slot)); + FQ_VERIFY(connect(abortButton_, SIGNAL(clicked()), this, SLOT(hide()))); + abortButton_->show(); + + parentWidget()->adjustSize(); + + return *this; +} + +void ProgressBar::setDone() { + if (!isFinished_) { + isFinished_ = true; + abortButton_->setEnabled(false); + setStatus(tr("Done")); + } else { + // then we we're aborted + setStatus(tr("Aborted")); + } +} + +void ProgressBar::hide() { + //NOTE naughty + + isFinished_ = true; + abortButton_->setEnabled(false); + setStatus(tr("Aborting...")); +} + +} // namespace FQTerm diff --git a/src/ui/progressBar.h b/src/ui/progressBar.h new file mode 100644 index 0000000..9c2f539 --- /dev/null +++ b/src/ui/progressBar.h @@ -0,0 +1,71 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +//WARNING this is not meant for use outside this unit! + +#ifndef FQTERM_PROGRESSBAR_H +#define FQTERM_PROGRESSBAR_H + +#include <QProgressBar> +#include <QLabel> + +class QLabel; +class QPushButton; + +namespace FQTerm { +/** + * @class KDE::ProgressBar + * @short ProgressBar class with some useful additions + */ +class ProgressBar: public QProgressBar { + friend class StatusBar; + + public: + /** @param text a 1-6 word description of the progress operation */ + ProgressBar &setDescription(const QString &text); + + /** @param text eg. Scanning, Reading. The state of the operation */ + ProgressBar &setStatus(const QString &text); + + /** set the recipient slot for the abort button */ + ProgressBar &setAbortSlot(QObject *receiver, const char *slot); + + void setDone(); + + QString description()const { + return description_; + } + + protected: + ProgressBar(QWidget *parent, QLabel *label); + ~ProgressBar(); + + virtual void hide(); + + QLabel *label_; + QString description_; + bool isFinished_; + + QPushButton *abortButton_; +}; + +} // namespace FQTerm + +#endif // FQTERM_PROGRESSBAR_H diff --git a/src/ui/quickdialog.cpp b/src/ui/quickdialog.cpp new file mode 100644 index 0000000..1ac3888 --- /dev/null +++ b/src/ui/quickdialog.cpp @@ -0,0 +1,258 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include <stdio.h> + +#include <QCloseEvent> +#include <QComboBox> +#include <QPixmap> +#include <QImage> +#include <QPixmap> +#include <QMessageBox> + +#include "fqterm_trace.h" +#include "fqterm_path.h" +#include "fqterm_config.h" +#include "fqterm_param.h" +#include "addrdialog.h" +#include "quickdialog.h" + +namespace FQTerm { + +//extern QString fileCfg; +//extern QString addrCfg; + +extern void saveAddress(FQTermConfig *, int, const FQTermParam &); + +const int quickDialog::ports[3] = {23, 22, 22}; + +quickDialog::quickDialog(FQTermConfig * config, QWidget *parent, Qt::WFlags fl) + : QDialog(parent, fl), + config_(config) { + ui_.setupUi(this); + + ui_.addPushButton->setIcon(QPixmap(getPath(RESOURCE) + "pic/address_book.png")); + + ui_.addPushButton->setToolTip(tr("Add To AddressBook")); + + ui_.connectPushButton->setDefault(true); + + connectSlots(); + + loadHistory(); + +// adjustSize(); +// setFixedSize(size()); + +} + +quickDialog::~quickDialog() { +} + +void quickDialog::closeEvent(QCloseEvent*) { + config_->save(getPath(USER_CONFIG) + "fqterm.cfg"); + reject(); +} + +void quickDialog::loadHistory() { + QString defaultIndex = config_->getItemValue("global", "quickdefaultindex"); + if (defaultIndex.isEmpty()) { + config_->setItemValue("global", "quick default index", "0"); + defaultIndex = "0"; + } + QString strTmp = config_->getItemValue("quick list", "num"); + QString strSection; + for (int i = 0; i < strTmp.toInt(); i++) { + strSection = QString("quick %1").arg(i); + ui_.historyComboBox->addItem(config_->getItemValue(strSection.toLatin1(), "addr")); + } + + int index = defaultIndex.toInt(); + if (strTmp.toInt() > index) { + ui_.historyComboBox->setCurrentIndex(index); + listChanged(index); + } +} + +void quickDialog::connectSlots() { + FQ_VERIFY(connect(ui_.historyComboBox, SIGNAL(activated(int)), this, SLOT(listChanged(int)))); + FQ_VERIFY(connect(ui_.protocolComboBox, SIGNAL(activated(int)), this, SLOT(onSelectProtocol(int)))); + FQ_VERIFY(connect(ui_.addPushButton, SIGNAL(clicked()), this, SLOT(onAdd()))); + FQ_VERIFY(connect(ui_.deletePushButton, SIGNAL(clicked()), this, SLOT(onDelete()))); + FQ_VERIFY(connect(ui_.advPushButton, SIGNAL(clicked()), this, SLOT(onAdvance()))); + FQ_VERIFY(connect(ui_.connectPushButton, SIGNAL(clicked()), this, SLOT(onConnect()))); + FQ_VERIFY(connect(ui_.closePushButton, SIGNAL(clicked()), this, SLOT(onClose()))); +} + +void quickDialog::listChanged(int index) { + QString strTmp = config_->getItemValue("quick list", "num"); + if (strTmp == "0") { + return ; + } + loadParam(index); + setUIFromParam(); +} + +void quickDialog::onAdd() { + setParamFromUI(); + + FQTermConfig *pAddrConf = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg"); + QString strTmp; + strTmp = pAddrConf->getItemValue("bbs list", "num"); + int num = strTmp.toInt(); + strTmp.setNum(num + 1); + pAddrConf->setItemValue("bbs list", "num", strTmp); + saveAddress(pAddrConf, num, param_); + pAddrConf->save(getPath(USER_CONFIG) + "address.cfg"); +} + +void quickDialog::onDelete() { + int index = ui_.historyComboBox->currentIndex(); + + QString strTmp = config_->getItemValue("quick list", "num"); + int num = strTmp.toInt(); + + if (num != 0 && index != -1) { + QString strSection = QString("quick %1").arg(index); + if (!config_->deleteSection(strSection.toLatin1())) { + return ; + } + ui_.historyComboBox->removeItem(index); + + for (int i = index + 1; i < num; i++) { + strTmp = QString("quick %1").arg(i); + strSection = QString("quick %1").arg(i - 1); + config_->renameSection(strTmp.toLatin1(), strSection.toLatin1()); + } + + strTmp = config_->getItemValue("quick list", "num"); + strTmp.setNum(qMax(0, strTmp.toInt() - 1)); + config_->setItemValue("quick list", "num", strTmp.toLatin1()); + + // update + if (num > 1) { + ui_.historyComboBox->setCurrentIndex(qMin(index, num - 2)); + listChanged(qMin(index, num - 2)); + } + } +} + +void quickDialog::onAdvance() { + setParamFromUI(); + + addrDialog set(this, param_, addrDialog::APPLY); + + if (set.exec() == 1) { + param_ = set.param(); + setUIFromParam(); + } +} + +void quickDialog::onConnect() { + if (ui_.historyComboBox->currentText().isEmpty() || ui_.portEdit->text().isEmpty()) { + QMessageBox mb("FQTerm", "address or port cant be blank", QMessageBox::Warning, + QMessageBox::Ok | QMessageBox::Default, 0, 0); + mb.exec(); + return ; + } + + setParamFromUI(); + FQTermParam newParam = param_; + loadParam(ui_.historyComboBox->currentIndex()); + + QString strTmp = config_->getItemValue("quick list", "num"); + if (strTmp.isEmpty() || strTmp == "-1") { + strTmp = "0"; + } + int num = strTmp.toInt(); + if (ui_.historyComboBox->currentIndex() == -1 || + newParam.hostAddress_ != param_.hostAddress_ || + newParam.protocolType_ != param_.protocolType_ || + newParam.port_ != param_.port_) { + //changed. add new info + param_ = newParam; + saveParam(num); + ui_.historyComboBox->addItem(param_.hostAddress_); + ui_.historyComboBox->setCurrentIndex(num); + config_->setItemValue("quick list", "num", QString("%1").arg(num + 1)); + } else { + param_ = newParam; + } + + config_->setItemValue("global", "quickdefaultindex", + QString("%1").arg(ui_.historyComboBox->currentIndex())); + done(1); +} + +void quickDialog::onClose() { + done(0); +} + +void quickDialog::onSelectProtocol(int index) +{ + ui_.portCheck->setChecked(false); + ui_.portEdit->setText(QString("%1").arg(ports[index])); +} + +void quickDialog::setUIFromParam() +{ + ui_.historyComboBox->setItemText(ui_.historyComboBox->currentIndex(), param_.hostAddress_); + ui_.protocolComboBox->setCurrentIndex(param_.protocolType_); + ui_.portEdit->setText(QString("%1").arg(param_.port_)); + if (param_.port_ != ports[param_.protocolType_]) { + ui_.portCheck->setChecked(true); + } + else { + ui_.portCheck->setChecked(false); + } +} + +void quickDialog::setParamFromUI() +{ + param_.name_ = ui_.historyComboBox->currentText(); + param_.hostAddress_ = ui_.historyComboBox->currentText(); + param_.protocolType_ = ui_.protocolComboBox->currentIndex(); + bool ok; + param_.port_ = ui_.portEdit->text().toInt(&ok); + if (!ok) { + param_.port_ = ports[param_.protocolType_]; + } +} + +void quickDialog::loadParam(int index) +{ + param_ = FQTermParam(); + QString strSection = QString("quick %1").arg(index); + param_.name_ = config_->getItemValue(strSection, "addr"); + param_.hostAddress_ = param_.name_; + param_.protocolType_ = config_->getItemValue(strSection, "protocol").toInt(); + param_.port_ = config_->getItemValue(strSection, "port").toInt(); +} + +void quickDialog::saveParam(int index) +{ + QString strSection = QString("quick %1").arg(index); + config_->setItemValue(strSection, "addr", param_.hostAddress_); + config_->setItemValue(strSection, "protocol", QString("%1").arg(param_.protocolType_)); + config_->setItemValue(strSection, "port", QString("%1").arg(param_.port_)); +} +} // namespace FQTerm + +#include "quickdialog.moc" diff --git a/src/ui/quickdialog.h b/src/ui/quickdialog.h new file mode 100644 index 0000000..bbcae89 --- /dev/null +++ b/src/ui/quickdialog.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef FQTERM_QUICK_DIALOG_H +#define FQTERM_QUICK_DIALOG_H + +#include "fqterm_param.h" +#include "ui_quickdialog.h" +//Added by qt3to4: +//#include <QCloseEvent> + +class QCloseEvent; +class QResizeEvent; + +namespace FQTerm { + +class FQTermConfig; + +class quickDialog: public QDialog { + Q_OBJECT; + public: + quickDialog(FQTermConfig *, QWidget *parent_ = 0, Qt::WFlags fl = 0); + ~quickDialog(); + + FQTermParam param_; + + static const int ports[3]; + + protected slots: + void listChanged(int); // + void onAdd(); + void onDelete(); + void onAdvance(); + void onConnect(); // + void onClose(); + void onSelectProtocol(int index); + + private: + + void closeEvent(QCloseEvent*); // + void connectSlots(); + void loadHistory(); // + void setUIFromParam(); + void setParamFromUI(); + void loadParam(int index); + void saveParam(int index); + + FQTermConfig *config_; + + private: + Ui::quickDialog ui_; +}; + +} // namespace FQTerm + +#endif // FQTERM_QUICK_DIALOG_H diff --git a/src/ui/quickdialog.ui b/src/ui/quickdialog.ui new file mode 100644 index 0000000..867596d --- /dev/null +++ b/src/ui/quickdialog.ui @@ -0,0 +1,211 @@ +<ui version="4.0" > + <class>quickDialog</class> + <widget class="QDialog" name="quickDialog" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>394</width> + <height>117</height> + </rect> + </property> + <property name="sizePolicy" > + <sizepolicy vsizetype="Expanding" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="windowTitle" > + <string>Quick Login</string> + </property> + <layout class="QGridLayout" > + <item row="0" column="0" > + <layout class="QHBoxLayout" > + <item> + <widget class="QLabel" name="TextLabel4" > + <property name="frameShape" > + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow" > + <enum>QFrame::Plain</enum> + </property> + <property name="text" > + <string>Host Name</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="historyComboBox" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="editable" > + <bool>true</bool> + </property> + <property name="insertPolicy" > + <enum>QComboBox::NoInsert</enum> + </property> + <property name="duplicatesEnabled" > + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="deletePushButton" > + <property name="text" > + <string>Delete</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="addPushButton" > + <property name="text" > + <string/> + </property> + <property name="icon" > + <iconset> + <normaloff/> + </iconset> + </property> + </widget> + </item> + </layout> + </item> + <item row="2" column="0" > + <widget class="Line" name="line" > + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="3" column="0" > + <layout class="QHBoxLayout" > + <item> + <widget class="QPushButton" name="advPushButton" > + <property name="text" > + <string>Advanced</string> + </property> + </widget> + </item> + <item> + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="connectPushButton" > + <property name="text" > + <string>Connect</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="closePushButton" > + <property name="text" > + <string>Close</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="1" column="0" > + <layout class="QHBoxLayout" > + <item> + <widget class="QLabel" name="TextLabel6" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Preferred" hsizetype="Minimum" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string>Protocol</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="protocolComboBox" > + <item> + <property name="text" > + <string>Telnet</string> + </property> + </item> + <item> + <property name="text" > + <string>SSH1</string> + </property> + </item> + <item> + <property name="text" > + <string>SSH2</string> + </property> + </item> + </widget> + </item> + <item> + <widget class="QCheckBox" name="portCheck" > + <property name="text" > + <string>Port</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="portEdit" > + <property name="enabled" > + <bool>false</bool> + </property> + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Maximum" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string>23</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11" /> + <tabstops> + <tabstop>historyComboBox</tabstop> + <tabstop>deletePushButton</tabstop> + <tabstop>addPushButton</tabstop> + <tabstop>advPushButton</tabstop> + <tabstop>connectPushButton</tabstop> + <tabstop>closePushButton</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>portCheck</sender> + <signal>toggled(bool)</signal> + <receiver>portEdit</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>151</x> + <y>54</y> + </hint> + <hint type="destinationlabel" > + <x>203</x> + <y>54</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/ui/schemadialog.cpp b/src/ui/schemadialog.cpp new file mode 100644 index 0000000..d5a197b --- /dev/null +++ b/src/ui/schemadialog.cpp @@ -0,0 +1,323 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include <QFileDialog> +#include <QColorDialog> +#include <QComboBox> +#include <QMessageBox> + +#include "fqterm_config.h" +#include "fqterm_path.h" +#include "fqterm_trace.h" + +#include "schemadialog.h" + +namespace FQTerm { + +schemaDialog::schemaDialog(QWidget *parent, Qt::WFlags fl) + : QDialog(parent, fl), + buttonGroup_(this) { + ui_.setupUi(this); + buttonGroup_.addButton(ui_.noneRadioButton, 0); + buttonGroup_.addButton(ui_.imageRadioButton, 1); + + lastItemID_ = -1; + isModified_ = false; + + ui_.alphaSlider->setMinimum(0); + ui_.alphaSlider->setMaximum(100); + ui_.alphaSlider->setSingleStep(1); + ui_.alphaSlider->setPageStep(10); + + // ui.bgButtonGroup->setRadioButtonExclusive(true); + colorButtons[0] = ui_.clr0Button; + colorButtons[1] = ui_.clr1Button; + colorButtons[2] = ui_.clr2Button; + colorButtons[3] = ui_.clr3Button; + colorButtons[4] = ui_.clr4Button; + colorButtons[5] = ui_.clr5Button; + colorButtons[6] = ui_.clr6Button; + colorButtons[7] = ui_.clr7Button; + colorButtons[8] = ui_.clr8Button; + colorButtons[9] = ui_.clr9Button; + colorButtons[10] = ui_.clr10Button; + colorButtons[11] = ui_.clr11Button; + colorButtons[12] = ui_.clr12Button; + colorButtons[13] = ui_.clr13Button; + colorButtons[14] = ui_.clr14Button; + colorButtons[15] = ui_.clr15Button; + + connectSlots(); + loadList(); +} + + +schemaDialog::~schemaDialog(){} + + +void schemaDialog::connectSlots() { + FQ_VERIFY(connect(ui_.saveButton, SIGNAL(clicked()), this, SLOT(saveSchema()))); + FQ_VERIFY(connect(ui_.removeButton, SIGNAL(clicked()), this, SLOT(removeSchema()))); + FQ_VERIFY(connect(ui_.okButton, SIGNAL(clicked()), this, SLOT(onOK()))); + FQ_VERIFY(connect(ui_.cancelButton, SIGNAL(clicked()), this, SLOT(onCancel()))); + + for (int i = 0; i < 16; ++i) { + FQ_VERIFY(connect(colorButtons[i], SIGNAL(clicked()), this, SLOT(buttonClicked()))); + } + + FQ_VERIFY(connect(ui_.nameListWidget, SIGNAL(currentRowChanged(int)), + this, SLOT(nameChanged(int)))); + + + FQ_VERIFY(connect(ui_.chooseButton, SIGNAL(clicked()), + this, SLOT(chooseImage()))); + + FQ_VERIFY(connect(ui_.titleLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(modified(const QString &)))); + FQ_VERIFY(connect(ui_.imageLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(modified(const QString &)))); + FQ_VERIFY(connect(ui_.alphaSlider, SIGNAL(valueChanged(int)), + this, SLOT(modified(int)))); + FQ_VERIFY(connect(ui_.optionComboBox, SIGNAL(activated(int)), + this, SLOT(modified(int)))); + FQ_VERIFY(connect(ui_.coverComboBox, SIGNAL(activated(int)), + this, SLOT(modified(int)))); + FQ_VERIFY(connect(ui_.noneRadioButton, SIGNAL(toggled(bool)), + this, SLOT(modified(bool)))); + FQ_VERIFY(connect(ui_.imageRadioButton, SIGNAL(toggled(bool)), + this, SLOT(modified(bool)))); + FQ_VERIFY(connect(ui_.alphaCheckBox, SIGNAL(toggled(bool)), + this, SLOT(modified(bool)))); +} + +void schemaDialog::loadList() { + QFileInfoList lstFile = getSchemaList(); + + //if(lstFile != NULL) + { + foreach(QFileInfo fi, lstFile) { + FQTermConfig *pConf = new FQTermConfig(fi.absoluteFilePath()); + QListWidgetItem* item = new QListWidgetItem(pConf->getItemValue("schema", "title"), ui_.nameListWidget); + item->setData(Qt::UserRole, fi.absoluteFilePath()); + ui_.nameListWidget->addItem(item); + delete pConf; + } + } + if (ui_.nameListWidget->count() != 0) { + ui_.nameListWidget->setCurrentRow(0); + } +} + +void schemaDialog::loadSchema(const QString &strSchemaFile) { + FQTermConfig *pConf = new FQTermConfig(strSchemaFile); + + title_ = pConf->getItemValue("schema", "title"); + //0 -- none 1 -- image + int type = pConf->getItemValue("background", "type").toInt(); + if (type == 0) { + ui_.noneRadioButton->setChecked(true); + } else if (type == 1) { + ui_.imageRadioButton->setChecked(true); + } + ui_.imageLineEdit->setText(pConf->getItemValue("image", "name")); + QString strTmp = pConf->getItemValue("image", "render"); + ui_.optionComboBox->setCurrentIndex(strTmp.toInt()); + strTmp = pConf->getItemValue("image", "cover"); + ui_.coverComboBox->setCurrentIndex(strTmp.toInt()); + ui_.alphaCheckBox->setChecked(pConf->getItemValue("image", "usealpha").toInt()); + ui_.alphaSlider->setValue(pConf->getItemValue("image", "alpha").toInt()); + + for (int i = 0; i < 16; ++i) { + colors[i].setNamedColor(pConf->getItemValue("color", QString("color%1").arg(i))); + } + + delete pConf; + + updateView(); + +} + +QFileInfoList schemaDialog::getSchemaList() { + QDir dir; + dir.setNameFilters(QStringList("*.schema")); + dir.setPath(getPath(USER_CONFIG) + "schema"); + return dir.entryInfoList(); +} + +int schemaDialog::saveNumSchema(int n) { + + int saved = n; + title_ = ui_.titleLineEdit->text(); + + QString schemaFileName = getPath(USER_CONFIG) + "schema/" + title_ + ".schema"; + QListWidgetItem* item = ui_.nameListWidget->currentItem(); + // create a new schema if title changed + QString test = ui_.nameListWidget->currentItem()->data(Qt::UserRole).toString(); + if (QFileInfo(schemaFileName) != QFileInfo(ui_.nameListWidget->item(n)->data(Qt::UserRole).toString())) { + item = new QListWidgetItem(title_, ui_.nameListWidget); + item->setData(Qt::UserRole, schemaFileName); + ui_.nameListWidget->addItem(item); + saved = ui_.nameListWidget->row(item); + } + + FQTermConfig *pConf = new FQTermConfig(ui_.nameListWidget->item(n)->data(Qt::UserRole).toString()); + + pConf->setItemValue("schema", "title", title_); + + QString strTmp; + //0 -- none 1 -- image + int type = 0; + + if (ui_.noneRadioButton->isChecked()) { + type = 0; + } else if (ui_.imageRadioButton->isChecked()) { + type = 1; + } + strTmp.setNum(type); + pConf->setItemValue("background", "type", strTmp); + + pConf->setItemValue("image", "name", ui_.imageLineEdit->text()); + + + strTmp.setNum(ui_.optionComboBox->currentIndex()); + pConf->setItemValue("image", "render", strTmp); + + strTmp.setNum(ui_.coverComboBox->currentIndex()); + pConf->setItemValue("image", "cover", strTmp); + + pConf->setItemValue("image", "usealpha", ui_.alphaCheckBox->isChecked() ? "1" : "0"); + + strTmp.setNum(ui_.alphaSlider->value()); + pConf->setItemValue("image", "alpha", strTmp); + + + for (int i = 0; i < 16; ++i) { + pConf->setItemValue("color", QString("color%1").arg(i), colors[i].name()); + } + + pConf->save(schemaFileName); + + delete pConf; + + clearModified(); + emit schemaEdited(); + return saved; +} + +void schemaDialog::updateView() { + // title + ui_.titleLineEdit->setText(title_); + for (int i = 0; i < 16; ++i) { + QPalette palette; + palette.setColor(QPalette::Button, colors[i]); + colorButtons[i]->setPalette(palette); + } + + // load from file, nothing changed + clearModified(); +} + +void schemaDialog::buttonClicked() { + QPushButton *button = (QPushButton*)sender(); + QColor color = + QColorDialog::getColor(button->palette().color(button->backgroundRole())); + if (color.isValid() == true) { + QPalette palette; + palette.setColor(QPalette::Button, color); + button->setPalette(palette); + modified(); + } + for (int i = 0; i < 16; ++i) { + if (colorButtons[i] == button) { + colors[i] = color; + break; + } + } +} + +void schemaDialog::nameChanged(int item) { + if (isModified_) { + QMessageBox mb("FQTerm", "Setting changed, do you want to save?", + QMessageBox::Warning, QMessageBox::Yes | QMessageBox::Default, + QMessageBox::No | QMessageBox::Escape, 0, this); + if (mb.exec() == QMessageBox::Yes) { + if (lastItemID_ != -1) { + saveNumSchema(lastItemID_); + } + } + } + + int n = item; //nameListBox->index(item); + lastItemID_ = n; + + + loadSchema(ui_.nameListWidget->item(n)->data(Qt::UserRole).toString()); + updateView(); + ui_.nameListWidget->setCurrentRow(n, QItemSelectionModel::Select); +} + + +void schemaDialog::chooseImage() { + QString img = QFileDialog::getOpenFileName( + this, "Choose an image", QDir::currentPath()); + if (!img.isNull()) { + ui_.imageLineEdit->setText(img); + isModified_ = true; + } +} + + + +void schemaDialog::saveSchema() { + // get current schema file name + int n = ui_.nameListWidget->currentRow(); + int saved = saveNumSchema(n); + lastItemID_ = saved; + ui_.nameListWidget->setCurrentRow(saved, QItemSelectionModel::Select); +} + +void schemaDialog::removeSchema() { + QFileInfo fi(ui_.nameListWidget->currentItem()->data(Qt::UserRole).toString()); + if (fi.isWritable()) { + QFile::remove(ui_.nameListWidget->currentItem()->data(Qt::UserRole).toString()); + int n = ui_.nameListWidget->currentRow(); + delete ui_.nameListWidget->takeItem(n); + emit schemaEdited(); + } else { + QMessageBox::warning(this, "Error", + "This is a system schema. Permission Denied"); + } +} + +void schemaDialog::onOK() { + saveSchema(); + done(1); +} + +void schemaDialog::onCancel() { + done(0); +} + + + + +} // namespace FQTerm + +#include "schemadialog.moc" diff --git a/src/ui/schemadialog.h b/src/ui/schemadialog.h new file mode 100644 index 0000000..c2ef977 --- /dev/null +++ b/src/ui/schemadialog.h @@ -0,0 +1,80 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef FQTERM_SCHEMADIALOG_H +#define FQTERM_SCHEMADIALOG_H + +#include "ui_schemadialog.h" +#include <QStringList> +namespace FQTerm { + +class schemaDialog: public QDialog { + Q_OBJECT; + public: + schemaDialog(QWidget *parent = 0, Qt::WFlags fl = 0); + ~schemaDialog(); + + static QFileInfoList getSchemaList(); + protected: + QColor colors[16]; + QPushButton * colorButtons[16]; + QString title_; + QStringList fileList_; + + bool isModified_; + int lastItemID_; + private: + Ui::schemaDialog ui_; + QButtonGroup buttonGroup_; + + protected: + void connectSlots(); + + void loadList(); + void loadSchema(const QString &schemaFileName); + int saveNumSchema(int n = -1); + + void updateView(); + + protected slots: + void buttonClicked(); + void nameChanged(int); + void chooseImage(); + + void saveSchema(); + void removeSchema(); + + void onOK(); + void onCancel(); + + void modified(const QString&) {modified();} + void modified(int) {modified();} + void modified(bool) {modified();} + void modified() {isModified_ = true;} + + void clearModified() {isModified_ = false;} + +signals: + void schemaEdited(); +}; + +} // namespace FQTerm + +#endif // FQTERM_SCHEMADIALOG_H diff --git a/src/ui/schemadialog.ui b/src/ui/schemadialog.ui new file mode 100644 index 0000000..0d987bb --- /dev/null +++ b/src/ui/schemadialog.ui @@ -0,0 +1,539 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>schemaDialog</class> + <widget class="QDialog" name="schemaDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>612</width> + <height>334</height> + </rect> + </property> + <property name="windowTitle"> + <string>Schema Editor</string> + </property> + <layout class="QGridLayout"> + <item row="0" column="0"> + <layout class="QGridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="textLabel1_2"> + <property name="text"> + <string>Title</string> + </property> + </widget> + </item> + <item row="0" column="1" colspan="8"> + <widget class="QLineEdit" name="titleLineEdit"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="textLabel1"> + <property name="text"> + <string>0-7</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QPushButton" name="clr0Button"> + <property name="cursor"> + <cursorShape>PointingHandCursor</cursorShape> + </property> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QPushButton" name="clr1Button"> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="iconSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="3"> + <widget class="QPushButton" name="clr2Button"> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="iconSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="4"> + <widget class="QPushButton" name="clr3Button"> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="iconSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="5"> + <widget class="QPushButton" name="clr4Button"> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="iconSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="6"> + <widget class="QPushButton" name="clr5Button"> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="iconSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="7"> + <widget class="QPushButton" name="clr6Button"> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="iconSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="8"> + <widget class="QPushButton" name="clr7Button"> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="iconSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="textLabel2"> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> + </property> + <property name="text"> + <string>8-15</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QPushButton" name="clr8Button"> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="iconSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QPushButton" name="clr9Button"> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="iconSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="2" column="3"> + <widget class="QPushButton" name="clr10Button"> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="iconSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="2" column="4"> + <widget class="QPushButton" name="clr11Button"> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="iconSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="2" column="5"> + <widget class="QPushButton" name="clr12Button"> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="iconSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="2" column="6"> + <widget class="QPushButton" name="clr13Button"> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="iconSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="2" column="7"> + <widget class="QPushButton" name="clr14Button"> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="iconSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="2" column="8"> + <widget class="QPushButton" name="clr15Button"> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="iconSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="3" column="1" colspan="8"> + <widget class="QListWidget" name="nameListWidget"/> + </item> + <item row="4" column="1" colspan="8"> + <layout class="QHBoxLayout"> + <item> + <widget class="QPushButton" name="saveButton"> + <property name="text"> + <string>Save</string> + </property> + </widget> + </item> + <item> + <spacer> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="removeButton"> + <property name="text"> + <string>Remove </string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item row="1" column="1"> + <layout class="QHBoxLayout"> + <item> + <widget class="QPushButton" name="okButton"> + <property name="text"> + <string>OK</string> + </property> + </widget> + </item> + <item> + <spacer> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="cancelButton"> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="0" column="1"> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Background</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <widget class="QRadioButton" name="noneRadioButton"> + <property name="text"> + <string>None</string> + </property> + </widget> + </item> + <item row="1" column="0" colspan="3"> + <layout class="QGridLayout" name="gridLayout"> + <item row="1" column="0"> + <widget class="QLineEdit" name="imageLineEdit"/> + </item> + <item row="1" column="1"> + <widget class="QPushButton" name="chooseButton"> + <property name="text"> + <string>Choose</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QRadioButton" name="imageRadioButton"> + <property name="text"> + <string>Image</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QComboBox" name="optionComboBox"> + <item> + <property name="text"> + <string>Tile</string> + </property> + </item> + <item> + <property name="text"> + <string>Center</string> + </property> + </item> + <item> + <property name="text"> + <string>Scale</string> + </property> + </item> + </widget> + </item> + <item row="3" column="1"> + <widget class="QComboBox" name="coverComboBox"> + <item> + <property name="text"> + <string>Whole</string> + </property> + </item> + <item> + <property name="text"> + <string>Padding</string> + </property> + </item> + </widget> + </item> + <item row="4" column="1"> + <layout class="QHBoxLayout"> + <item> + <widget class="QLabel" name="TextLabel2"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Min</string> + </property> + </widget> + </item> + <item> + <widget class="QSlider" name="alphaSlider"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="TextLabel3"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Max</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="4" column="0"> + <widget class="QCheckBox" name="alphaCheckBox"> + <property name="text"> + <string>Alpha</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Render</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Coverage</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="3" column="1"> + <widget class="QLineEdit" name="ForAlignment"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>0</height> + </size> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QLineEdit" name="ForAlignment_2"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>0</height> + </size> + </property> + </widget> + </item> + <item row="4" column="0" colspan="3"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Note: + Alpha will only apply on background + If Coverage is set to Padding + Alpha will take no effect +</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections/> +</ui> diff --git a/src/ui/shortcutdialog.cpp b/src/ui/shortcutdialog.cpp new file mode 100644 index 0000000..0b73ab3 --- /dev/null +++ b/src/ui/shortcutdialog.cpp @@ -0,0 +1,176 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include "shortcutdialog.h" +#include "fqterm_shortcuthelper.h" + +#include <QTableWidget> +#include <QKeyEvent> +#include <QGridLayout> +#include <QPushButton> +#include <QHeaderView> +#include <QStringList> +#include <QScrollBar> +#include <QLabel> +#include <QSignalMapper> +namespace FQTerm +{ +FQTermShortcutDialog::FQTermShortcutDialog(FQTermShortcutHelper* helper, QWidget *parent_, Qt::WFlags fl) + : QDialog(parent_, fl), + helper_(helper), + table_(NULL) { + setWindowTitle(tr("Shortcut Setting")); + //grabKeyboard(); + if (helper_) + { + QSignalMapper* signalMapper = new QSignalMapper(this); + int row = FQTermShortcutHelper::FQTERM_APPLICATION_SHORTCUT_END - FQTermShortcutHelper::FQTERM_APPLICATION_SHORTCUT_START - 1; + int column = 3; + table_ = new QTableWidget(row, column, this); + table_->clear(); + QStringList header; + header << tr("Description") << tr("Shortcut") << ""; + table_->setHorizontalHeaderLabels(header); + for (int i = 0; i < row; ++i) { + for (int j = 0; j < column; ++j) { + if (j == 0) { + QTableWidgetItem* item = new QTableWidgetItem; + table_->setItem(i, j, item); + item->setFlags(item->flags() & ~Qt::ItemIsEditable); + item->setText(helper_->getShortcutDescription(i + 1)); + } else if (j == 1) { + FQTermShortcutTableWidget* stw = new FQTermShortcutTableWidget(table_); + stw->setReadOnly(true); + stw->setText(helper_->getShortcutText(i + 1)); + table_->setCellWidget(i, j, stw); + }else { + QPushButton* btn = new QPushButton(tr("default"), table_); + table_->setCellWidget(i, j, btn); + FQ_VERIFY(connect(btn, SIGNAL(clicked()), signalMapper, SLOT(map()))); + signalMapper->setMapping(btn, i); + } + } + } + table_->resizeColumnsToContents(); + int tableWidth = table_->horizontalHeader()->length(); + if (table_->horizontalScrollBar() && table_->horizontalScrollBar()->isVisible()) { + tableWidth += table_->horizontalScrollBar()->width(); + } + QPushButton* okBtn = new QPushButton(tr("OK"), this); + FQ_VERIFY(connect(okBtn, SIGNAL(clicked()), this, SLOT(okBtnClicked()))); + QPushButton* applyBtn = new QPushButton(tr("Apply"), this); + FQ_VERIFY(connect(applyBtn, SIGNAL(clicked()), this, SLOT(applyBtnClicked()))); + QPushButton* cancelBtn = new QPushButton(tr("Cancel"), this); + FQ_VERIFY(connect(cancelBtn, SIGNAL(clicked()), this, SLOT(cancelBtnClicked()))); + QPushButton* resetBtn = new QPushButton(tr("Reset All"), this); + FQ_VERIFY(connect(resetBtn, SIGNAL(clicked()), this, SLOT(resetBtnClicked()))); + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + QGridLayout* layout = new QGridLayout(this); + QLabel* label = new QLabel(tr("Press key/combines on Shortcut column.\nNote Del is reserved for clear shortcut setting.")); + layout->addWidget(label, 0, 0, 1, -1); + layout->addWidget(table_, 1, 0, 1, -1); + layout->addWidget(okBtn, 2, 0); + layout->addWidget(applyBtn, 2, 1); + layout->addWidget(cancelBtn, 2, 2); + layout->addWidget(resetBtn, 2, 3); + setLayout(layout); + int left = 0; + int right = 0; + layout->getContentsMargins(&left, NULL, &right, NULL); + table_->horizontalHeader()->setStretchLastSection(true); + tableWidth *= 1.1; + resize(tableWidth + left + right, height()); + FQ_VERIFY(connect(signalMapper, SIGNAL(mapped(int)),this, SLOT(defaultClicked(int)))); + } +} + +FQTermShortcutDialog::~FQTermShortcutDialog() { + //releaseKeyboard(); +} + +void FQTermShortcutDialog::defaultClicked(int row) { + ((QLineEdit*)table_->cellWidget(row, 1))->setText(helper_->getShortcutDefaultText(row + 1)); +} + +void FQTermShortcutDialog::okBtnClicked() { + applyChanges(); + done(true); +} + +void FQTermShortcutDialog::applyBtnClicked() { + applyChanges(); +} + +void FQTermShortcutDialog::cancelBtnClicked() { + done(false); +} + +void FQTermShortcutDialog::resetBtnClicked() { + int row = FQTermShortcutHelper::FQTERM_APPLICATION_SHORTCUT_END - FQTermShortcutHelper::FQTERM_APPLICATION_SHORTCUT_START - 1; + for (int i = 0; i < row; ++i) { + ((QLineEdit*)table_->cellWidget(i, 1))->setText(helper_->getShortcutDefaultText(i + 1)); + } +} + +void FQTermShortcutDialog::applyChanges() { + int row = FQTermShortcutHelper::FQTERM_APPLICATION_SHORTCUT_END - FQTermShortcutHelper::FQTERM_APPLICATION_SHORTCUT_START - 1; + for (int i = 0; i < row; ++i) { + helper_->setShortcutText(i + 1, ((QLineEdit*)table_->cellWidget(i, 1))->text()); + } +} + +void FQTermShortcutTableWidget::keyReleaseEvent(QKeyEvent * event) { + if (event) { + event->accept(); + } +} + +void FQTermShortcutTableWidget::keyPressEvent(QKeyEvent * event) { + if (event) { + event->accept(); + if (event == QKeySequence::Delete) { + setText(""); + } else { + //Thank you hooey. + int key = event->key(); + Qt::KeyboardModifiers mod = event->modifiers(); + + if (key == Qt::Key_Shift || + key == Qt::Key_Control || + key == Qt::Key_Meta || + key == Qt::Key_Alt || + key == Qt::Key_AltGr) + return; + QString text = ""; + if (mod != Qt::NoModifier) { + QKeySequence seqMod(mod); + text = seqMod.toString(QKeySequence::NativeText); + } + QKeySequence seqKey(key); + text += seqKey.toString(QKeySequence::NativeText); + setText(text); + } + } +} + +}//namespace FQTerm + + +#include "shortcutdialog.moc" diff --git a/src/ui/shortcutdialog.h b/src/ui/shortcutdialog.h new file mode 100644 index 0000000..d8fd109 --- /dev/null +++ b/src/ui/shortcutdialog.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef FQTERM_SHORTCUT_DIALOG_H +#define FQTERM_SHORTCUT_DIALOG_H +#include <QDialog> +#include <QLineEdit> +class QTableWidget; +namespace FQTerm +{ +class FQTermShortcutHelper; + +class FQTermShortcutTableWidget : public QLineEdit +{ +public: + FQTermShortcutTableWidget(QWidget* parent) : QLineEdit(parent) { + } +protected: + void keyReleaseEvent(QKeyEvent * event); + void keyPressEvent(QKeyEvent * event); +}; + +class FQTermShortcutDialog : public QDialog +{ + Q_OBJECT; +public: + FQTermShortcutDialog(FQTermShortcutHelper* helper, QWidget *parent_ = 0, Qt::WFlags fl = Qt::Dialog); + ~FQTermShortcutDialog(); +private: + FQTermShortcutHelper* helper_; + QTableWidget* table_; +protected slots: + void defaultClicked(int row); + void okBtnClicked(); + void applyBtnClicked(); + void cancelBtnClicked(); + void resetBtnClicked(); +private: + void applyChanges(); +}; +}//namespace FQTerm + + +#endif //FQTERM_SHORTCUT_DIALOG_H diff --git a/src/ui/sitemanager.cpp b/src/ui/sitemanager.cpp new file mode 100644 index 0000000..29f2ccd --- /dev/null +++ b/src/ui/sitemanager.cpp @@ -0,0 +1,412 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include <QTextCharFormat> +#include <QDialog> +#include <QIntValidator> +#include <QPainter> +#include <QResizeEvent> +#include <QPalette> +#include <QListWidgetItem> +#include <QMessageBox> + +#include "fqterm_config.h" +#include "fqterm_param.h" +#include "fqterm_param.h" +#include "fqterm_path.h" +#include "fqterm_trace.h" + +#include "sitemanager.h" + +namespace FQTerm{ + +int siteDialog::ports[] = {23, 22, 22, 0}; + +siteDialog::siteDialog(QWidget *parent_ /*= 0*/, Qt::WFlags fl /*= 0*/) + : QDialog(parent_, fl) { + ui_.setupUi(this); + + config_ = new FQTermConfig(getPath(USER_CONFIG) + "address.cfg"); + QStringList name_list; + loadNameList(config_, name_list); + ui_.siteList->addItems(name_list); + + if (ui_.siteList->count() != 0) { + setCurrentSite(0); + loadCurrentParam(); + setUIFromParam(); + } + else { + ui_.editGroup->setDisabled(true); + } + connector(); +} + +siteDialog::~siteDialog() { + config_->save(getPath(USER_CONFIG) + "address.cfg"); + delete config_; +} + +void siteDialog::onSelectProtocol(int index) { + ui_.portCheck->setChecked(false); + ui_.portEdit->setText(QString("%1").arg(ports[index])); +} + +void siteDialog::setParamFromUI() { + param_.name_ = ui_.nameEdit->text(); + param_.hostAddress_ = ui_.addrEdit->text(); + param_.protocolType_ = ui_.protocolCombo->currentIndex(); + bool ok; + int port = ui_.portEdit->text().toInt(&ok); + param_.port_ = (ok && port >= 0 && port <= 65535)?port:ports[ui_.protocolCombo->currentIndex()]; + param_.hostType_ = ui_.hostTypeCombo->currentIndex(); + if (!ui_.proxyCheck->isChecked()) { + param_.proxyType_ = 0; + } + param_.isAutoLogin_ = ui_.autoLoginCheck->isChecked(); +} + +//auto fix errors. +void siteDialog::setUIFromParam() { + ui_.nameEdit->setText(param_.name_); + ui_.addrEdit->setText(param_.hostAddress_); + ui_.protocolCombo->setCurrentIndex(param_.protocolType_); + ui_.portCheck->setCheckState(param_.port_ == ports[ui_.protocolCombo->currentIndex()]?Qt::Unchecked:Qt::Checked); + ui_.portEdit->setText(QString("%1").arg(param_.port_)); + ui_.hostTypeCombo->setCurrentIndex(param_.hostType_); + ui_.proxyCheck->setCheckState(param_.proxyType_?Qt::Checked:Qt::Unchecked); + ui_.autoLoginCheck->setCheckState(param_.isAutoLogin_?Qt::Checked:Qt::Unchecked); + + previewFont(); +} + +void siteDialog::loadCurrentParam() { + if (ui_.siteList->count() == 0) { + return; + } + loadAddress(config_, currentSiteIndex(), param_); +} + +void siteDialog::saveCurrentParam() { + if (ui_.siteList->count() == 0) { + return; + } + saveAddress(config_, currentSiteIndex(), param_); +} + +void siteDialog::previewFont() { + //issue 98 + + QPalette palette; + palette.setColor(QPalette::Window, param_.backgroundColor_); + palette.setColor(QPalette::WindowText, param_.foregroundColor_); + ui_.fontPreviewer->setPalette(palette); + + QString sample("<html><body style=\" font-family:'" + + param_.englishFontName_ + "'; font-size:" + + QString().setNum(param_.englishFontSize_) + + "pt;\"><BR>AaBbCc</body></html>"); + sample += QString("<html><body style=\" font-family:'" + + param_.otherFontName_ + "'; font-size:" + + QString().setNum(param_.otherFontSize_) + "pt;\">" + + param_.otherFontName_ + "<BR></body></html>"); + ui_.fontPreviewer->setText(sample); +} + +void siteDialog::swapSite(int first, int second) { + FQTermParam firstParam; + FQTermParam secondParam; + loadAddress(config_, first, firstParam); + loadAddress(config_, second, secondParam); + saveAddress(config_, first, secondParam); + saveAddress(config_, second, firstParam); + + QListWidgetItem* firstItem = ui_.siteList->item(first); + QListWidgetItem* secondItem = ui_.siteList->item(second); + QString tmpStr = firstItem->text(); + firstItem->setText(secondItem->text()); + secondItem->setText(tmpStr); +} + +int siteDialog::moveSite(int pos, int offset) +{ + int newPos = pos + offset; + int step = offset>0?1:-1; + if (newPos >= ui_.siteList->count() || newPos < 0) { + return pos; + } + for(int i = pos; i != newPos; i += step) { + swapSite(i , i + step); + } + return newPos; +} + +QMessageBox::StandardButton siteDialog::checkModification(int row) { //with current display + FQTermParam originParam; + loadAddress(config_, row, originParam); + setParamFromUI(); + QMessageBox::StandardButton ret = QMessageBox::No; + if (!(originParam == param_)) { + QMessageBox msgBox; + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle(tr("Warning")); + msgBox.setText(tr("The site configuration has been changed.\nTo save, press Yes.\nTo discard, press No.\nTo continue editing, press Cancel")); + + + switch(ret = static_cast<QMessageBox::StandardButton>(msgBox.exec())) { + case QMessageBox::No: + param_ = originParam; + break; + default: + break; + } + ui_.siteList->item(row)->setText(param_.name_); + } + return ret; +} + +void siteDialog::onSelectSite(QListWidgetItem* current, QListWidgetItem* previous) +{ + int currentRow = ui_.siteList->row(current); + int previousRow = ui_.siteList->row(previous); + if (currentRow < 0) { + ui_.editGroup->setDisabled(true); + } + else { + ui_.editGroup->setEnabled(true); + } + if (previousRow >= 0){ + if (checkModification(previousRow) == QMessageBox::Cancel) { + forcedSetCurrentSite(previousRow); + return; + } + saveAddress(config_, previousRow, param_); + } + if (currentRow >= 0){ + loadAddress(config_, currentRow, param_); + setUIFromParam(); + } + +} + +//without emit a signal +void siteDialog::forcedSetCurrentSite(int row) +{ + FQ_VERIFY(disconnect(ui_.siteList, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), + this, SLOT(onSelectSite(QListWidgetItem*, QListWidgetItem*)))); + ui_.siteList->setCurrentRow(row); + FQ_VERIFY(connect(ui_.siteList, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), + this, SLOT(onSelectSite(QListWidgetItem*, QListWidgetItem*)))); +} + +//emit a signal +void siteDialog::setCurrentSite(int row) +{ + ui_.siteList->setCurrentRow(row); +} + +void siteDialog::removeSite(int row) +{ + if (row < 0) { + return; + } + int last = ui_.siteList->count() - 1; + setCurrentSite(last - 1); + moveSite(row, last - row); + config_->deleteSection(QString("%1").arg(last)); + config_->setItemValue("bbs list", "num", QString("%1").arg(last)); + delete ui_.siteList->takeItem(last); + + loadCurrentParam(); + setUIFromParam(); +} + +void siteDialog::onNew() { + int row = ui_.siteList->count(); + if (row < 0) { + row = 0; + } + config_->setItemValue("bbs list", "num", QString("%1").arg(row + 1)); + + FQTermParam newParam; + loadAddress(config_, -1, newParam); + saveAddress(config_, row, newParam); + ui_.siteList->addItem(newParam.name_); + setCurrentSite(row); +} + +void siteDialog::onDelete() { + if (ui_.siteList->count() == 0) { + return; + } + QMessageBox msgBox; + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle(tr("Warning")); + msgBox.setText(tr("Are you sure to DELETE this site?")); + switch(msgBox.exec()) + { + case QMessageBox::Yes: + removeSite(currentSiteIndex()); + break; + case QMessageBox::No: + break; + } +} + +void siteDialog::siteNameChanged( QString name ) { + QListWidgetItem* item = ui_.siteList->currentItem(); + if (item) { + item->setText(name); + } +} + +void siteDialog::setSiteSelected() { + int row = currentSiteIndex(); + if(row >= 0) { + ui_.siteList->item(row)->setSelected(true); + } +} + +void siteDialog::close(int doneValue) { + if (ui_.siteList->count() > 0) { + switch(checkModification(currentSiteIndex())) { + case QMessageBox::Yes: + onApply(); + break; + case QMessageBox::No: + loadCurrentParam(); + break; + case QMessageBox::Cancel: + return; + default: + break; + } + } + done(doneValue); +} + +void siteDialog::onReset() { + loadCurrentParam(); + setUIFromParam(); +} + +void siteDialog::onApply() { + setParamFromUI(); + saveCurrentParam(); + setUIFromParam(); +} + +void siteDialog::onUp() { + int newPos = moveSite(currentSiteIndex(), -1); + forcedSetCurrentSite(newPos); +} + +void siteDialog::onDown() { + int newPos = moveSite(currentSiteIndex(), 1); + forcedSetCurrentSite(newPos); +} + +void siteDialog::onClose() { + close(0); +} + +void siteDialog::onConnect() { + close(1); +} + +void siteDialog::resizeEvent( QResizeEvent * re ) { + previewFont(); +} + +FQTermParam siteDialog::currentParameter() { + return param_; +} + +int siteDialog::currentSiteIndex() { + return ui_.siteList->currentRow(); +} + +void siteDialog::onAdvance() { + setting(addrDialog::General); +} + +void siteDialog::setting(addrDialog::Tabs tab) { + setParamFromUI(); + addrDialog addr(this, param_, addrDialog::APPLY); + addr.setCurrentTabIndex(tab); + int res = addr.exec(); + if (res == 1) { + param_ = addr.param(); + setUIFromParam(); + } +} + +void siteDialog::onProxy() { + setting(addrDialog::Proxy); +} + +void siteDialog::onAutoLogin() { + setting(addrDialog::General); +} + +void siteDialog::onDblClicked(QListWidgetItem * item) { + onConnect(); +} + +void siteDialog::connector() { + FQ_VERIFY(connect(ui_.siteList, SIGNAL(itemSelectionChanged()), + this, SLOT(setSiteSelected()))); + FQ_VERIFY(connect(ui_.siteList, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), + this, SLOT(onSelectSite(QListWidgetItem*, QListWidgetItem*)))); + FQ_VERIFY(connect(ui_.nameEdit, SIGNAL(textChanged(QString)), + this, SLOT(siteNameChanged(QString)))); + FQ_VERIFY(connect(ui_.protocolCombo, SIGNAL(currentIndexChanged(int)), + this, SLOT(onSelectProtocol(int)))); + FQ_VERIFY(connect(ui_.resetButton, SIGNAL(clicked()), + this, SLOT(onReset()))); + FQ_VERIFY(connect(ui_.upButton, SIGNAL(clicked()), + this, SLOT(onUp()))); + FQ_VERIFY(connect(ui_.downButton, SIGNAL(clicked()), + this, SLOT(onDown()))); + FQ_VERIFY(connect(ui_.newButton, SIGNAL(clicked()), + this, SLOT(onNew()))); + FQ_VERIFY(connect(ui_.deleteButton, SIGNAL(clicked()), + this, SLOT(onDelete()))); + FQ_VERIFY(connect(ui_.applyButton, SIGNAL(clicked()), + this, SLOT(onApply()))); + FQ_VERIFY(connect(ui_.closeButton, SIGNAL(clicked()), + this, SLOT(onClose()))); + FQ_VERIFY(connect(ui_.connectButton, SIGNAL(clicked()), + this, SLOT(onConnect()))); + FQ_VERIFY(connect(ui_.advanceButton, SIGNAL(clicked()), + this, SLOT(onAdvance()))); + FQ_VERIFY(connect(ui_.proxyButton, SIGNAL(clicked()), + this, SLOT(onProxy()))); + FQ_VERIFY(connect(ui_.autoLoginButton, SIGNAL(clicked()), + this, SLOT(onAutoLogin()))); + FQ_VERIFY(connect(ui_.siteList, SIGNAL(itemDoubleClicked(QListWidgetItem *)), + this, SLOT(onDblClicked(QListWidgetItem *)))); +} + +} //namespace FQTerm + +#include "sitemanager.moc" diff --git a/src/ui/sitemanager.h b/src/ui/sitemanager.h new file mode 100644 index 0000000..6aae387 --- /dev/null +++ b/src/ui/sitemanager.h @@ -0,0 +1,104 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef FQTERM_SITEMANGER_H +#define FQTERM_SITEMANGER_H + +#include "addrdialog.h" + +#include "ui_sitemanager.h" +#include "ui_quickdialog.h" + +class QListWidgetItem; + +namespace FQTerm { +class FQTermParam; +class FQTermConfig; + +class siteDialog: public QDialog { + Q_OBJECT; + public: + siteDialog(QWidget *parent_ = 0, Qt::WFlags fl = 0);; + ~siteDialog(); + + FQTermParam currentParameter(); + + int currentSiteIndex(); + + private: + void connector(); + + void resizeEvent(QResizeEvent * re); + + //Note: changes are made on config_ + void saveCurrentParam(); + void loadCurrentParam(); + + void setParamFromUI(); + void setUIFromParam(); + + void previewFont(); + + void swapSite(int first, int second); + int moveSite(int pos, int offset); + void forcedSetCurrentSite(int row); + void setCurrentSite(int row); + + QMessageBox::StandardButton checkModification(int row); + + void removeSite(int row); + + void close(int doneValue); + void setting(addrDialog::Tabs tab); + + + protected slots: + void onSelectSite(QListWidgetItem* current, QListWidgetItem* previous); + void siteNameChanged(QString name); + void setSiteSelected(); + + void onSelectProtocol(int index); + + void onReset(); + void onApply(); + void onUp(); + void onDown(); + void onNew(); + void onDelete(); + void onClose(); + void onConnect(); + + void onAdvance(); + void onProxy(); + void onAutoLogin(); + void onDblClicked(QListWidgetItem * item); + + private: + FQTermConfig *config_; + FQTermParam param_; + + Ui::siteManager ui_; + + static int ports[]; //telnet, ssh1, ssh2 +}; + +} //FQTerm namespace + +#endif // FQTERM_SITEMANGER_H diff --git a/src/ui/sitemanager.ui b/src/ui/sitemanager.ui new file mode 100644 index 0000000..9b085ed --- /dev/null +++ b/src/ui/sitemanager.ui @@ -0,0 +1,593 @@ +<ui version="4.0" > + <class>siteManager</class> + <widget class="QDialog" name="siteManager" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>481</width> + <height>495</height> + </rect> + </property> + <property name="windowTitle" > + <string>Address Book</string> + </property> + <layout class="QGridLayout" > + <item row="0" column="0" > + <layout class="QGridLayout" > + <item row="0" column="0" colspan="2" > + <widget class="QListWidget" name="siteList" /> + </item> + <item row="1" column="0" > + <widget class="QPushButton" name="upButton" > + <property name="text" > + <string>&Up</string> + </property> + </widget> + </item> + <item row="1" column="1" > + <widget class="QPushButton" name="downButton" > + <property name="text" > + <string>&Down</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="0" column="1" > + <widget class="QGroupBox" name="editGroup" > + <property name="title" > + <string/> + </property> + <layout class="QGridLayout" > + <item row="0" column="0" > + <widget class="QLabel" name="nameLabel" > + <property name="text" > + <string>Site Name</string> + </property> + </widget> + </item> + <item row="0" column="1" colspan="3" > + <widget class="QLineEdit" name="nameEdit" /> + </item> + <item row="1" column="0" > + <widget class="QLabel" name="addrLabel" > + <property name="text" > + <string>Address</string> + </property> + </widget> + </item> + <item row="1" column="1" colspan="3" > + <widget class="QLineEdit" name="addrEdit" /> + </item> + <item row="2" column="0" > + <widget class="QLabel" name="protocolLabel" > + <property name="text" > + <string>Protocol</string> + </property> + </widget> + </item> + <item row="2" column="1" > + <widget class="QComboBox" name="protocolCombo" > + <item> + <property name="text" > + <string>Telnet</string> + </property> + </item> + <item> + <property name="text" > + <string>SSH1</string> + </property> + </item> + <item> + <property name="text" > + <string>SSH2</string> + </property> + </item> + </widget> + </item> + <item row="2" column="2" > + <widget class="QCheckBox" name="portCheck" > + <property name="text" > + <string>Port</string> + </property> + </widget> + </item> + <item row="2" column="3" > + <widget class="QLineEdit" name="portEdit" > + <property name="enabled" > + <bool>false</bool> + </property> + <property name="text" > + <string/> + </property> + </widget> + </item> + <item row="3" column="0" > + <widget class="QLabel" name="hostTypeLabel" > + <property name="text" > + <string>Host Type</string> + </property> + </widget> + </item> + <item row="3" column="1" > + <widget class="QComboBox" name="hostTypeCombo" > + <item> + <property name="text" > + <string>BBS</string> + </property> + </item> + <item> + <property name="text" > + <string>*NIX</string> + </property> + </item> + </widget> + </item> + <item row="4" column="0" > + <widget class="QCheckBox" name="proxyCheck" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Preferred" hsizetype="Minimum" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string>Use Proxy</string> + </property> + </widget> + </item> + <item row="4" column="1" > + <widget class="QPushButton" name="proxyButton" > + <property name="enabled" > + <bool>false</bool> + </property> + <property name="text" > + <string>Setting...</string> + </property> + </widget> + </item> + <item row="5" column="0" > + <widget class="QCheckBox" name="autoLoginCheck" > + <property name="text" > + <string>Auto Login</string> + </property> + </widget> + </item> + <item row="5" column="1" > + <widget class="QPushButton" name="autoLoginButton" > + <property name="enabled" > + <bool>false</bool> + </property> + <property name="sizePolicy" > + <sizepolicy vsizetype="Fixed" hsizetype="Preferred" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string>Setting...</string> + </property> + </widget> + </item> + <item row="6" column="0" > + <widget class="QLabel" name="label_10" > + <property name="text" > + <string>Font Preview</string> + </property> + </widget> + </item> + <item row="6" column="1" colspan="3" > + <widget class="QLabel" name="fontPreviewer" > + <property name="autoFillBackground" > + <bool>true</bool> + </property> + <property name="text" > + <string>Font Previewer</string> + </property> + <property name="textFormat" > + <enum>Qt::RichText</enum> + </property> + <property name="alignment" > + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="8" column="0" colspan="4" > + <layout class="QHBoxLayout" > + <item> + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>55</width> + <height>25</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="resetButton" > + <property name="text" > + <string>&Reset</string> + </property> + </widget> + </item> + <item> + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>54</width> + <height>25</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="advanceButton" > + <property name="text" > + <string>A&dvance</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="7" column="1" > + <spacer> + <property name="orientation" > + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item row="1" column="0" colspan="2" > + <layout class="QHBoxLayout" > + <item> + <widget class="QPushButton" name="newButton" > + <property name="text" > + <string>&New</string> + </property> + </widget> + </item> + <item> + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="deleteButton" > + <property name="text" > + <string>&Delete</string> + </property> + </widget> + </item> + <item> + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="connectButton" > + <property name="text" > + <string>C&onnect</string> + </property> + </widget> + </item> + <item> + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="applyButton" > + <property name="text" > + <string>&Save</string> + </property> + </widget> + </item> + <item> + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="closeButton" > + <property name="text" > + <string>&Close</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + <widget class="QLabel" name="label" > + <property name="geometry" > + <rect> + <x>9</x> + <y>553</y> + <width>31</width> + <height>0</height> + </rect> + </property> + <property name="maximumSize" > + <size> + <width>16777215</width> + <height>0</height> + </size> + </property> + <property name="text" > + <string/> + </property> + </widget> + <widget class="QLabel" name="label_2" > + <property name="geometry" > + <rect> + <x>120</x> + <y>553</y> + <width>30</width> + <height>0</height> + </rect> + </property> + <property name="maximumSize" > + <size> + <width>16777215</width> + <height>0</height> + </size> + </property> + <property name="text" > + <string/> + </property> + </widget> + <widget class="QLabel" name="label_3" > + <property name="geometry" > + <rect> + <x>156</x> + <y>553</y> + <width>78</width> + <height>0</height> + </rect> + </property> + <property name="maximumSize" > + <size> + <width>16777215</width> + <height>0</height> + </size> + </property> + <property name="text" > + <string/> + </property> + </widget> + <widget class="QLabel" name="label_4" > + <property name="geometry" > + <rect> + <x>240</x> + <y>553</y> + <width>69</width> + <height>0</height> + </rect> + </property> + <property name="maximumSize" > + <size> + <width>16777215</width> + <height>0</height> + </size> + </property> + <property name="text" > + <string/> + </property> + </widget> + <widget class="QLabel" name="label_5" > + <property name="geometry" > + <rect> + <x>410</x> + <y>553</y> + <width>34</width> + <height>0</height> + </rect> + </property> + <property name="maximumSize" > + <size> + <width>16777215</width> + <height>0</height> + </size> + </property> + <property name="text" > + <string/> + </property> + </widget> + <widget class="QLabel" name="label_6" > + <property name="geometry" > + <rect> + <x>369</x> + <y>553</y> + <width>35</width> + <height>0</height> + </rect> + </property> + <property name="maximumSize" > + <size> + <width>16777215</width> + <height>0</height> + </size> + </property> + <property name="text" > + <string/> + </property> + </widget> + <widget class="QLabel" name="label_7" > + <property name="geometry" > + <rect> + <x>46</x> + <y>553</y> + <width>30</width> + <height>0</height> + </rect> + </property> + <property name="maximumSize" > + <size> + <width>16777215</width> + <height>0</height> + </size> + </property> + <property name="text" > + <string/> + </property> + </widget> + <widget class="QLabel" name="label_8" > + <property name="geometry" > + <rect> + <x>82</x> + <y>553</y> + <width>32</width> + <height>0</height> + </rect> + </property> + <property name="maximumSize" > + <size> + <width>16777215</width> + <height>0</height> + </size> + </property> + <property name="text" > + <string/> + </property> + </widget> + <widget class="QLabel" name="label_9" > + <property name="geometry" > + <rect> + <x>315</x> + <y>553</y> + <width>48</width> + <height>0</height> + </rect> + </property> + <property name="maximumSize" > + <size> + <width>16777215</width> + <height>0</height> + </size> + </property> + <property name="text" > + <string/> + </property> + </widget> + </widget> + <tabstops> + <tabstop>siteList</tabstop> + <tabstop>nameEdit</tabstop> + <tabstop>addrEdit</tabstop> + <tabstop>protocolCombo</tabstop> + <tabstop>portCheck</tabstop> + <tabstop>portEdit</tabstop> + <tabstop>hostTypeCombo</tabstop> + <tabstop>proxyCheck</tabstop> + <tabstop>autoLoginCheck</tabstop> + <tabstop>connectButton</tabstop> + <tabstop>upButton</tabstop> + <tabstop>downButton</tabstop> + <tabstop>resetButton</tabstop> + <tabstop>advanceButton</tabstop> + <tabstop>newButton</tabstop> + <tabstop>deleteButton</tabstop> + <tabstop>applyButton</tabstop> + <tabstop>closeButton</tabstop> + <tabstop>proxyButton</tabstop> + <tabstop>autoLoginButton</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>portCheck</sender> + <signal>toggled(bool)</signal> + <receiver>portEdit</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>372</x> + <y>81</y> + </hint> + <hint type="destinationlabel" > + <x>477</x> + <y>83</y> + </hint> + </hints> + </connection> + <connection> + <sender>proxyCheck</sender> + <signal>toggled(bool)</signal> + <receiver>proxyButton</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>235</x> + <y>141</y> + </hint> + <hint type="destinationlabel" > + <x>285</x> + <y>126</y> + </hint> + </hints> + </connection> + <connection> + <sender>autoLoginCheck</sender> + <signal>toggled(bool)</signal> + <receiver>autoLoginButton</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>232</x> + <y>155</y> + </hint> + <hint type="destinationlabel" > + <x>361</x> + <y>172</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/ui/soundconf.cpp b/src/ui/soundconf.cpp new file mode 100644 index 0000000..2681b83 --- /dev/null +++ b/src/ui/soundconf.cpp @@ -0,0 +1,178 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include <QMessageBox> +#include <QFileDialog> + +#include "fqterm.h" +#include "fqterm_config.h" +#include "fqterm_path.h" +#include "fqterm_sound.h" + +#include "soundconf.h" + +namespace FQTerm { +/* + * Constructs a fSoundConf which is a child of 'parent', with the + * name 'name' and widget flags set to 'f' + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ + +soundConf::soundConf(FQTermConfig * config, QWidget *parent, Qt::WFlags fl) + : QDialog(parent, fl), + buttonGroup_(this), + config_(config){ + ui_.setupUi(this); + buttonGroup_.addButton(ui_.radioButton1, 0); + buttonGroup_.addButton(ui_.radioButton2, 1); + sound_ = NULL; + loadSetting(); + FQ_VERIFY(connect(ui_.bfSelect, SIGNAL(clicked()), + this, SLOT(onSelectFile()))); + FQ_VERIFY(connect(ui_.bpSelect, SIGNAL(clicked()), + this, SLOT(onSelectProg()))); + FQ_VERIFY(connect(ui_.bpTest, SIGNAL(clicked()), + this, SLOT(onTestPlay()))); + FQ_VERIFY(connect(ui_.bOK, SIGNAL(clicked()), + this, SLOT(accept()))); + FQ_VERIFY(connect(ui_.bCancel, SIGNAL(clicked()), + this, SLOT(reject()))); +} + +/* + * Destroys the object and frees any allocated resources + */ +soundConf::~soundConf() { + // no need to delete child widgets, Qt does it all for us +} + +/* + * public slot + */ +void soundConf::onSelectFile() { + FQTermFileDialog fileDialog(config_); + QString soundfile = fileDialog.getOpenName("Choose a WAVE file", "WAVE Audio Files (*.wav *.WAV)"); + if (!soundfile.isEmpty()) { + ui_.leFile->setText(soundfile); + } +} + +/* + * public slot + */ +void soundConf::onSelectProg() { + FQTermFileDialog fileDialog(config_); + QString progfile = fileDialog.getOpenName("Choose a program", ""); + if (!progfile.isEmpty()) { + ui_.leProg->setText(progfile); + } +} + +/* + * public slot + */ +void soundConf::onPlayMethod(int id) { +FQ_TRACE("sconf", 0) << id << ": " << buttonGroup_.checkedId(); + ui_.bpSelect->setEnabled(id == 1 || buttonGroup_.checkedId() == 1); +} + +void soundConf::onTestPlay() { + if (ui_.leFile->text().isEmpty()) { + QMessageBox::critical(this, tr("No sound file"), + tr("You have to select a file to test the sound"), tr("&Ok")); + + return; + } + + sound_ = NULL; + + switch (buttonGroup_.checkedId()) { + case 0: + sound_ = new FQTermSystemSound(ui_.leFile->text()); + break; + case 1: + if (ui_.leProg->text().isEmpty()) { + QMessageBox::critical(this, tr("No player"), + tr("You have to specify an external player"), tr("&Ok")); + + break; + } + + sound_ = new FQTermExternalSound(ui_.leProg->text(), ui_.leFile->text()); + break; + } + + if (sound_) { + sound_->start(); + } +} + +void soundConf::loadSetting() { + + QString strTmp; + + strTmp = config_->getItemValue("preference", "wavefile"); + if (!strTmp.isEmpty()) { + ui_.leFile->setText(strTmp); + } + + strTmp = config_->getItemValue("preference", "playmethod"); + + int valTmp = !strTmp.isEmpty()? strTmp.toInt(): -1; + + if (valTmp >= 0 && valTmp <= 1) { + buttonGroup_.button(valTmp)->setChecked(true); + if (valTmp == 1) { + strTmp = config_->getItemValue("preference", "externalplayer"); + if (!strTmp.isEmpty()) { + ui_.leProg->setText(strTmp); + } + } + } +} + +void soundConf::saveSetting() { + + QString strTmp; + + config_->setItemValue("preference", "beep", "2"); + + config_->setItemValue("preference", "wavefile", ui_.leFile->text()); + + strTmp.setNum(buttonGroup_.checkedId()); + config_->setItemValue("preference", "playmethod", strTmp); + + if (strTmp == "1") { + config_->setItemValue("preference", "externalplayer", ui_.leProg->text()); + } + + config_->save(getPath(USER_CONFIG) + "fqterm.cfg"); +} + +void soundConf::accept() { + saveSetting(); + QDialog::accept(); +} + +} // namespace FQTerm + +#include "soundconf.moc" diff --git a/src/ui/soundconf.h b/src/ui/soundconf.h new file mode 100644 index 0000000..5b4fe4c --- /dev/null +++ b/src/ui/soundconf.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef FQTERM_SOUND_CONF_H +#define FQTERM_SOUND_CONF_H + +#include "ui_soundconf.h" +#include "fqterm_filedialog.h" + +namespace FQTerm { + +class FQTermSound; +class FQTermConfig; + +class soundConf: public QDialog { + Q_OBJECT; + public: + soundConf(FQTermConfig *, QWidget *parent_ = 0, Qt::WFlags fl = 0); + ~soundConf(); + void loadSetting(); + void saveSetting(); + + public slots: + void onSelectFile(); + void onSelectProg(); + void onPlayMethod(int id); + void onTestPlay(); + protected slots: + void accept(); + + private: + FQTermSound *sound_; + Ui::soundConf ui_; + QButtonGroup buttonGroup_; + FQTermConfig * config_; +}; + +} // namespace FQTerm + +#endif // FQTERM_SOUND_CONF_H diff --git a/src/ui/soundconf.ui b/src/ui/soundconf.ui new file mode 100644 index 0000000..9cfe761 --- /dev/null +++ b/src/ui/soundconf.ui @@ -0,0 +1,162 @@ +<ui version="4.0" > + <class>soundConf</class> + <widget class="QDialog" name="soundConf" > + <property name="enabled" > + <bool>true</bool> + </property> + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>308</width> + <height>269</height> + </rect> + </property> + <property name="windowTitle" > + <string>Configure</string> + </property> + <layout class="QGridLayout" > + <item row="0" column="0" colspan="2" > + <widget class="QGroupBox" name="groupBox" > + <property name="title" > + <string>Sound File:</string> + </property> + <layout class="QGridLayout" > + <item row="0" column="0" > + <widget class="QLineEdit" name="leFile" /> + </item> + <item row="0" column="2" > + <widget class="QPushButton" name="bfSelect" > + <property name="text" > + <string>Select...</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="1" column="0" colspan="2" > + <widget class="QGroupBox" name="groupBox_2" > + <property name="title" > + <string>Play With:</string> + </property> + <layout class="QGridLayout" > + <item row="0" column="0" > + <widget class="QRadioButton" name="radioButton1" > + <property name="enabled" > + <bool>true</bool> + </property> + <property name="text" > + <string>Internal</string> + </property> + </widget> + </item> + <item row="0" column="1" > + <widget class="QRadioButton" name="radioButton2" > + <property name="enabled" > + <bool>true</bool> + </property> + <property name="text" > + <string>External</string> + </property> + </widget> + </item> + <item row="0" column="4" > + <widget class="QPushButton" name="bpTest" > + <property name="text" > + <string>Test</string> + </property> + </widget> + </item> + <item row="0" column="2" > + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item row="2" column="0" colspan="2" > + <widget class="QGroupBox" name="groupBox_3" > + <property name="enabled" > + <bool>false</bool> + </property> + <property name="title" > + <string>External Program:</string> + </property> + <layout class="QGridLayout" > + <item row="0" column="0" > + <widget class="QLineEdit" name="leProg" /> + </item> + <item row="0" column="2" > + <widget class="QPushButton" name="bpSelect" > + <property name="text" > + <string>Select...</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="3" column="0" > + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="3" column="1" > + <layout class="QHBoxLayout" > + <item> + <widget class="QPushButton" name="bOK" > + <property name="text" > + <string>OK</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="bCancel" > + <property name="text" > + <string>Cancel</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11" /> + <resources/> + <connections> + <connection> + <sender>radioButton2</sender> + <signal>toggled(bool)</signal> + <receiver>groupBox_3</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>124</x> + <y>136</y> + </hint> + <hint type="destinationlabel" > + <x>123</x> + <y>176</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/ui/sshlogin.ui b/src/ui/sshlogin.ui new file mode 100644 index 0000000..8794a57 --- /dev/null +++ b/src/ui/sshlogin.ui @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>SSHLogin</class> + <widget class="QDialog" name="SSHLogin"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>295</width> + <height>170</height> + </rect> + </property> + <property name="windowTitle"> + <string>Login</string> + </property> + <layout class="QGridLayout"> + <item row="0" column="0" colspan="3"> + <widget class="QLabel" name="textLabel2_2"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Please enter your username and password</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="textLabel1"> + <property name="text"> + <string>UserName:</string> + </property> + </widget> + </item> + <item row="1" column="1" colspan="2"> + <widget class="QLineEdit" name="leUserName"/> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="textLabel2"> + <property name="text"> + <string>Password:</string> + </property> + </widget> + </item> + <item row="2" column="1" colspan="2"> + <widget class="QLineEdit" name="lePassword"/> + </item> + <item row="3" column="0"> + <widget class="QPushButton" name="bOK"> + <property name="focusPolicy"> + <enum>Qt::NoFocus</enum> + </property> + <property name="text"> + <string>OK</string> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QPushButton" name="bCancel"> + <property name="focusPolicy"> + <enum>Qt::NoFocus</enum> + </property> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources/> + <connections/> +</ui> diff --git a/src/ui/sshlogindialog.cpp b/src/ui/sshlogindialog.cpp new file mode 100644 index 0000000..cd858cb --- /dev/null +++ b/src/ui/sshlogindialog.cpp @@ -0,0 +1,80 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include <QString> +#include <QLineEdit> + +#include "fqterm_trace.h" +#include "sshlogindialog.h" + +namespace FQTerm { + +/* + * Constructs a fSSHLogin which is a child of 'parent', with the + * name 'name' and widget flags set to 'f' + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +SSHLoginDialog::SSHLoginDialog(QString *username, QString *password, + QWidget *parent_, Qt::WFlags fl) + : QDialog(parent_, fl) { + ui_.setupUi(this); + setWindowTitle(parent_->windowTitle()); + strUserName = username; + strPassword = password; + ui_.lePassword->setEchoMode(QLineEdit::Password); + ui_.leUserName->setText(*username); + ui_.lePassword->setText(*password); + if (!username->isEmpty()) { + ui_.leUserName->setDisabled(true); + ui_.lePassword->setFocus(); + } else { + ui_.leUserName->setDisabled(false); + ui_.leUserName->setFocus(); + } + + FQ_VERIFY(connect(ui_.bOK, SIGNAL(clicked()), this, SLOT(accept()))); + FQ_VERIFY(connect(ui_.bCancel, SIGNAL(clicked()), this, SLOT(reject()))); + FQ_VERIFY(connect(ui_.leUserName, SIGNAL(returnPressed()), this, SLOT(moveFocus()))); + FQ_VERIFY(connect(ui_.lePassword, SIGNAL(returnPressed()), this, SLOT(accept()))); +} + +/* + * Destroys the object and frees any allocated resources + */ +SSHLoginDialog::~SSHLoginDialog() { + // no need to delete child widgets, Qt does it all for us +} + +void SSHLoginDialog::accept() { + *strUserName = ui_.leUserName->text(); + *strPassword = ui_.lePassword->text(); + QDialog::accept(); +} + +void SSHLoginDialog::moveFocus() +{ + ui_.lePassword->setFocus(); +} + +} // namespace FQTerm + +#include "sshlogindialog.moc" diff --git a/src/ui/sshlogindialog.h b/src/ui/sshlogindialog.h new file mode 100644 index 0000000..e3295cc --- /dev/null +++ b/src/ui/sshlogindialog.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef FQTERM_SSH_LOGIN_H +#define FQTERM_SSH_LOGIN_H + +#include "ui_sshlogin.h" + +namespace FQTerm { + +class SSHLoginDialog: public QDialog { + Q_OBJECT; +public: + SSHLoginDialog(QString *username, QString *password, + QWidget *parent_ = 0, Qt::WFlags fl = 0); + ~SSHLoginDialog(); +private: + QString *strUserName; + QString *strPassword; + Ui::SSHLogin ui_; +private slots: + void accept(); + void moveFocus(); +}; + +} // namespace FQTerm + +#endif // FQTERM_SSH_LOGIN_H diff --git a/src/ui/statusBar.cpp b/src/ui/statusBar.cpp new file mode 100644 index 0000000..be48fc4 --- /dev/null +++ b/src/ui/statusBar.cpp @@ -0,0 +1,530 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include <QPaintEvent> +#include <QEvent> +#include <QHBoxLayout> +#include <QCustomEvent> +#include <QProgressBar> +#include <QToolButton> +#include <QPushButton> +#include <QPainter> +#include <QPixmap> +#include <QMessageBox> +#include <QApplication> +#include <QToolTip> + +#include "fqterm_trace.h" +#include "fqterm_path.h" + +#include "popupMessage.h" +#include "progressBar.h" +#include "overlayWidget.h" +#include "statusBar.h" + +namespace FQTerm { + +//TODO allow for uncertain progress periods + +StatusBar *StatusBar::singletonStatusBar_ = 0; + +StatusBar::StatusBar(QWidget *parent, const char *name) + : QWidget(parent) { + setObjectName(name); + singletonStatusBar_ = this; + QBoxLayout *mainlayout = new QHBoxLayout(this); //, 2, /*spacing*/5 ); + mainlayout->setMargin(0); + mainlayout->setSpacing(5); + + //we need extra spacing due to the way we paint the surrounding boxes + QBoxLayout *layout = new QHBoxLayout; + layout->setSpacing(5); + mainlayout->addLayout(layout); + + m_mainTextLabel = new QLabel(this); + m_mainTextLabel->setObjectName("mainTextLabel"); + m_mainTextLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored); + + QWidget *mainProgressBarBox = new QWidget(this); + mainProgressBarBox->setObjectName("progressBox"); + + QHBoxLayout *mainProgressBarLayout = new QHBoxLayout(mainProgressBarBox); + mainProgressBarLayout->setContentsMargins(0, 0, 0, 0); + + QToolButton *b1 = new QToolButton(mainProgressBarBox); + b1->setObjectName("cancelButton"); + b1->setContentsMargins(0, 0, 0, 0); + b1->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored); + mainProgressBarLayout->addWidget(b1); + + mainProgressBar_ = new QProgressBar(mainProgressBarBox); + mainProgressBar_->setObjectName("mainProgressBar"); + mainProgressBarLayout->addWidget(mainProgressBar_); + + QToolButton *b2 = new QToolButton(mainProgressBarBox); + b2->setObjectName("showAllProgressDetails"); + b2->setContentsMargins(0,0,0,0); + b2->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored); + mainProgressBarLayout->addWidget(b2); + + mainProgressBarLayout->setSpacing(2); + mainProgressBarBox->hide(); + + layout->addWidget(mainProgressBarBox); + layout->addWidget(m_mainTextLabel); + + layout->setStretchFactor(m_mainTextLabel, 2); + layout->setStretchFactor(mainProgressBarBox, 1); + + otherWidgetLayout_ = new QHBoxLayout; + otherWidgetLayout_->setSpacing(0); + mainlayout->addLayout(otherWidgetLayout_); + + mainlayout->setStretchFactor(layout, 6); + mainlayout->setStretchFactor(otherWidgetLayout_, 4); + + b1->setIcon(QPixmap(getPath(RESOURCE) + "pic/messagebox_critical.png")); + b2->setIcon(QPixmap(getPath(RESOURCE) + "pic/messagebox_info.png")); + b2->setCheckable(true); + b1->setToolTip(tr("Abort all background-operations")); + b2->setToolTip(tr("Show progress detail")); + + FQ_VERIFY(connect(b1, SIGNAL(clicked()), SLOT(abortAllProgressOperations()))); + FQ_VERIFY(connect(b2, SIGNAL(toggled(bool)), SLOT(toggleProgressWindow(bool)))); + + popupProgressMessage_ = new PopupMessage(this, mainProgressBarBox, 0); + popupProgressMessage_->showCloseButton(false); + popupProgressMessage_->showCounter(false); + + popupProgressMessage_->setFrameStyle(QFrame::Box | QFrame::Raised); + popupProgressMessage_->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); +} + +void StatusBar::addWidget(QWidget *widget) { + otherWidgetLayout_->addWidget(widget); +} + + +/// reimplemented functions + +void StatusBar::ensurePolished() { + QWidget::ensurePolished(); + + int h = 0; + QObjectList list = children(); + + //for( QObject * o = list.first(); o; o = list.next() ) { + foreach(QObject *o, list) { + if (o->inherits("QWidget")) { + int _h = static_cast < QWidget * > (o)->minimumSizeHint().height(); + if (_h > h) { + h = _h; + } + + + if (o->inherits("QLabel")) { + static_cast < QLabel * > (o)->setIndent(4); + } + } + } + + h -= 4; // it's too big usually + + //for ( QObject * o = list.first(); o; o = list.next() ) + foreach(QObject *o, list)static_cast < QWidget * > (o)->setFixedHeight(h); + + //delete list; +} + +void StatusBar::paintEvent(QPaintEvent*) { + QObjectList list = children(); //queryList( "QWidget", 0, false, false ); + QPainter p(this); + + //for( QObject * o = list.first(); o; o = list.next() ) { + foreach(QObject *o, list) { + if (o->inherits("QWidget")) { + QWidget *w = (QWidget*)o; + + if (!w->isVisible()) { + continue; + } + + /*style().drawPrimitive( + QStyle::PE_StatusBarSection, + &p, + QRect( w->x() - 1, w->y() - 1, w->width() + 2, w->height() + 2 ), + colorGroup(), + QStyle::State_None, + QStyleOption( w ) );*/ + } + } + + //delete list; +} + +bool StatusBar::event(QEvent *e) { + if (e->type() == QEvent::LayoutRequest) { + update(); + } + + return QWidget::event(e); +} + + +/// Messaging system + +void StatusBar::setMainText(const QString &text) { + mainText_ = text; + + // it may not be appropriate for us to set the mainText yet + resetMainText(); +} + +void StatusBar::shortMessage(const QString &text) { + m_mainTextLabel->setText(text); + m_mainTextLabel->setPalette(QToolTip::palette()); + + //SingleShotPool::startTimer( 5000, this, SLOT(resetMainText()) ); + resetMainText(); +} + +void StatusBar::resetMainText() { + /* + if( sender() ) + debug() << sender()->name() << endl; + + // don't reset if we are showing a shortMessage + if( SingleShotPool::isActive( this, SLOT(resetMainText()) ) ) + return; + */ + m_mainTextLabel->setPalette(QPalette()); + + if (allDone()) { + m_mainTextLabel->setText(mainText_); + } + + else { + //m_mainTextLabel->setPaletteBackgroundColor( m_mainTextLabel->paletteBackgroundColor().dark( 110 ) ); + m_mainTextLabel->setPalette(QToolTip::palette()); + + ProgressBar *bar = 0; + uint count = 0; + + for (ProgressMap::ConstIterator it = progressMap_.begin(); + it != progressMap_.end(); ++it ) { + if (!(*it)->isFinished_) { + bar = *it; + count++; + } + } + + if (count == 1) { + m_mainTextLabel->setText(bar->description() + "..."); + } else { + m_mainTextLabel->setText(tr("Multiple background-tasks running")); + } + } +} +/* + void + StatusBar::shortLongMessage( const QString &_short, const QString &_long ) + { + shortMessage( _short ); + + if ( !_long.isEmpty() ) { + AMAROK_NOTIMPLEMENTED + } + } +*/ +//void +//StatusBar::longMessage( const QString &text, int /*type*/ ) +/*{ + PopupMessage * message; + message = new PopupMessage( this, m_mainTextLabel ); + message->setText( text ); + + if ( !m_messageQueue.isEmpty() ) + message->stackUnder( m_messageQueue.last() ); + + message->reposition(); + message->display(); + + raise(); + + m_messageQueue += message; + } +*/ + +//void +//StatusBar::longMessageThreadSafe( const QString &text, int /*type*/ ) +/*{ + QCustomEvent * e = new QCustomEvent( 1000 ); + e->setData( new QString( text ) ); + QApplication::postEvent( this, e ); + } +*/ +// void +// StatusBar::customEvent( QCustomEvent *e ) +// { +// QString *s = static_cast<QString*>( e->data() ); +// shortMessage( *s ); +// delete s; +//} + + +/// application wide progress monitor + +inline bool StatusBar::allDone() { + for (ProgressMap::Iterator it = progressMap_.begin(), end = + progressMap_.end(); it != end; ++it) + if ((*it)->isFinished_ == false) { + return false; + } + + return true; +} + +ProgressBar &StatusBar::newProgressOperation(QObject *owner) { + if (progressMap_.contains(owner)) { + return *progressMap_[owner]; + } + + if (allDone()) { + // if we're allDone then we need to remove the old progressBars before + // we start anything new or the total progress will not be accurate + pruneProgressBars(); + } else { + (progressBox()->findChild < QWidget * > ("showAllProgressDetails"))->show(); + } + + QWidget *hbox = new QWidget(popupProgressMessage_); + QHBoxLayout *hlayout = new QHBoxLayout(hbox); + QLabel *label = new QLabel(hbox); + hlayout->addWidget(label); + ProgressBar *pBar = new ProgressBar(hbox, label); + hlayout->addWidget(pBar); + hbox->show(); + popupProgressMessage_->addWidget(hbox); + progressMap_.insert(owner, pBar); + + + FQ_VERIFY(connect(owner, SIGNAL(destroyed(QObject*)), SLOT(endProgressOperation(QObject*)))); + + // so we can show the correct progress information + // after the ProgressBar is setup + //SingleShotPool::startTimer( 0, this, SLOT(updateProgressAppearance()) ); + updateProgressAppearance(); + + progressBox()->show(); + cancelButton()->setEnabled(true); + + return *progressMap_[owner]; +} +/* + ProgressBar& + StatusBar::newProgressOperation( KIO::Job *job ) + { + ProgressBar & bar = newProgressOperation( (QObject*)job ); + bar.setTotalSteps( 100 ); + + if(!allDone()) + static_cast<QWidget*>(progressBox()->child("showAllProgressDetails"))->show(); + QVERIFY(connect( job, SIGNAL(result( KIO::Job* )), SLOT(endProgressOperation()))); + //TODO QVERIFY(connect( job, SIGNAL(infoMessage( KIO::Job *job, const QString& )), SLOT() )); + QVERIFY(connect( job, SIGNAL(percent( KIO::Job*, unsigned long )), SLOT(setProgress( KIO::Job*, unsigned long )))); + + return bar; + } +*/ +/* + void + StatusBar::endProgressOperation() + { + QObject *owner = (QObject*)sender(); //HACK deconsting it + KIO::Job *job = dynamic_cast<KIO::Job*>( owner ); + + //FIXME doesn't seem to work for KIO::DeleteJob, it has it's own error handler and returns no error too + // if you try to delete http urls for instance <- KDE SUCKS! + + if( job && job->error() ) + longMessage( job->errorString(), Error ); + + endProgressOperation( owner ); + } +*/ +void StatusBar::endProgressOperation(QObject *owner) { + //the owner of this progress operation has been deleted + //we need to stop listening for progress from it + //NOTE we don't delete it yet, as this upsets some + //things, we just call setDone(). + + if (!progressMap_.contains(owner)) { + return ; + } + + progressMap_[owner]->setDone(); + + if (allDone() && popupProgressMessage_->isHidden()) { + cancelButton()->setEnabled(false); + //SingleShotPool::startTimer( 2000, this, SLOT(hideMainProgressBar()) ); + hideMainProgressBar(); + } + + updateTotalProgress(); +} + +void StatusBar::abortAllProgressOperations() { //slot + for (ProgressMap::Iterator it = progressMap_.begin(), end = + progressMap_.end(); it != end; ++it) { + (*it)->abortButton_->animateClick(); + } + + m_mainTextLabel->setText(tr("Aborting all jobs...")); + + cancelButton()->setEnabled(false); +} + +void StatusBar::toggleProgressWindow(bool show) { //slot + popupProgressMessage_->adjustSize(); + //FIXME shouldn't be needed, adding bars doesn't seem to do this + popupProgressMessage_->setShown(show); + + if (!show) { + hideMainProgressBar(); + } + //SingleShotPool::startTimer( 2000, this, SLOT(hideMainProgressBar()) ); +} + +void StatusBar::showMainProgressBar() { + if (!allDone()) { + progressBox()->show(); + } +} + +void StatusBar::hideMainProgressBar() { + if (allDone() && popupProgressMessage_->isHidden()) { + pruneProgressBars(); + + resetMainText(); + + mainProgressBar_->setValue(0); + progressBox()->close(); + } +} + +void StatusBar::setProgress(int steps) { + setProgress(sender(), steps); +} +/* + void + StatusBar::setProgress( KIO::Job *job, unsigned long percent ) + { + setProgress( ( QObject* ) job, percent ); + } +*/ +void StatusBar::setProgress(const QObject *owner, int steps) { + if (!progressMap_.contains(owner)) { + return ; + } + + progressMap_[owner]->setValue(steps); + + updateTotalProgress(); +} + +void StatusBar::setProgressStatus(const QObject *owner, const QString &text) { + if (!progressMap_.contains(owner)) { + return ; + } + + progressMap_[owner]->setStatus(text); +} + +void StatusBar::incrementProgress() { + incrementProgress(sender()); +} + +void StatusBar::incrementProgress(const QObject *owner) { + if (!progressMap_.contains(owner)) { + return ; + } + + progressMap_[owner]->setValue(progressMap_[owner]->value() + 1); + + updateTotalProgress(); +} + +void StatusBar::updateTotalProgress() { + uint totalSteps = 0; + uint progress = 0; + + for (ProgressMap::ConstIterator it = progressMap_.begin(); + it != progressMap_.end(); ++it ) { + totalSteps += (*it)->maximum(); + progress += (*it)->value(); + } + + if (totalSteps == 0 && progress == 0) { + return ; + } + + mainProgressBar_->setMaximum(totalSteps); + mainProgressBar_->setValue(progress); + + pruneProgressBars(); +} + +void StatusBar::updateProgressAppearance() { + toggleProgressWindowButton()->setShown(progressMap_.count() > 1); + + resetMainText(); + + updateTotalProgress(); +} + +void StatusBar::pruneProgressBars() { + ProgressMap::Iterator it = progressMap_.begin(); + const ProgressMap::Iterator end = progressMap_.end(); + int count = 0; + bool removedBar = false; + while (it != end) + if ((*it)->isFinished_ == true) { + delete (*it)->label_; + delete (*it)->abortButton_; + delete (*it); + + ProgressMap::Iterator jt = it; + ++it; + progressMap_.erase(jt); + removedBar = true; + } else { + ++it; + ++count; + } + if (count == 1 && removedBar) { //if its gone from 2 or more bars to one bar... + resetMainText(); + (progressBox()->findChild < QWidget * > ("showAllProgressDetails"))->hide(); + popupProgressMessage_->setShown(false); + } +} + +} //namespace FQTerm + +#include "statusBar.moc" diff --git a/src/ui/statusBar.h b/src/ui/statusBar.h new file mode 100644 index 0000000..9737f90 --- /dev/null +++ b/src/ui/statusBar.h @@ -0,0 +1,148 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef FQTERM_STATUSBAR_H +#define FQTERM_STATUSBAR_H + +#include "progressBar.h" //convenience +// #include <qwidget.h> //baseclass +// #include <qmap.h> //stack allocated +// #include <q3valuelist.h> //stack allocated +//Added by qt3to4: +// #include <QCustomEvent> +#include <QLabel> +#include <QEvent> +#include <QPaintEvent> +#include <QMap> +#include <QList> +#include <QWidget> +#include <QProgressBar> + +class QString; +class QLayout; +class QLabel; +class QString; + +namespace FQTerm { + +class PopupMessage; +typedef QMap < const QObject *, ProgressBar * > ProgressMap; + +class StatusBar: public QWidget { + Q_OBJECT; + public: + StatusBar(QWidget *parent_, const char *name = "mainStatusBar"); + static StatusBar *instance() { + return singletonStatusBar_ + ; + } + /** + * Start a progress operation, if owner is 0, the return value is + * undefined - the application will probably crash. + * @param owner controls progress for this operation + * @return the progressBar so you can configure its parameters + * @see setProgress( QObject*, int ) + * @see incrementProgress( QObject* ) + * @see setProgressStatus( const QObject*, const QString& ) + */ + ProgressBar &newProgressOperation(QObject *owner); + + void setProgress(const QObject *owner, int steps); + void incrementProgress(const QObject *owner); + void setProgressStatus(const QObject *owner, const QString &text); + public slots: + void setMainText(const QString &text); + void resetMainText(); + void shortMessage(const QString &text); + /** Stop anticipating progress from sender() */ + //void endProgressOperation(); + + /** Stop anticipating progress from @param owner */ + void endProgressOperation(QObject *owner); + + /** + * Convenience function works like setProgress( QObject*, int ) + * Uses the return value from sender() to determine the owner of + * the progress bar in question + */ + void setProgress(int steps); + + /** + * Convenience function works like incrementProgress( QObject* ) + * Uses the return value from sender() to determine the owner of + * the progress bar in question + */ + void incrementProgress(); + + public slots: + void toggleProgressWindow(bool show); + void abortAllProgressOperations(); + + private slots: + /** For internal use against KIO::Jobs */ + //void setProgress( KIO::Job*, unsigned long percent ); + void showMainProgressBar(); + void hideMainProgressBar(); + void updateProgressAppearance(); + + protected: + virtual void ensurePolished(); + // virtual void customEvent( QCustomEvent* ); + virtual void paintEvent(QPaintEvent*); + virtual bool event(QEvent*); + + /** + * You must parent the widget to the statusbar, we won't do that + * for you! The widget will be added to the right of the layout. + * Currently you must add widgets before the statusbar gets shown + * for the first time, because we are not currently very flexible. + */ + void addWidget(QWidget *widget); + + QLabel *m_mainTextLabel; + private: + void updateTotalProgress(); + bool allDone(); ///@return true if all progress operations are complete + void pruneProgressBars(); /// deletes old progress bars + + QWidget *cancelButton() { + return findChild<QWidget *>("cancelButton"); + } + QWidget *toggleProgressWindowButton() { + return findChild<QWidget *>("showAllProgressDetails"); + } + QWidget *progressBox() { + return findChild <QWidget *>("progressBox"); + } + + PopupMessage *popupProgressMessage_; + QProgressBar *mainProgressBar_; + + ProgressMap progressMap_; + // QList<QWidget *> m_messageQueue; + QString mainText_; + + QLayout *otherWidgetLayout_; + static StatusBar *singletonStatusBar_; +}; + +} // namespace FQTerm + +#endif // FQTERM_STATUSBAR_H diff --git a/src/ui/zmodemdialog.cpp b/src/ui/zmodemdialog.cpp new file mode 100644 index 0000000..629a40a --- /dev/null +++ b/src/ui/zmodemdialog.cpp @@ -0,0 +1,73 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include <QMessageBox> + +#include "fqterm_trace.h" +#include "zmodemdialog.h" + +namespace FQTerm { + +zmodemDialog::zmodemDialog(QWidget *parent_, Qt::WFlags fl) + : QDialog(parent_, fl) { + ui_.setupUi(this); + FQ_VERIFY(connect(ui_.buttonCancel, SIGNAL(clicked()), this, SLOT(slotCancel()))); +} + +zmodemDialog::~zmodemDialog(){} + +void zmodemDialog::setProgress(int offset) { + ui_.pbProgress->setValue(offset); + QString strTmp; + strTmp = QString("%1 out of %2 bytes").arg(offset).arg(ui_.pbProgress->maximum() + ); + ui_.labelStatus->setText(strTmp); +} + +void zmodemDialog::setFileInfo(const QString &name, int size) { + ui_.labelFileName->setText(name); + ui_.pbProgress->setMaximum(size); +} + +void zmodemDialog::addErrorLog(const QString &err) { + // FIXME:display error message; + //browserError->append(err); +} + +void zmodemDialog::clearErrorLog() { + //browserError->clear(); +} + +void zmodemDialog::slotCancel() { + QMessageBox mb("FQTerm", "We dont support cancel operation yet. " + "But you can try, it will crash when downloading.\n" + "Do you want to continue?", + QMessageBox::Warning, QMessageBox::Yes, + QMessageBox::No | QMessageBox::Escape | QMessageBox::Default, + 0, this); + if (mb.exec() == QMessageBox::Yes) { + emit canceled(); + hide(); + } +} + +} // namespace FQTerm + +#include "zmodemdialog.moc" diff --git a/src/ui/zmodemdialog.h b/src/ui/zmodemdialog.h new file mode 100644 index 0000000..f310b64 --- /dev/null +++ b/src/ui/zmodemdialog.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef FQTERM_ZMODEM_DIALOG_H +#define FQTERM_ZMODEM_DIALOG_H + +#include "ui_zmodemdialog.h" + +namespace FQTerm { + +class zmodemDialog: public QDialog { + Q_OBJECT; + public: + zmodemDialog(QWidget *parent_ = 0, Qt::WFlags fl = 0); + ~zmodemDialog(); + + void setFileInfo(const QString &, int); + void addErrorLog(const QString &); + void clearErrorLog(); + void setProgress(int); + + public slots: + void slotCancel(); + + signals: + void canceled(); + + private: + Ui::zmodemDialog ui_; +}; + +} // namespace FQTerm + +#endif // FQTERM_ZMODEM_DIALOG_H diff --git a/src/ui/zmodemdialog.ui b/src/ui/zmodemdialog.ui new file mode 100644 index 0000000..9f2bb2b --- /dev/null +++ b/src/ui/zmodemdialog.ui @@ -0,0 +1,105 @@ +<ui version="4.0" > + <class>zmodemDialog</class> + <widget class="QDialog" name="zmodemDialog" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>333</width> + <height>259</height> + </rect> + </property> + <property name="windowTitle" > + <string>Zmodem Status</string> + </property> + <layout class="QGridLayout" > + <property name="margin" > + <number>9</number> + </property> + <property name="spacing" > + <number>6</number> + </property> + <item row="0" column="0" colspan="3" > + <widget class="QLabel" name="labelFileName" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Minimum" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string>textLabel1</string> + </property> + </widget> + </item> + <item row="4" column="0" > + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType" > + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>121</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="4" column="2" > + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType" > + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>111</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="4" column="1" > + <widget class="QPushButton" name="buttonCancel" > + <property name="text" > + <string>Cancel</string> + </property> + </widget> + </item> + <item row="3" column="0" colspan="3" > + <widget class="QTextBrowser" name="textBrowser" /> + </item> + <item row="2" column="0" colspan="3" > + <widget class="QLabel" name="labelStatus" > + <property name="sizePolicy" > + <sizepolicy vsizetype="Preferred" hsizetype="Expanding" > + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string>textLabel2</string> + </property> + </widget> + </item> + <item row="1" column="0" colspan="3" > + <widget class="QProgressBar" name="pbProgress" > + <property name="value" > + <number>24</number> + </property> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11" /> + <resources/> + <connections/> +</ui> |