summaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/CMakeLists.txt122
-rw-r--r--src/ui/aboutdialog.cpp71
-rw-r--r--src/ui/aboutdialog.h39
-rw-r--r--src/ui/aboutdialog.ui175
-rw-r--r--src/ui/addrdialog.cpp396
-rw-r--r--src/ui/addrdialog.h87
-rw-r--r--src/ui/addrdialog.ui1211
-rw-r--r--src/ui/articledialog.cpp105
-rw-r--r--src/ui/articledialog.h52
-rw-r--r--src/ui/articledialog.ui132
-rw-r--r--src/ui/defineescape.cpp51
-rw-r--r--src/ui/defineescape.h44
-rw-r--r--src/ui/defineescape.ui68
-rw-r--r--src/ui/fqterm_canvas.cpp537
-rw-r--r--src/ui/fqterm_canvas.h105
-rw-r--r--src/ui/fqterm_time_label.cpp50
-rw-r--r--src/ui/fqterm_time_label.h44
-rw-r--r--src/ui/fqterm_tool_button.cpp41
-rw-r--r--src/ui/fqterm_tool_button.h46
-rw-r--r--src/ui/imageviewer.cpp1749
-rw-r--r--src/ui/imageviewer.h336
-rw-r--r--src/ui/iplookup.cpp56
-rw-r--r--src/ui/iplookup.h43
-rw-r--r--src/ui/iplookup.ui76
-rw-r--r--src/ui/keydialog.cpp285
-rw-r--r--src/ui/keydialog.h63
-rw-r--r--src/ui/keydialog.ui665
-rw-r--r--src/ui/msgdialog.cpp43
-rw-r--r--src/ui/msgdialog.h35
-rw-r--r--src/ui/msgdialog.ui86
-rw-r--r--src/ui/osdmessage.cpp210
-rw-r--r--src/ui/osdmessage.h69
-rw-r--r--src/ui/overlayWidget.cpp84
-rw-r--r--src/ui/overlayWidget.h51
-rw-r--r--src/ui/pictureflow.cpp1201
-rw-r--r--src/ui/pictureflow.h198
-rw-r--r--src/ui/popupMessage.cpp316
-rw-r--r--src/ui/popupMessage.h116
-rw-r--r--src/ui/popwidget.cpp177
-rw-r--r--src/ui/popwidget.h70
-rw-r--r--src/ui/prefdialog.cpp332
-rw-r--r--src/ui/prefdialog.h66
-rw-r--r--src/ui/prefdialog.ui644
-rw-r--r--src/ui/progressBar.cpp100
-rw-r--r--src/ui/progressBar.h71
-rw-r--r--src/ui/quickdialog.cpp258
-rw-r--r--src/ui/quickdialog.h73
-rw-r--r--src/ui/quickdialog.ui211
-rw-r--r--src/ui/schemadialog.cpp323
-rw-r--r--src/ui/schemadialog.h80
-rw-r--r--src/ui/schemadialog.ui539
-rw-r--r--src/ui/shortcutdialog.cpp176
-rw-r--r--src/ui/shortcutdialog.h61
-rw-r--r--src/ui/sitemanager.cpp412
-rw-r--r--src/ui/sitemanager.h104
-rw-r--r--src/ui/sitemanager.ui593
-rw-r--r--src/ui/soundconf.cpp178
-rw-r--r--src/ui/soundconf.h57
-rw-r--r--src/ui/soundconf.ui162
-rw-r--r--src/ui/sshlogin.ui75
-rw-r--r--src/ui/sshlogindialog.cpp80
-rw-r--r--src/ui/sshlogindialog.h45
-rw-r--r--src/ui/statusBar.cpp530
-rw-r--r--src/ui/statusBar.h148
-rw-r--r--src/ui/zmodemdialog.cpp73
-rw-r--r--src/ui/zmodemdialog.h51
-rw-r--r--src/ui/zmodemdialog.ui105
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>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
+p, li { white-space: pre-wrap; }
+&lt;/style>&lt;/head>&lt;body>
+&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">&lt;br />FQTerm&lt;br />&lt;br />&lt;br />&lt;a href="http://code.google.com/p/fqterm">&lt;span style=" text-decoration: underline; color:#0000ff;">http://code.google.com/p/fqterm&lt;/span>&lt;/a>&lt;/p>&lt;/body>&lt;/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>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
+p, li { white-space: pre-wrap; }
+&lt;/style>&lt;/head>&lt;body style=" font-family:'SimSun'; font-size:9pt; font-weight:400; font-style:normal;">
+&lt;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;">&lt;/p>&lt;/body>&lt;/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 (&amp;Temporarily)</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QPushButton" name="closePushButton">
+ <property name="text">
+ <string>&amp;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>&amp;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 &amp; 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>&amp;Up</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QPushButton" name="downButton" >
+ <property name="text" >
+ <string>&amp;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>&amp;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&amp;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>&amp;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>&amp;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&amp;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>&amp;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>&amp;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>