13501
|
1 /* Quint - A graphical user interface for Octave |
|
2 * Copyright (C) 2011 Jacob Dawid |
|
3 * jacob.dawid@googlemail.com |
|
4 * |
|
5 * This program is free software: you can redistribute it and/or modify |
|
6 * it under the terms of the GNU General Public License as published by |
|
7 * the Free Software Foundation, either version 3 of the License, or |
|
8 * (at your option) any later version. |
|
9 * |
|
10 * This program is distributed in the hope that it will be useful, |
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 * GNU General Public License for more details. |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License |
|
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
17 */ |
|
18 |
|
19 #include <QMenuBar> |
|
20 #include <QMenu> |
|
21 #include <QAction> |
|
22 #include <QSettings> |
|
23 #include <QDesktopServices> |
|
24 #include <QFileDialog> |
|
25 #include "MainWindow.h" |
|
26 #include "FileEditorMdiSubWindow.h" |
|
27 #include "ImageViewerMdiSubWindow.h" |
|
28 #include "SettingsDialog.h" |
|
29 |
|
30 MainWindow::MainWindow(QWidget *parent) |
|
31 : QMainWindow(parent), |
|
32 m_isRunning(true) { |
|
33 QDesktopServices desktopServices; |
|
34 m_settingsFile = desktopServices.storageLocation(QDesktopServices::HomeLocation) + "/.quint/settings.ini"; |
|
35 construct(); |
|
36 establishOctaveLink(); |
|
37 } |
|
38 |
|
39 MainWindow::~MainWindow() { |
|
40 } |
|
41 |
|
42 void MainWindow::handleOpenFileRequest(QString fileName) { |
|
43 reportStatusMessage(tr("Opening file.")); |
|
44 QPixmap pixmap; |
|
45 if(pixmap.load(fileName)) { |
|
46 // ImageViewerMdiSubWindow *subWindow = new ImageViewerMdiSubWindow(pixmap, this); |
|
47 // subWindow->setAttribute(Qt::WA_DeleteOnClose); |
|
48 // m_centralMdiArea->addSubWindow(subWindow); |
|
49 // subWindow->setWindowTitle(fileName); |
|
50 } else { |
|
51 FileEditorMdiSubWindow *subWindow = new FileEditorMdiSubWindow(m_centralMdiArea); |
|
52 subWindow->setAttribute(Qt::WA_DeleteOnClose); |
|
53 // addSubWindow uncommented to avoid "QMdiArea::addSubWindow: window is already added" |
|
54 // m_centralMdiArea->addSubWindow(subWindow); |
|
55 subWindow->loadFile(fileName); |
|
56 } |
|
57 } |
|
58 |
|
59 void MainWindow::reportStatusMessage(QString statusMessage) { |
|
60 m_statusBar->showMessage(statusMessage, 1000); |
|
61 } |
|
62 |
|
63 void MainWindow::openWebPage(QString url) { |
|
64 m_documentationWidget->load(QUrl(url)); |
|
65 } |
|
66 |
|
67 void MainWindow::handleSaveWorkspaceRequest() { |
|
68 QDesktopServices desktopServices; |
|
69 QString selectedFile = QFileDialog::getSaveFileName(this, tr("Save Workspace"), |
|
70 desktopServices.storageLocation(QDesktopServices::HomeLocation) + "/.quint/workspace"); |
|
71 m_octaveTerminal->sendText(QString("save \'%1\'\n").arg(selectedFile)); |
|
72 m_octaveTerminal->setFocus(); |
|
73 } |
|
74 |
|
75 void MainWindow::handleLoadWorkspaceRequest() { |
|
76 QDesktopServices desktopServices; |
|
77 QString selectedFile = QFileDialog::getOpenFileName(this, tr("Load Workspace"), |
|
78 desktopServices.storageLocation(QDesktopServices::HomeLocation) + "/.quint/workspace"); |
|
79 m_octaveTerminal->sendText(QString("load \'%1\'\n").arg(selectedFile)); |
|
80 m_octaveTerminal->setFocus(); |
|
81 } |
|
82 |
|
83 void MainWindow::handleClearWorkspaceRequest() { |
|
84 m_octaveTerminal->sendText("clear\n"); |
|
85 m_octaveTerminal->setFocus(); |
|
86 } |
|
87 |
|
88 void MainWindow::handleCommandDoubleClicked(QString command) { |
|
89 m_octaveTerminal->sendText(command); |
|
90 m_octaveTerminal->setFocus(); |
|
91 } |
|
92 |
|
93 void MainWindow::alignMdiWindows() { |
|
94 m_centralMdiArea->tileSubWindows(); |
|
95 } |
|
96 |
|
97 void MainWindow::openBugTrackerPage() { |
|
98 QDesktopServices::openUrl(QUrl("http://savannah.gnu.org/bugs/?group=octave")); |
|
99 } |
|
100 |
|
101 void MainWindow::processSettingsDialogRequest() { |
|
102 SettingsDialog settingsDialog(this, m_settingsFile); |
|
103 settingsDialog.exec(); |
|
104 } |
|
105 |
|
106 void MainWindow::closeEvent(QCloseEvent *closeEvent) { |
|
107 m_isRunning = false; |
|
108 reportStatusMessage(tr("Saving data and shutting down.")); |
|
109 writeSettings(); |
|
110 |
|
111 m_octaveCallbackThread->terminate(); |
|
112 m_octaveCallbackThread->wait(); |
|
113 |
|
114 m_octaveMainThread->terminate(); |
|
115 QMainWindow::closeEvent(closeEvent); |
|
116 } |
|
117 |
|
118 void MainWindow::readSettings() { |
|
119 QSettings settings(m_settingsFile, QSettings::IniFormat); |
|
120 restoreGeometry(settings.value("MainWindow/geometry").toByteArray()); |
|
121 restoreState(settings.value("MainWindow/windowState").toByteArray()); |
|
122 } |
|
123 |
|
124 void MainWindow::writeSettings() { |
|
125 QSettings settings(m_settingsFile, QSettings::IniFormat); |
|
126 settings.setValue("MainWindow/geometry", saveGeometry()); |
|
127 settings.setValue("MainWindow/windowState", saveState()); |
|
128 } |
|
129 |
|
130 void MainWindow::construct() { |
|
131 |
|
132 if(QFile::exists("../media/logo.png")) |
|
133 setWindowIcon(QIcon("../media/logo.png")); |
|
134 else |
|
135 setWindowIcon(QIcon("/usr/share/octave/quint/media/logo.png")); |
|
136 |
|
137 // Initialize MDI area. |
|
138 m_centralMdiArea = new QMdiArea(this); |
|
139 m_centralMdiArea->setObjectName("CentralMdiArea"); |
|
140 m_centralMdiArea->setViewMode(QMdiArea::TabbedView); |
|
141 |
|
142 // Setup dockable widgets and the status bar. |
|
143 m_variablesDockWidget = new VariablesDockWidget(this); |
|
144 m_historyDockWidget = new HistoryDockWidget(this); |
|
145 m_filesDockWidget = new FilesDockWidget(this); |
|
146 m_statusBar = new QStatusBar(this); |
|
147 |
|
148 // Setup essential MDI Windows. |
|
149 m_octaveTerminal = new OctaveTerminal(this); |
|
150 m_documentationWidget = new BrowserWidget(this); |
|
151 m_ircWidget = new IRCWidget(this, m_settingsFile); |
|
152 |
|
153 m_documentationWidgetSubWindow = m_centralMdiArea->addSubWindow(m_documentationWidget, |
|
154 Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint); |
|
155 m_documentationWidgetSubWindow->setObjectName("DocumentationWidgetSubWindow"); |
|
156 m_documentationWidgetSubWindow->setWindowTitle(tr("Documentation")); |
|
157 m_documentationWidgetSubWindow->setWindowIcon(QIcon("../media/help_index.png")); |
|
158 |
|
159 m_octaveTerminalSubWindow = m_centralMdiArea->addSubWindow(m_octaveTerminal, |
|
160 Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint); |
|
161 m_octaveTerminalSubWindow->setObjectName("OctaveTerminalSubWindow"); |
|
162 m_octaveTerminalSubWindow->setWindowTitle(tr("Terminal")); |
|
163 m_octaveTerminalSubWindow->setWindowIcon(QIcon("../media/terminal.png")); |
|
164 |
|
165 m_ircWidgetSubWindow = m_centralMdiArea->addSubWindow(m_ircWidget, |
|
166 Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint); |
|
167 m_ircWidgetSubWindow->setObjectName("ChatWidgetSubWindow"); |
|
168 m_ircWidgetSubWindow->setWindowTitle(tr("Chat")); |
|
169 m_ircWidgetSubWindow->setWindowIcon(QIcon("../media/chat.png")); |
|
170 |
|
171 QMenu *controlMenu = menuBar()->addMenu(tr("Octave")); |
|
172 QAction *settingsAction = controlMenu->addAction(tr("Settings")); |
|
173 controlMenu->addSeparator(); |
|
174 QAction *exitAction = controlMenu->addAction(tr("Exit")); |
|
175 |
|
176 QMenu *interfaceMenu = menuBar()->addMenu(tr("Interface")); |
|
177 QAction *alignWindowsAction = interfaceMenu->addAction(tr("Align Windows")); |
|
178 |
|
179 QMenu *communityMenu = menuBar()->addMenu(tr("Community")); |
|
180 QAction *reportBugAction = communityMenu->addAction(tr("Report Bug")); |
|
181 |
|
182 connect(settingsAction, SIGNAL(triggered()), this, SLOT(processSettingsDialogRequest())); |
|
183 connect(exitAction, SIGNAL(triggered()), this, SLOT(close())); |
|
184 connect(alignWindowsAction, SIGNAL(triggered()), this, SLOT(alignMdiWindows())); |
|
185 connect(reportBugAction, SIGNAL(triggered()), this, SLOT(openBugTrackerPage())); |
|
186 |
|
187 setWindowTitle("Octave"); |
|
188 setCentralWidget(m_centralMdiArea); |
|
189 addDockWidget(Qt::LeftDockWidgetArea, m_variablesDockWidget); |
|
190 addDockWidget(Qt::LeftDockWidgetArea, m_historyDockWidget); |
|
191 addDockWidget(Qt::RightDockWidgetArea, m_filesDockWidget); |
|
192 setStatusBar(m_statusBar); |
|
193 |
|
194 readSettings(); |
|
195 |
|
196 connect(m_filesDockWidget, SIGNAL(openFile(QString)), this, SLOT(handleOpenFileRequest(QString))); |
|
197 connect(m_historyDockWidget, SIGNAL(information(QString)), this, SLOT(reportStatusMessage(QString))); |
|
198 connect(m_historyDockWidget, SIGNAL(commandDoubleClicked(QString)), this, SLOT(handleCommandDoubleClicked(QString))); |
|
199 connect(m_variablesDockWidget, SIGNAL(saveWorkspace()), this, SLOT(handleSaveWorkspaceRequest())); |
|
200 connect(m_variablesDockWidget, SIGNAL(loadWorkspace()), this, SLOT(handleLoadWorkspaceRequest())); |
|
201 connect(m_variablesDockWidget, SIGNAL(clearWorkspace()), this, SLOT(handleClearWorkspaceRequest())); |
|
202 |
|
203 openWebPage("http://www.gnu.org/software/octave/doc/interpreter/"); |
|
204 } |
|
205 |
|
206 void MainWindow::establishOctaveLink() { |
|
207 m_octaveMainThread = new OctaveMainThread(this); |
|
208 m_octaveMainThread->start(); |
|
209 |
|
210 m_octaveCallbackThread = new OctaveCallbackThread(this, this); |
|
211 m_octaveCallbackThread->start(); |
|
212 |
|
213 command_editor::add_event_hook(OctaveLink::readlineEventHook); |
|
214 |
|
215 int fdm, fds; |
|
216 if(openpty(&fdm, &fds, 0, 0, 0) < 0) { |
|
217 assert(0); |
|
218 } |
|
219 dup2 (fds, 0); |
|
220 dup2 (fds, 1); |
|
221 dup2 (fds, 2); |
|
222 m_octaveTerminal->openTeletype(fdm); |
|
223 reportStatusMessage(tr("Established link to Octave.")); |
|
224 } |