1 /***************************************************************************
2  *                                                                         *
3  *   copyright : (C) 2007 The University of Toronto                        *
4  *                   netterfield@astro.utoronto.ca                         *
5  *                                                                         *
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.                                   *
10  *                                                                         *
11  ***************************************************************************/
12 
13 #include "tabwidget.h"
14 #include "mainwindow.h"
15 #include "view.h"
16 #include "viewitem.h"
17 #include "curveplacement.h"
18 #include "plotitem.h"
19 #include "plotitemmanager.h"
20 #include "plotrenderitem.h"
21 
22 #include <QInputDialog>
23 #include <QMenu>
24 #include <QTabBar>
25 #include <QUndoGroup>
26 #include <QDebug>
27 #include <QDragEnterEvent>
28 
29 
30 namespace Kst {
31 
32 class TabBar : public QTabBar
33 {
34 public:
35   TabBar();
36   void dragEnterEvent(QDragEnterEvent* event);
37   void dragMoveEvent(QDragMoveEvent* event);
38   void dropEvent(QDropEvent* event);
39 };
40 
41 
TabBar()42 TabBar::TabBar()
43 {
44   setAcceptDrops(true);
45 }
46 
dragEnterEvent(QDragEnterEvent * event)47 void TabBar::dragEnterEvent(QDragEnterEvent* event)
48 {
49   if (MimeDataViewItem::downcast(event->mimeData())) {
50     setCurrentIndex(tabAt(event->pos()));
51     event->acceptProposedAction();
52   }
53 }
54 
dragMoveEvent(QDragMoveEvent * event)55 void TabBar::dragMoveEvent(QDragMoveEvent* event)
56 {
57   if (MimeDataViewItem::downcast(event->mimeData())) {
58     setCurrentIndex(tabAt(event->pos()));
59     event->acceptProposedAction();
60    }
61 }
62 
dropEvent(QDropEvent * event)63 void TabBar::dropEvent(QDropEvent* event)
64 {
65   event->setDropAction(Qt::IgnoreAction);
66   event->accept();
67 }
68 
69 
70 
TabWidget(QWidget * parent)71 TabWidget::TabWidget(QWidget *parent)
72 : QTabWidget(parent) {
73   setTabBar(new TabBar);
74   tabBar()->setContextMenuPolicy(Qt::CustomContextMenu);
75   connect(tabBar(), SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenu(QPoint)));
76   _cnt = 0;
77 #if QT_VERSION >= 0x040500
78   tabBar()->setMovable(true);
79   tabBar()->setExpanding(true);
80 #endif
81 }
82 
83 
~TabWidget()84 TabWidget::~TabWidget() {
85 }
86 
87 
createView()88 View *TabWidget::createView() {
89   View *view = new View;
90   addView(view);
91   return view;
92 }
93 
94 
checkedShowTabbar()95 void TabWidget::checkedShowTabbar() {
96   if (count() < 2) {
97     tabBar()->hide();
98   } else {
99     tabBar()->show();
100   }
101 }
102 
addView(View * view)103 void TabWidget::addView(View* view) {
104   MainWindow *parent = qobject_cast<MainWindow*>(this->parent());
105   if (parent) {
106     parent->undoGroup()->addStack(view->undoStack());
107     parent->undoGroup()->setActiveStack(view->undoStack());
108   }
109 
110   connect(view, SIGNAL(viewModeChanged(View::ViewMode)), this, SIGNAL(currentViewModeChanged()));
111 
112   QString label = view->objectName().isEmpty() ?
113                   tr("View &%1").arg(++_cnt) :
114                   view->objectName();
115 
116   addTab(view, label);
117   checkedShowTabbar();
118   setCurrentWidget(view);
119 }
120 
121 
currentView() const122 View *TabWidget::currentView() const {
123   return qobject_cast<View*>(currentWidget());
124 }
125 
126 
views() const127 QList<View*> TabWidget::views() const {
128   QList<View*> v;
129   for (int i = 0; i < count(); ++i) {
130     v.append(qobject_cast<View*>(widget(i)));
131   }
132   return v;
133 }
134 
135 
deleteView(View * view)136 void TabWidget::deleteView(View* view) {
137   MainWindow *parent = qobject_cast<MainWindow*>(this->parent());
138   PlotItemManager::self()->clearAllTiedZoom(view);
139   if (parent) {
140     parent->undoGroup()->removeStack(view->undoStack());
141   }
142   removeTab(indexOf(view));
143   delete view;
144   checkedShowTabbar();
145 }
146 
147 
clear()148 void TabWidget::clear() {
149   QList<View*> tabs = views();
150   foreach(View* view, tabs) {
151     deleteView(view);
152   }
153   _cnt = 0;
154   checkedShowTabbar();
155 }
156 
157 
closeCurrentView()158 void TabWidget::closeCurrentView() {
159   deleteView(currentView());
160   if (count() == 0)
161     createView();
162 }
163 
164 
renameCurrentView()165 void TabWidget::renameCurrentView() {
166   QTabBar *tb = tabBar();
167   int idx = tb->currentIndex();
168   bool ok = false;
169   QString rc = QInputDialog::getText(this, tr("Rename Tab"), tr("Enter a new tab name:"), QLineEdit::Normal, tb->tabText(idx), &ok);
170   if (ok) {
171     tb->setTabText(idx, rc);
172   }
173 }
174 
setCurrentViewName(QString name)175 void TabWidget::setCurrentViewName(QString name) {
176   int idx = tabBar()->currentIndex();
177   tabBar()->setTabText(idx, name);
178 }
179 
contextMenu(const QPoint & pos)180 void TabWidget::contextMenu(const QPoint& pos) {
181   QTabBar *tb = tabBar();
182   int idx = tb->currentIndex();
183   for (int i = 0; i < tb->count(); ++i) {
184     if (tb->tabRect(i).contains(pos)) {
185        idx = i;
186        tb->setCurrentIndex(i);
187        break;
188     }
189   }
190   const QString txt = tb->tabText(idx);
191   QMenu m(txt, tb);
192   m.addAction(tr("&Add tab"), this, SLOT(createView()));
193   m.addAction(tr("&Rename tab"), this, SLOT(renameCurrentView()));
194   m.addAction(tr("&Close tab"), this, SLOT(closeCurrentView()));
195   m.addSeparator();
196   m.addAction(tr("&Edit View"), currentView(), SLOT(edit()));
197 
198   QMenu layoutMenu;
199   layoutMenu.setTitle(tr("Cleanup Layout"));
200   layoutMenu.addAction(tr("Automatic"), currentView(), SLOT(createLayout()));
201   layoutMenu.addAction(tr("Custom"), currentView(), SLOT(createCustomLayout()));
202   m.addMenu(&layoutMenu);
203 
204   m.exec(tb->mapToGlobal(pos));
205 }
206 
207 }
208 
209 // vim: ts=2 sw=2 et
210