Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / editors / sc-ide / widgets / post_window.cpp
blob9057d334504fbb654378bc07326c832f06e44faf
1 /*
2 SuperCollider Qt IDE
3 Copyright (c) 2012 Jakob Leben & Tim Blechmann
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "main_window.hpp"
22 #include "post_window.hpp"
23 #include "../core/main.hpp"
24 #include "../core/settings/manager.hpp"
26 #include <QApplication>
27 #include <QDesktopWidget>
28 #include <QHBoxLayout>
29 #include <QLabel>
30 #include <QPointer>
31 #include <QScrollBar>
32 #include <QShortcut>
33 #include <QToolBar>
35 namespace ScIDE {
37 PostWindow::PostWindow(QWidget* parent):
38 QPlainTextEdit(parent),
39 mNewlinePending(false)
41 setReadOnly(true);
42 setLineWrapMode(QPlainTextEdit::NoWrap);
43 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
45 QRect availableScreenRect = qApp->desktop()->availableGeometry(this);
46 mSizeHint = QSize( availableScreenRect.width() / 2.7, 300 );
48 QAction * action;
50 QAction *copyAction = new QAction(tr("Copy"), this);
51 connect(copyAction, SIGNAL(triggered()), this, SLOT(copy()));
52 copyAction->setShortcut( Main::settings()->shortcut("IDE/shortcuts/copy") );
53 addAction(copyAction);
55 mClearAction = new QAction(tr("Clear"), this);
56 connect(mClearAction, SIGNAL(triggered()), this, SLOT(clear()));
57 addAction(mClearAction);
59 action = new QAction(this);
60 action->setSeparator(true);
61 addAction(action);
63 action = new QAction(tr("Enlarge Post Font"), this);
64 action->setIconText("+");
65 action->setShortcut(tr("Ctrl++", "Enlarge Font"));
66 action->setShortcutContext( Qt::WidgetShortcut );
67 action->setToolTip(tr("Enlarge font"));
68 connect(action, SIGNAL(triggered()), this, SLOT(zoomIn()));
69 addAction(action);
71 action = new QAction(tr("Shrink Post Font"), this);
72 action->setIconText("-");
73 action->setShortcut(tr("Ctrl+-", "Shrink Font"));
74 action->setToolTip(tr("Shrink font"));
75 action->setShortcutContext( Qt::WidgetShortcut );
76 connect(action, SIGNAL(triggered()), this, SLOT(zoomOut()));
77 addAction(action);
79 action = new QAction(this);
80 action->setSeparator(true);
81 addAction(action);
83 mAutoScrollAction = new QAction(tr("Auto Scroll"), this);
84 mAutoScrollAction->setToolTip(tr("Scroll to bottom on new posts"));
85 mAutoScrollAction->setCheckable(true);
86 mAutoScrollAction->setChecked(true);
87 addAction(mAutoScrollAction);
89 setContextMenuPolicy(Qt::ActionsContextMenu);
91 connect(this, SIGNAL(scrollToBottomRequest()),
92 this, SLOT(scrollToBottom()), Qt::QueuedConnection);
93 connect(mAutoScrollAction, SIGNAL(triggered(bool)),
94 this, SLOT(onAutoScrollTriggered(bool)));
96 applySettings( Main::settings() );
99 void PostWindow::applySettings(Settings::Manager * settings)
101 int scrollback = settings->value("IDE/editor/postWindowScrollback").toInt();
103 QFont font = settings->codeFont();
105 QPalette palette;
106 settings->beginGroup("IDE/editor/colors");
107 if (settings->contains("text")) {
108 QTextCharFormat format = settings->value("text").value<QTextCharFormat>();
109 QBrush bg = format.background();
110 QBrush fg = format.foreground();
111 if (bg.style() != Qt::NoBrush)
112 palette.setBrush(QPalette::Base, bg);
113 if (fg.style() != Qt::NoBrush)
114 palette.setBrush(QPalette::Text, fg);
116 settings->endGroup(); // colors
118 setMaximumBlockCount(scrollback);
119 setFont(font);
120 setPalette(palette);
123 QString PostWindow::symbolUnderCursor()
125 QTextCursor cursor = textCursor();
126 if (!cursor.hasSelection())
127 cursor.select(QTextCursor::WordUnderCursor);
128 return cursor.selectedText();
131 void PostWindow::post(const QString &text)
133 QScrollBar *scrollBar = verticalScrollBar();
134 bool scroll = mAutoScrollAction->isChecked();
136 QTextCursor c(document());
137 c.movePosition(QTextCursor::End);
139 if (mNewlinePending) {
140 c.insertBlock();
141 mNewlinePending = false;
142 c.movePosition(QTextCursor::End);
145 if ( text.endsWith("\n") ) {
146 QString textToInsert (text);
147 textToInsert.chop(1);
148 mNewlinePending = true;
149 c.insertText(textToInsert);
150 } else {
151 c.insertText(text);
154 if (scroll)
155 emit(scrollToBottomRequest());
158 void PostWindow::scrollToBottom()
160 verticalScrollBar()->triggerAction(QAbstractSlider::SliderToMaximum);
163 void PostWindow::onAutoScrollTriggered(bool on)
165 if (on)
166 scrollToBottom();
169 void PostWindow::zoomIn(int steps)
171 zoomFont(steps);
174 void PostWindow::zoomOut(int steps)
176 zoomFont(-steps);
179 void PostWindow::zoomFont(int steps)
181 QFont currentFont = font();
182 const int newSize = currentFont.pointSize() + steps;
183 if (newSize <= 0)
184 return;
185 currentFont.setPointSize(newSize);
186 setFont(currentFont);
189 void PostWindow::wheelEvent( QWheelEvent * e )
191 if (e->modifiers() == Qt::ControlModifier) {
192 if (e->delta() > 0)
193 zoomIn();
194 else
195 zoomOut();
196 return;
199 QPlainTextEdit::wheelEvent(e);
202 void PostWindow::focusOutEvent( QFocusEvent * event )
204 MainWindow::instance()->focusCodeEditor();
205 event->accept();
208 bool PostWindow::openDocumentation()
210 return Main::openDocumentation(symbolUnderCursor());
213 void PostWindow::openDefinition()
215 Main::openDefinition(symbolUnderCursor(), MainWindow::instance());
218 void PostWindow::findReferences()
220 Main::findReferences(symbolUnderCursor(), MainWindow::instance());
224 PostDock::PostDock(QWidget* parent):
225 QDockWidget(tr("Post window"), parent)
227 setAllowedAreas(Qt::BottomDockWidgetArea | Qt::RightDockWidgetArea | Qt::LeftDockWidgetArea);
228 setFeatures(DockWidgetFloatable | DockWidgetMovable | DockWidgetClosable);
230 mPostWindow = new PostWindow(this);
231 setWidget(mPostWindow);
233 QToolBar *toolBar = new QToolBar();
234 toolBar->addAction(mPostWindow->mAutoScrollAction);
236 QWidget *titleBar = new QWidget();
237 QHBoxLayout *l = new QHBoxLayout();
238 l->setContentsMargins(5,2,5,0);
239 l->addWidget(new QLabel(windowTitle()), 1);
240 l->addWidget(toolBar);
241 titleBar->setLayout(l);
243 setTitleBarWidget(titleBar);
245 connect(this, SIGNAL(topLevelChanged(bool)), this, SLOT(onFloatingChanged(bool)));
248 void PostDock::onFloatingChanged(bool floating)
250 // HACK: After undocking when main window maximized, the dock widget can not be
251 // resized anymore. Apparently it has to do something with the fact that the dock
252 // widget spans from edge to edge of the screen.
253 // The issue is avoided by slightly shrinking the dock widget.
254 if (floating)
255 resize(size() - QSize(1,1));
258 } // namespace ScIDE