Fix no newlines warnings. Patch by Peter Oberndorfer
[kdevelopdvcssupport.git] / sublime / ideal.cpp
blob27b9b8e51ba7ae446a2f615db39745ed372ab8ec
1 /*
2 Copyright 2007 Roberto Raggi <roberto@kdevelop.org>
3 Copyright 2007 Hamish Rodda <rodda@kde.org>
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 #include "ideal.h"
24 #include <QMainWindow>
25 #include <QStylePainter>
26 #include <KIcon>
27 #include <kdebug.h>
28 #include <klocale.h>
29 #include <KActionCollection>
30 #include <KActionMenu>
31 #include <KAcceleratorManager>
32 #include <KMenu>
33 #include <KToolBar>
35 #include "area.h"
36 #include "view.h"
37 #include "document.h"
38 #include "mainwindow.h"
40 using namespace Sublime;
42 IdealToolButton::IdealToolButton(Qt::DockWidgetArea area, QWidget *parent)
43 : QToolButton(parent), _area(area)
45 setFocusPolicy(Qt::NoFocus);
46 KAcceleratorManager::setNoAccel(this);
47 setCheckable(true);
48 setAutoRaise(true);
49 setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
52 Qt::Orientation IdealToolButton::orientation() const
54 if (_area == Qt::LeftDockWidgetArea || _area == Qt::RightDockWidgetArea)
55 return Qt::Vertical;
57 return Qt::Horizontal;
60 QSize IdealToolButton::sizeHint() const
62 ensurePolished();
64 QStyleOptionToolButton opt;
65 initStyleOption(&opt);
67 QFontMetrics fm = fontMetrics();
69 const int charWidth = fm.width(QLatin1Char('x'));
71 QSize textSize = fm.size(Qt::TextShowMnemonic, opt.text);
72 textSize.rwidth() += 2 * charWidth;
74 const int spacing = 2; // ### FIXME
75 int width = 4 + textSize.width() + opt.iconSize.width() + spacing;
76 int height = 4 + qMax(textSize.height(), opt.iconSize.height());
78 if (orientation() == Qt::Vertical)
79 return QSize(height, width);
81 return QSize(width, height);
84 void IdealToolButton::paintEvent(QPaintEvent *event)
86 if (_area == Qt::TopDockWidgetArea || _area == Qt::BottomDockWidgetArea) {
87 QToolButton::paintEvent(event);
88 } else {
89 QStyleOptionToolButton opt;
90 initStyleOption(&opt);
91 opt.rect.setSize(QSize(opt.rect.height(), opt.rect.width()));
93 QPixmap pix(opt.rect.width(), opt.rect.height());
94 QStylePainter painter(&pix, this);
95 painter.fillRect(pix.rect(), opt.palette.background());
96 painter.drawComplexControl(QStyle::CC_ToolButton, opt);
97 painter.end();
99 QPainter p(this);
101 if (_area == Qt::LeftDockWidgetArea) {
102 p.translate(0, height());
103 p.rotate(-90);
104 } else {
105 p.translate(width(), 0);
106 p.rotate(90);
109 p.drawPixmap(0, 0, pix);
113 IdealButtonBarWidget::IdealButtonBarWidget(Qt::DockWidgetArea area, IdealMainWidget *parent)
114 : QWidget(parent)
115 , _area(area)
116 , _actions(new QActionGroup(this))
118 // TODO Only for now...
119 _actions->setExclusive(true);
121 (void) new IdealButtonBarLayout(orientation(), this);
124 KAction *IdealButtonBarWidget::addWidget(const QString& title, IdealDockWidget *dock,
125 Area *area, View *view)
127 kDebug() << "adding widget";
128 KAction *action = new KAction(this);
129 action->setCheckable(true);
130 action->setText(title);
131 action->setIcon(dock->windowIcon());
133 if (_area == Qt::BottomDockWidgetArea || _area == Qt::TopDockWidgetArea)
134 dock->setFeatures( dock->features() | IdealDockWidget::DockWidgetVerticalTitleBar );
136 dock->setArea(area);
137 dock->setView(view);
138 dock->setDockWidgetArea(_area);
140 connect(dock, SIGNAL(anchor(bool)), SLOT(anchor(bool)));
141 connect(dock, SIGNAL(maximize(bool)), SLOT(maximize(bool)));
143 _widgets[action] = dock;
144 connect(action, SIGNAL(toggled(bool)), this, SLOT(showWidget(bool)));
146 addAction(action);
147 _actions->addAction(action);
149 return action;
152 void IdealButtonBarWidget::removeAction(QAction * action)
154 _widgets.remove(action);
155 delete _buttons.take(action);
156 delete action;
159 Qt::Orientation IdealButtonBarWidget::orientation() const
161 if (_area == Qt::LeftDockWidgetArea || _area == Qt::RightDockWidgetArea)
162 return Qt::Vertical;
164 return Qt::Horizontal;
167 void IdealButtonBarWidget::showWidget(bool checked)
169 Q_ASSERT(parentWidget() != 0);
171 QAction *action = qobject_cast<QAction *>(sender());
172 Q_ASSERT(action);
174 IdealDockWidget *widget = _widgets.value(action);
175 Q_ASSERT(widget);
177 parentWidget()->showDockWidget(widget, checked);
180 void IdealButtonBarWidget::anchor(bool anchor)
182 parentWidget()->anchorDockWidget(anchor, this);
185 void IdealButtonBarWidget::maximize(bool maximized)
187 parentWidget()->maximizeDockWidget(maximized, this);
190 void IdealButtonBarWidget::actionEvent(QActionEvent *event)
192 QAction *action = qobject_cast<QAction *>(event->action());
193 if (! action)
194 return;
196 switch (event->type()) {
197 case QEvent::ActionAdded: {
198 if (! _buttons.contains(action)) {
199 IdealToolButton *button = new IdealToolButton(_area);
200 _buttons.insert(action, button);
202 button->setText(action->text());
203 button->setIcon(action->icon());
204 button->setShortcut(QKeySequence());
205 button->setChecked(action->isChecked());
206 layout()->addWidget(button);
207 connect(action, SIGNAL(toggled(bool)), SLOT(actionToggled(bool)));
208 connect(button, SIGNAL(toggled(bool)), action, SLOT(setChecked(bool)));
210 } break;
212 case QEvent::ActionRemoved: {
213 if (IdealToolButton *button = _buttons.value(action)) {
214 for (int index = 0; index < layout()->count(); ++index) {
215 if (QLayoutItem *item = layout()->itemAt(index)) {
216 if (item->widget() == button) {
217 action->disconnect(this);
218 delete layout()->takeAt(index);
219 layout()->invalidate();
220 break;
225 } break;
227 case QEvent::ActionChanged: {
228 if (IdealToolButton *button = _buttons.value(action)) {
229 button->setText(action->text());
230 button->setIcon(action->icon());
231 button->setShortcut(QKeySequence());
232 Q_ASSERT(_widgets.contains(action));
233 _widgets[action]->setWindowTitle(action->text());
235 } break;
237 default:
238 break;
242 void IdealButtonBarWidget::actionToggled(bool state)
244 QAction* action = qobject_cast<QAction*>(sender());
245 Q_ASSERT(action);
247 IdealToolButton* button = _buttons.value(action);
248 Q_ASSERT(button);
250 bool blocked = button->blockSignals(true);
251 button->setChecked(state);
252 button->blockSignals(blocked);
255 IdealDockWidget::IdealDockWidget(QWidget *parent)
256 : QDockWidget(parent),
257 m_area(0),
258 m_view(0),
259 m_docking_area(Qt::NoDockWidgetArea),
260 m_maximized(false)
263 QAbstractButton *floatButton =
264 qFindChild<QAbstractButton *>(this, QLatin1String("qt_dockwidget_floatbutton"));
266 QAbstractButton *closeButton =
267 qFindChild<QAbstractButton *>(this, QLatin1String("qt_dockwidget_closebutton"));
269 if (floatButton && closeButton) {
270 disconnect(floatButton, SIGNAL(clicked()), 0, 0);
271 disconnect(closeButton, SIGNAL(clicked()), 0, 0);
273 m_anchor = floatButton;
274 m_anchor->setCheckable(true);
275 m_anchor->setToolTip(i18n("Lock the tool"));
276 m_anchor->setWhatsThis(i18n("<b>Lock the tool</b><p>When a tool is unlocked, it "
277 "will be automatically hidden when you click outside it. "
278 "A locked tool will remain visible until you explicitly "
279 "hide it, or switch to a different tool."));
280 connect(m_anchor, SIGNAL(toggled(bool)), SIGNAL(anchor(bool)));
282 m_close = closeButton;
283 m_close->setToolTip(i18n("Remove the tool"));
284 m_close->setWhatsThis(i18n("<b>Remove the tool</b><p>Removes this tool completely. "
285 "You can add the tool again by using the "
286 "<tt>View->Add Tool View</tt> command."));
287 connect(m_close, SIGNAL(clicked(bool)), this, SLOT(slotRemove()));
291 IdealDockWidget::~IdealDockWidget()
295 Area *IdealDockWidget::area() const
296 { return m_area; }
298 void IdealDockWidget::setArea(Area *area)
299 { m_area = area; }
301 View *IdealDockWidget::view() const
302 { return m_view; }
304 void IdealDockWidget::setView(View *view)
305 { m_view = view; }
307 Qt::DockWidgetArea IdealDockWidget::dockWidgetArea() const
308 { return m_docking_area; }
310 void IdealDockWidget::setDockWidgetArea(Qt::DockWidgetArea dockingArea)
311 { m_docking_area = dockingArea; }
313 void IdealDockWidget::mouseDoubleClickEvent(QMouseEvent *event)
315 event->accept();
316 setMaximized(!isMaximized());
317 slotMaximize(isMaximized());
320 bool IdealDockWidget::isMaximized() const
321 { return m_maximized; }
323 void IdealDockWidget::setMaximized(bool maximized)
324 { m_maximized = maximized; }
326 bool IdealDockWidget::event(QEvent *e)
327 { return QWidget::event(e); }
329 bool IdealDockWidget::isAnchored() const
330 { return m_anchor->isChecked(); }
332 void IdealDockWidget::setAnchored(bool anchored, bool emitSignals)
334 bool blocked = false;
336 if (!emitSignals)
337 blocked = m_anchor->blockSignals(true);
339 m_anchor->setChecked(anchored);
341 if (!emitSignals)
342 m_anchor->blockSignals(blocked);
345 void IdealDockWidget::slotMaximize(bool maximized)
347 #if 0 // ### fixme
348 QStyle::StandardPixmap pix;
350 if (maximized)
351 pix = QStyle::SP_TitleBarNormalButton;
352 else
353 pix = QStyle::SP_TitleBarMaxButton;
355 m_maximize->setIcon(style()->standardPixmap(pix));
356 #endif
358 emit maximize(maximized);
361 void IdealDockWidget::slotRemove()
363 m_area->removeToolView(m_view);
366 void IdealDockWidget::contextMenuEvent(QContextMenuEvent *event)
368 KMenu menu;
370 menu.addTitle(i18n("Position"));
372 QActionGroup *g = new QActionGroup(this);
374 QAction *left = new QAction(i18n("Left"), g);
375 QAction *bottom = new QAction(i18n("Bottom"), g);
376 QAction *right = new QAction(i18n("Right"), g);
377 QAction *top = new QAction(i18n("Top"), g);
379 QAction* actions[] = {left, bottom, right, top};
380 for (int i = 0; i < 4; ++i)
382 menu.addAction(actions[i]);
383 actions[i]->setCheckable(true);
385 if (m_docking_area == Qt::TopDockWidgetArea)
386 top->setChecked(true);
387 else if (m_docking_area == Qt::BottomDockWidgetArea)
388 bottom->setChecked(true);
389 else if (m_docking_area == Qt::LeftDockWidgetArea)
390 left->setChecked(true);
391 else
392 right->setChecked(true);
394 QAction* triggered = menu.exec(event->globalPos());
396 if (triggered)
398 Sublime::Position pos;
399 if (triggered == left)
400 pos = Sublime::Left;
401 else if (triggered == bottom)
402 pos = Sublime::Bottom;
403 else if (triggered == right)
404 pos = Sublime::Right;
405 else
406 pos = Sublime::Top;
408 Area *area = m_area;
409 View *view = m_view;
410 /* This call will delete *this, so we no longer
411 can access member variables. */
412 m_area->moveToolView(m_view, pos);
413 area->raiseToolView(view);
417 IdealMainWidget::IdealMainWidget(MainWindow* parent, KActionCollection* ac)
418 : QWidget(parent)
419 , m_centralWidgetFocusing(false), m_switchingDocksShown(false)
421 leftBarWidget = new IdealButtonBarWidget(Qt::LeftDockWidgetArea, this);
422 leftBarWidget->hide();
424 rightBarWidget = new IdealButtonBarWidget(Qt::RightDockWidgetArea, this);
425 rightBarWidget->hide();
427 bottomBarWidget = new IdealButtonBarWidget(Qt::BottomDockWidgetArea, this);
428 bottomBarWidget->hide();
430 topBarWidget = new IdealButtonBarWidget(Qt::TopDockWidgetArea, this);
431 topBarWidget->hide();
433 m_mainLayout = new IdealMainLayout(this);
434 m_mainLayout->addButtonBar(leftBarWidget, IdealMainLayout::Left);
435 m_mainLayout->addButtonBar(rightBarWidget, IdealMainLayout::Right);
436 m_mainLayout->addButtonBar(topBarWidget, IdealMainLayout::Top);
437 m_mainLayout->addButtonBar(bottomBarWidget, IdealMainLayout::Bottom);
439 setLayout(m_mainLayout);
441 connect(parent, SIGNAL(settingsLoaded()), m_mainLayout, SLOT(loadSettings()));
443 KAction* action = m_showLeftDock = new KAction(i18n("Show Left Dock"), this);
444 action->setCheckable(true);
445 action->setShortcut(Qt::META | Qt::CTRL | Qt::Key_L);
446 connect(action, SIGNAL(toggled(bool)), SLOT(showLeftDock(bool)));
447 ac->addAction("show_left_dock", action);
449 m_showRightDock = action = new KAction(i18n("Show Right Dock"), this);
450 action->setCheckable(true);
451 action->setShortcut(Qt::META | Qt::CTRL | Qt::Key_R);
452 connect(action, SIGNAL(toggled(bool)), SLOT(showRightDock(bool)));
453 ac->addAction("show_right_dock", action);
455 m_showBottomDock = action = new KAction(i18n("Show Bottom Dock"), this);
456 action->setCheckable(true);
457 action->setShortcut(Qt::META | Qt::CTRL | Qt::Key_B);
458 connect(action, SIGNAL(toggled(bool)), SLOT(showBottomDock(bool)));
459 ac->addAction("show_bottom_dock", action);
461 m_showTopDock = action = new KAction(i18n("Show Top Dock"), this);
462 action->setCheckable(true);
463 action->setShortcut(Qt::META | Qt::CTRL | Qt::Key_T);
464 connect(action, SIGNAL(toggled(bool)), SLOT(showTopDock(bool)));
465 ac->addAction("show_top_dock", action);
467 action = new KAction(i18n("Hide/Restore Docks"), this);
468 action->setShortcut(Qt::META | Qt::CTRL | Qt::Key_H);
469 connect(action, SIGNAL(triggered(bool)), SLOT(toggleDocksShown()));
470 ac->addAction("hide_all_docks", action);
472 action = new KAction(i18n("Focus Editor"), this);
473 action->setShortcut(Qt::META | Qt::CTRL | Qt::Key_E);
474 connect(action, SIGNAL(triggered(bool)), SLOT(focusEditor()));
475 ac->addAction("focus_editor", action);
477 m_anchorCurrentDock = action = new KAction(i18n("Anchor Current Dock"), this);
478 action->setCheckable(true);
479 action->setEnabled(false);
480 action->setShortcut(Qt::META | Qt::CTRL | Qt::Key_A);
481 connect(action, SIGNAL(toggled(bool)), SLOT(anchorCurrentDock(bool)));
482 ac->addAction("anchor_current_dock", action);
484 m_maximizeCurrentDock = action = new KAction(i18n("Maximize Current Dock"), this);
485 action->setCheckable(true);
486 action->setEnabled(false);
487 connect(action, SIGNAL(toggled(bool)), SLOT(maximizeCurrentDock(bool)));
488 ac->addAction("maximize_current_dock", action);
490 action = new KAction(i18n("Select Next Dock"), this);
491 action->setShortcut(Qt::META | Qt::CTRL | Qt::Key_N);
492 connect(action, SIGNAL(triggered(bool)), SLOT(selectNextDock()));
493 ac->addAction("select_next_dock", action);
495 action = new KAction(i18n("Select Previous Dock"), this);
496 action->setShortcut(Qt::META | Qt::CTRL | Qt::Key_P);
497 connect(action, SIGNAL(triggered(bool)), SLOT(selectPreviousDock()));
498 ac->addAction("select_previous_dock", action);
500 action = new KAction(i18n("Remove view"), this);
501 connect(action, SIGNAL(triggered(bool)), SLOT(removeView()));
502 ac->addAction("remove_view", action);
504 action = m_docks = new KActionMenu(i18n("Docks"), this);
505 ac->addAction("docks_submenu", action);
508 void IdealMainWidget::addView(Qt::DockWidgetArea area, View* view)
510 IdealDockWidget *dock = new IdealDockWidget(this);
512 KAcceleratorManager::setNoAccel(dock);
513 QWidget *w = view->widget(dock);
514 if (w->parent() == 0)
516 /* Could happen when we're moving the widget from
517 one IdealDockWidget to another. See moveView below.
518 In this case, we need to reparent the widget. */
519 w->setParent(dock);
522 QList<QAction *> toolBarActions = view->toolBarActions();
523 if (toolBarActions.isEmpty()) {
524 dock->setWidget(w);
525 } else {
526 QMainWindow *toolView = new QMainWindow();
527 KToolBar *toolBar = new KToolBar(toolView);
528 int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize);
529 toolBar->setIconSize(QSize(iconSize, iconSize));
530 toolBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
531 toolBar->setWindowTitle(i18n("%1 Tool Bar", w->windowTitle()));
532 toolBar->setFloatable(false);
533 toolBar->setMovable(false);
534 foreach (QAction *action, toolBarActions) {
535 toolBar->addAction(action);
537 toolView->setCentralWidget(w);
538 toolView->addToolBar(toolBar);
539 dock->setWidget(toolView);
542 dock->setWindowTitle(view->widget()->windowTitle());
543 dock->setWindowIcon(view->widget()->windowIcon());
544 dock->setAutoFillBackground(true);
545 dock->setFocusProxy(dock->widget());
547 if (IdealButtonBarWidget* bar = barForRole(roleForArea(area))) {
548 KAction* action = bar->addWidget(
549 view->document()->title(), dock,
550 static_cast<MainWindow*>(parent())->area(), view);
551 m_dockwidget_to_action[dock] = m_view_to_action[view] = action;
552 m_docks->addAction(action);
553 bar->show();
556 dock->hide();
558 docks[dock] = area;
561 KAction * Sublime::IdealMainWidget::actionForRole(IdealMainLayout::Role role) const
563 switch (role) {
564 case IdealMainLayout::Left:
565 default:
566 return m_showLeftDock;
567 case IdealMainLayout::Right:
568 return m_showRightDock;
569 case IdealMainLayout::Top:
570 return m_showTopDock;
571 case IdealMainLayout::Bottom:
572 return m_showBottomDock;
576 void IdealMainWidget::centralWidgetFocused()
578 m_centralWidgetFocusing = true;
580 for (IdealMainLayout::Role role = IdealMainLayout::Left; role <= IdealMainLayout::Top; role = static_cast<IdealMainLayout::Role>(role + 1))
581 if (!m_mainLayout->isAreaAnchored(role))
582 actionForRole(role)->setChecked(false);
584 m_centralWidgetFocusing = false;
587 // helper for toggleDocksShown
588 bool IdealMainWidget::allDocksHidden()
590 foreach(QAction* shown, m_view_to_action) {
591 if (shown->isChecked()) return false;
593 return true;
596 // helper for toggleDocksShown
597 bool IdealMainWidget::someDockMaximized()
599 QMapIterator<IdealDockWidget*, Qt::DockWidgetArea> it(docks);
600 while(it.hasNext()) {
601 it.next();
602 if (it.key() && it.key()->isMaximized()) {
603 return true;
606 return false;
609 // helper for toggleDocksShown
610 void IdealMainWidget::restorePreviouslyShownDocks()
612 kDebug() << "";
613 foreach(View* v, m_previouslyShownDocks) {
614 if (v && m_view_to_action.contains(v)) {
615 m_view_to_action[v]->setChecked(true);
620 // helper for toggleDocksShown
621 void IdealMainWidget::hideAllShownDocks()
623 kDebug() << "";
624 m_previouslyShownDocks.clear();
625 QMapIterator<View*, QAction*> it(m_view_to_action);
626 while(it.hasNext()) {
627 it.next();
628 if (it.value() && it.value()->isChecked()) {
629 m_previouslyShownDocks << it.key();
630 it.value()->setChecked(false);
633 centralWidgetFocused();
636 void IdealMainWidget::toggleDocksShown()
638 kDebug() << "";
639 if (m_switchingDocksShown || someDockMaximized()) {
640 return;
642 m_switchingDocksShown = true;
643 if (allDocksHidden()) {
644 restorePreviouslyShownDocks();
645 } else {
646 hideAllShownDocks();
648 m_switchingDocksShown = false;
651 void IdealMainWidget::raiseView(View * view)
653 QAction* action = m_view_to_action.value(view);
654 Q_ASSERT(action);
656 action->setChecked(true);
659 void IdealMainWidget::removeView(View* view, bool nondestructive)
661 Q_ASSERT(m_view_to_action.contains(view));
662 m_previouslyShownDocks.removeOne(view);
663 QAction* action = m_view_to_action.value(view);
665 QWidget *viewParent = view->widget()->parentWidget();
666 IdealDockWidget *dock = qobject_cast<IdealDockWidget *>(viewParent);
667 if (!dock) { // toolviews with a toolbar live in a QMainWindow which lives in a Dock
668 Q_ASSERT(qobject_cast<QMainWindow*>(viewParent));
669 viewParent = viewParent->parentWidget();
670 dock = qobject_cast<IdealDockWidget*>(viewParent);
672 Q_ASSERT(dock);
674 /* Hide the view, first. This is a workaround -- if we
675 try to remove IdealDockWidget without this, then eventually
676 a call to IdealMainLayout::takeAt will be made, which
677 method asserts immediately. */
678 action->setChecked(false);
680 if (IdealButtonBarWidget* bar = barForRole(roleForArea(docks.value(dock))))
681 bar->removeAction(action);
683 m_view_to_action.remove(view);
684 m_dockwidget_to_action.remove(dock);
686 if (nondestructive)
687 view->widget()->setParent(0);
689 delete dock;
692 void IdealMainWidget::moveView(View *view, Qt::DockWidgetArea area)
694 removeView(view);
695 addView(area, view);
698 void IdealMainWidget::setCentralWidget(QWidget * widget)
700 m_mainLayout->addWidget(widget, IdealMainLayout::Central);
703 void IdealMainWidget::anchorCurrentDock(bool anchor)
705 if (IdealDockWidget* dw = m_mainLayout->lastDockWidget()) {
706 if (!dw->isVisible())
707 return setAnchorActionStatus(dw->isAnchored());
709 dw->setAnchored(anchor, true);
713 void IdealMainWidget::maximizeCurrentDock(bool maximized)
715 if (IdealDockWidget* dw = m_mainLayout->lastDockWidget()) {
716 if (!dw->isVisible())
717 return setMaximizeActionStatus(false);
719 dw->setMaximized(maximized);
723 void IdealMainWidget::anchorDockWidget(bool checked, IdealButtonBarWidget * bar)
725 m_mainLayout->anchorWidget(checked, roleForBar(bar));
728 void IdealMainWidget::maximizeDockWidget(bool checked, IdealButtonBarWidget * bar)
730 IdealDockWidget* widget = 0;
731 if (checked) {
732 IdealMainLayout::Role role = roleForBar(bar);
733 widget = mainLayout()->lastDockWidget(role);
736 m_mainLayout->maximizeWidget(widget);
738 setMaximizeActionStatus(widget);
741 void IdealMainWidget::anchorDockWidget(IdealDockWidget * dock, bool anchor)
743 Q_ASSERT(docks.contains(dock));
745 m_mainLayout->anchorWidget(anchor, roleForArea(docks.value(dock)));
748 void IdealMainWidget::showDockWidget(IdealDockWidget * dock, bool show)
750 Q_ASSERT(docks.contains(dock));
752 IdealMainLayout::Role role = roleForArea(docks.value(dock));
754 dock->setAnchored(m_mainLayout->isAreaAnchored(role), false);
756 if (show) {
757 m_mainLayout->addWidget(dock, role);
759 bool isMaximized = dock->isMaximized();
760 if (isMaximized)
761 m_mainLayout->maximizeWidget(dock);
763 } else {
764 m_mainLayout->removeWidget(dock, role);
766 setMaximizeActionStatus(false);
769 m_maximizeCurrentDock->setEnabled(show);
770 m_anchorCurrentDock->setEnabled(show);
772 setShowDockStatus(role, show);
773 Sublime::Position pos;
774 if (role == IdealMainLayout::Left)
775 pos = Sublime::Left;
776 else if (role == IdealMainLayout::Right)
777 pos = Sublime::Right;
778 else if (role == IdealMainLayout::Top)
779 pos = Sublime::Top;
780 else if (role == IdealMainLayout::Bottom)
781 pos = Sublime::Bottom;
782 else
784 Q_ASSERT (0 && "unexpect position");
786 emit dockShown(dock->view(), pos, show);
788 // Put the focus back on the editor if a dock was hidden
789 if (!show)
790 focusEditor();
793 IdealSplitterHandle::IdealSplitterHandle(Qt::Orientation orientation, QWidget* parent, IdealMainLayout::Role resizeRole)
794 : QWidget(parent)
795 , m_orientation(orientation)
796 , m_hover(false)
797 , m_resizeRole(resizeRole)
799 setCursor(orientation == Qt::Horizontal ? Qt::SplitVCursor : Qt::SplitHCursor);
800 setMouseTracking(true);
801 setAutoFillBackground(true);
804 void IdealSplitterHandle::paintEvent(QPaintEvent *)
806 QStylePainter painter(this);
807 QStyleOption options;
808 options.initFrom(this);
810 if (m_orientation == Qt::Vertical)
811 options.state |= QStyle::State_Horizontal;
813 options.state |= QStyle::State_Enabled;
815 painter.drawControl(QStyle::CE_Splitter, options);
818 void IdealSplitterHandle::mouseMoveEvent(QMouseEvent * event)
820 if (!(event->buttons() & Qt::LeftButton))
821 return;
823 int thickness = convert(parentWidget()->mapFromGlobal(event->globalPos())) - m_dragStart;
825 switch (m_resizeRole) {
826 case IdealMainLayout::Right:
827 thickness = parentWidget()->size().width() - thickness;
828 break;
829 case IdealMainLayout::Bottom:
830 thickness = parentWidget()->size().height() - thickness;
831 break;
832 default:
833 break;
836 emit resize(thickness, m_resizeRole);
839 void IdealSplitterHandle::mousePressEvent(QMouseEvent * event)
841 if (event->button() == Qt::LeftButton)
842 m_dragStart = convert(event->pos());
845 IdealMainWidget * IdealButtonBarWidget::parentWidget() const
847 return static_cast<IdealMainWidget *>(QWidget::parentWidget());
850 IdealMainLayout * IdealMainWidget::mainLayout() const
852 return m_mainLayout;
855 void IdealMainWidget::showDock(IdealMainLayout::Role role, bool show)
857 // If the dock is shown but not focused, first focus it, a second press of the shortcut will hide it
858 if (!m_centralWidgetFocusing) {
859 if (IdealDockWidget* widget = mainLayout()->lastDockWidget(role)) {
860 if (widget->isVisible() && !widget->hasFocus()) {
861 widget->setFocus(Qt::ShortcutFocusReason);
863 // re-sync action state given we may have asked for the dock to be hidden
864 KAction* action = actionForRole(role);
865 if (!action->isChecked()) {
866 action->blockSignals(true);
867 action->setChecked(true);
868 action->blockSignals(false);
870 return;
875 if (show) {
876 if (IdealDockWidget* widget = m_mainLayout->lastDockWidget(role))
877 if (QAction *action = m_dockwidget_to_action.value(widget))
878 return action->setChecked(show);
880 if (barForRole(role)->actions().count())
881 barForRole(role)->actions().first()->setChecked(show);
883 } else {
884 foreach (QAction* action, barForRole(role)->actions())
885 if (action->isChecked())
886 action->setChecked(false);
888 // Focus editor
889 focusEditor();
893 void IdealMainWidget::showLeftDock(bool show)
895 showDock(IdealMainLayout::Left, show);
898 void IdealMainWidget::showBottomDock(bool show)
900 showDock(IdealMainLayout::Bottom, show);
903 void IdealMainWidget::showTopDock(bool show)
905 showDock(IdealMainLayout::Top, show);
908 void IdealMainWidget::showRightDock(bool show)
910 showDock(IdealMainLayout::Right, show);
913 QWidget * IdealMainWidget::firstWidget(IdealMainLayout::Role role) const
915 if (IdealButtonBarWidget* button = barForRole(role))
916 if (!button->actions().isEmpty())
917 return button->widgetForAction(button->actions().first());
919 return 0;
922 IdealButtonBarWidget* IdealMainWidget::barForRole(IdealMainLayout::Role role) const
924 switch (role) {
925 case IdealMainLayout::Left:
926 return leftBarWidget;
928 case IdealMainLayout::Top:
929 return topBarWidget;
931 case IdealMainLayout::Right:
932 return rightBarWidget;
934 case IdealMainLayout::Bottom:
935 return bottomBarWidget;
937 default:
938 Q_ASSERT(false);
939 return 0;
943 IdealMainLayout::Role IdealMainWidget::roleForBar(IdealButtonBarWidget* bar) const
945 if (bar == leftBarWidget)
946 return IdealMainLayout::Left;
947 else if (bar == topBarWidget)
948 return IdealMainLayout::Top;
949 else if (bar == rightBarWidget)
950 return IdealMainLayout::Right;
951 else if (bar == bottomBarWidget)
952 return IdealMainLayout::Bottom;
954 Q_ASSERT(false);
955 return IdealMainLayout::Left;
959 QAction * IdealMainWidget::actionForView(View * view) const
961 return m_view_to_action.value(view);
964 void IdealMainWidget::setAnchorActionStatus(bool checked)
966 bool blocked = m_anchorCurrentDock->blockSignals(true);
967 m_anchorCurrentDock->setChecked(checked);
968 m_anchorCurrentDock->blockSignals(blocked);
971 void IdealMainWidget::setMaximizeActionStatus(bool checked)
973 bool blocked = m_maximizeCurrentDock->blockSignals(true);
974 m_maximizeCurrentDock->setChecked(checked);
975 m_maximizeCurrentDock->blockSignals(blocked);
978 IdealDockWidget * IdealButtonBarWidget::widgetForAction(QAction *action) const
979 { return _widgets.value(action); }
981 void IdealMainWidget::selectNextDock()
983 IdealDockWidget* dock = mainLayout()->lastDockWidget();
984 IdealMainLayout::Role role = mainLayout()->lastDockWidgetRole();
986 IdealButtonBarWidget* bar = barForRole(role);
988 int index = bar->actions().indexOf(m_dockwidget_to_action.value(dock));
990 if (index == -1 || index == bar->actions().count() - 1)
991 index = 0;
992 else
993 ++index;
995 if (index < bar->actions().count()) {
996 QAction* action = bar->actions().at(index);
997 action->setChecked(true);
1001 void IdealMainWidget::selectPreviousDock()
1003 IdealDockWidget* dock = mainLayout()->lastDockWidget();
1004 IdealMainLayout::Role role = mainLayout()->lastDockWidgetRole();
1006 IdealButtonBarWidget* bar = barForRole(role);
1008 int index = bar->actions().indexOf(m_dockwidget_to_action.value(dock));
1010 if (index < 1)
1011 index = bar->actions().count() - 1;
1012 else
1013 --index;
1015 if (index < bar->actions().count()) {
1016 QAction* action = bar->actions().at(index);
1017 action->setChecked(true);
1021 void IdealMainWidget::removeView()
1023 MainWindow *main = dynamic_cast<MainWindow*>(parent());
1024 main->area()->removeToolView(main->activeToolView());
1027 void Sublime::IdealMainWidget::setShowDockStatus(IdealMainLayout::Role role, bool checked)
1029 KAction* action = actionForRole(role);
1030 if (action->isChecked() != checked) {
1031 bool blocked = action->blockSignals(true);
1032 action->setChecked(checked);
1033 action->blockSignals(blocked);
1037 void Sublime::IdealMainWidget::focusEditor()
1039 if (View* view = static_cast<MainWindow*>(parent())->activeView())
1040 if (view->hasWidget())
1041 view->widget()->setFocus(Qt::ShortcutFocusReason);
1044 IdealDockWidgetButton::IdealDockWidgetButton(QWidget *parent)
1045 : QToolButton(parent)
1047 setFocusPolicy(Qt::NoFocus);
1050 IdealDockWidgetButton::~IdealDockWidgetButton()
1054 QSize IdealDockWidgetButton::sizeHint() const
1056 ensurePolished();
1058 int size = 0;
1060 if (! icon().isNull()) {
1061 const QPixmap pix =
1062 icon().pixmap(style()->pixelMetric(QStyle::PM_SmallIconSize));
1064 size += qMax(pix.width(), pix.height());
1067 const int titleBarButtonMargin =
1068 style()->pixelMetric(QStyle::PM_DockWidgetTitleBarButtonMargin);
1070 size += titleBarButtonMargin * 2;
1072 return QSize(size, size);
1075 QSize IdealDockWidgetButton::minimumSizeHint() const
1076 { return sizeHint(); }
1078 void IdealDockWidgetButton::enterEvent(QEvent *event)
1080 if (isEnabled())
1081 update();
1083 QToolButton::enterEvent(event);
1086 void IdealDockWidgetButton::leaveEvent(QEvent *event)
1088 if (isEnabled())
1089 update();
1091 QToolButton::leaveEvent(event);
1094 void IdealDockWidgetButton::paintEvent(QPaintEvent *)
1096 QStylePainter painter(this);
1098 QStyleOptionToolButton options;
1099 options.init(this);
1100 options.state |= QStyle::State_AutoRaise;
1102 if (isEnabled() && underMouse() && ! isChecked() && ! isDown())
1103 options.state |= QStyle::State_Raised;
1104 if (isChecked())
1105 options.state |= QStyle::State_On;
1106 if (isDown())
1107 options.state |= QStyle::State_Sunken;
1109 options.subControls = QStyle::SC_None;
1110 options.activeSubControls = QStyle::SC_None;
1111 options.icon = icon();
1112 options.arrowType = Qt::NoArrow;
1113 options.features = QStyleOptionToolButton::None;
1114 const int size = style()->pixelMetric(QStyle::PM_SmallIconSize);
1115 options.iconSize = QSize(size, size);
1116 painter.drawComplexControl(QStyle::CC_ToolButton, options);
1119 #include "ideal.moc"