ATLAS Offline Software
Loading...
Searching...
No Matches
VP1DockWidget.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6// //
7// Implementation of class VP1DockWidget //
8// //
9// Author: Thomas Kittelmann <Thomas.Kittelmann@cern.ch> //
10// //
11// Initial version: April 2007 //
12// //
14
18
19#include <QFrame>
20#include <QEvent>
21#include <QSet>
22#include <QVBoxLayout>
23#include <QContextMenuEvent>
24#include <QMenu>
25
26#include <cassert>
27#include <iostream>
28
29//____________________________________________________________________
47
48//____________________________________________________________________
49class VP1DockWidget::Imp::FilterItem : public QObject {
50public:
53
54 void init() {
56 m_activationevents.insert(QEvent::ContextMenu);
57 //m_activationevents.insert(QEvent::EnterEditFocus); --> Does not compile.
58 m_activationevents.insert(QEvent::FocusIn);
59 m_activationevents.insert(QEvent::KeyPress);
60 m_activationevents.insert(QEvent::MouseButtonDblClick);
61 m_activationevents.insert(QEvent::MouseButtonPress);
62 m_activationevents.insert(QEvent::TabletPress);
63 m_activationevents.insert(QEvent::Wheel);
64 }
65
66protected:
67 QSet<QEvent::Type> m_activationevents;
68
69 bool eventFilter ( QObject * watched, QEvent * event ) {
70
71 if (event->type()==QEvent::ChildAdded) {
72 //Maybe the user added a widget, so update the event filters (todo: test that it works):
73 for (QObject* c : watched->children()) {
76 }
77 return false;
78 }
79
80 if ( !m_dw->m_d->selected && m_activationevents.contains(event->type()) ) {
81 m_dw->setSelected();
82 m_dw->wasSelected(m_dw);
83 }
84 // if ( watched==m_dw && event->type() == QEvent::Enter )
85 // m_dw->channelWidget()->setFocus(Qt::OtherFocusReason);
86
87 return false;
88 }
89
90 void installEventFilterRecursively(QObject * child, const bool& remove=false ) {
91 //NB: we install it on all QObjects in the tree rather than just
92 //the QWidgets, since we need to watch for ChildAdded events.
93 if (child==this)
94 return;
95 if (!child){
96 std::cerr<<"installEventFilterRecursively: Child is NULL. Aborting."<<std::endl;
97 return;
98 }
99 if (remove)
100 child->removeEventFilter(this);
101 else
102 child->installEventFilter(this);
103 for (QObject* c : child->children())
105 }
106};
107
108//____________________________________________________________________
110 : filteritem(new FilterItem(the_dw)), dw(the_dw), frame(0), vboxLayout(0),channelwidget(cw),
111 unselectedmargin(0),selected(false),tabmanager(the_tabmanager) {}
112
113//____________________________________________________________________
115{
116 delete m_d->filteritem;
117 delete m_d; m_d=0;
118}
119
120//______________________________________________________________________
122{
123 return "background-color: rgba(0, 0, 255, 12%)";
124}
125
126//______________________________________________________________________
128 : QDockWidget ( cw->unique_name(), 0 ), m_d(new Imp(this,cw,tm))
129{
130
131 setObjectName("VP1DockWidget:"+cw->name());//For storing/saving the layout of the dock widgets within the dock area.
132
133 setFocusProxy(cw);
134
135 setAllowedAreas(Qt::TopDockWidgetArea);
136 setFeatures(VP1DockWidget::DockWidgetMovable | VP1DockWidget::DockWidgetFloatable);
137
138 m_d->selectedstylesheet="QFrame#VP1DockWidgetFrame { "+highlightStyle()+" } ";
139
140 //Add frame, which will light up on selection:
141 m_d->frame = new QFrame(this);
142 m_d->frame->setObjectName("VP1DockWidgetFrame");
143 cw->setObjectName("IVP1ChannelWidget:"+cw->name());
144 ensureCWHasParent();//setup the cw in the frame
145
146 //Figure out what margin our drawn frame imposes:
147 setSelected();
148 QMargins marg = m_d->frame->contentsMargins();
149 Q_ASSERT(marg.left()==marg.top()&&marg.left()==marg.right()&&marg.left()==marg.bottom()&&"Qt changed its margin behaviour for QFrame!!");
150 m_d->unselectedmargin=marg.left();
151
152 //Channel starts unselected:
154
155 connect(cw,SIGNAL(uniqueNameChanged(QString)),this,SLOT(updateTitle()));
156 connect(cw,SIGNAL(systemRefreshInfoChanged(QString,int,int)),this,SLOT(systemRefreshInfoChanged(QString,int,int)));
157
158 //Setup a watch for selections:
159 m_d->filteritem->init();
160
161}
162
163//______________________________________________________________________
165{
166 if (!channelWidget()||!channelWidget()->parent())
167 return;
168 channelWidget()->setParent(0);
169 setWidget(0);
170 if (m_d->frame->layout()&&m_d->frame->layout()->indexOf(m_d->channelwidget)>=0) {
171 assert(m_d->vboxLayout);
172 m_d->vboxLayout->removeWidget(m_d->channelwidget);
173 }
174}
175
176//______________________________________________________________________
178{
179 if (!channelWidget()||channelWidget()->parent())
180 return;
181 if (!m_d->frame->layout()) {
182 assert(!m_d->vboxLayout);
183 m_d->vboxLayout = new QVBoxLayout(0);
184 m_d->frame->setLayout(m_d->vboxLayout);
185 m_d->vboxLayout->setObjectName("vp1dock-frame-layout");
186 m_d->vboxLayout->setSpacing(0);
187 }
188 if (m_d->frame->layout()->indexOf(m_d->channelwidget)<0)
189 m_d->frame->layout()->addWidget(m_d->channelwidget);
190 channelWidget()->setParent(m_d->frame);
191 setWidget(m_d->frame);
192}
193
194//______________________________________________________________________
195void VP1DockWidget::systemRefreshInfoChanged(const QString& sysrefreshing, int nsysOn, int nsysOnRefreshed)
196{
197 assert(nsysOnRefreshed<=nsysOn);
198 if (nsysOn==nsysOnRefreshed) {
199 // assert(sysrefreshing.isEmpty());
200 m_d->title_refreshpart.clear();
201 updateTitle();
202 return;
203 }
204 assert(nsysOnRefreshed<nsysOn);
205 if (sysrefreshing.isEmpty()) {
206 m_d->title_refreshpart = " [Refreshed "+QString::number(nsysOnRefreshed)+"/"+QString::number(nsysOn)+"]";
207 } else {
208 m_d->title_refreshpart = " [Refreshing "+QString::number(nsysOnRefreshed+1)+"/"+QString::number(nsysOn)+": "+sysrefreshing+" ]";
209 }
210 updateTitle();
211}
212
213//______________________________________________________________________
215{
216 if (m_d->selected)
217 setWindowTitle(">>> "+m_d->channelwidget->unique_name()+m_d->title_refreshpart+" <<<");
218 else
219 setWindowTitle(m_d->channelwidget->unique_name()+m_d->title_refreshpart);
220}
221
222//______________________________________________________________________
224{
225 if (m_d->selected)
226 return;
227 m_d->selected=true;
228 m_d->frame->setStyleSheet(m_d->selectedstylesheet);
229 assert(m_d->vboxLayout);
230 m_d->vboxLayout->setMargin(0);
231 m_d->frame->setFrameShape(QFrame::StyledPanel);
232 updateTitle();
233}
234
235//______________________________________________________________________
237{
238 if (!m_d->selected)
239 return;
240 m_d->selected=false;
241 m_d->frame->setStyleSheet("");
242 assert(m_d->vboxLayout);
243 m_d->vboxLayout->setMargin(m_d->unselectedmargin);
244 m_d->frame->setFrameShape(QFrame::NoFrame);
245 updateTitle();
246}
247
248//______________________________________________________________________
250{
251 return m_d->channelwidget;
252}
253
254//______________________________________________________________________
256{
257 return m_d->selected;
258}
259
260//______________________________________________________________________
261void VP1DockWidget::contextMenuEvent ( QContextMenuEvent * event )
262{
263 //Inside the frame, we use the normal behaviour:
264 if (m_d->frame->geometry().contains(event->pos())) {
265 QDockWidget::contextMenuEvent ( event );
266 return;
267 }
268 //Outside we show our contextmenu:
269
270 //Construct menu:
271 QMenu menu(this);
272// menu.addAction("Channel: "+m_d->channelwidget->unique_name())->setEnabled(false);
273// menu.addSeparator();
274
275 QAction* pFullScreenAction = menu.addAction("Show &full Screen");
276 menu.addSeparator();
277 QAction* pRemoveAction = menu.addAction("&Remove channel");
278 menu.addSeparator ();
279 QAction* pMoveChannelAction = menu.addAction("&Move to tab");
280
281 QStringList tablist = m_d->tabmanager->tabList();
282 QMenu menu_movechan(this);
283 if (tablist.count()==1) {
284 menu_movechan.addAction("No other tabs available")->setEnabled(false);
285 } else {
286 QString thistab = m_d->tabmanager->channelToTab(m_d->channelwidget);
287 for (const QString& tab : tablist) {
288 if (tab!=thistab)
289 menu_movechan.addAction(tab)->setData("MOVECHAN");
290 }
291 }
292 pMoveChannelAction->setMenu(&menu_movechan);
293
294 //Execute
295 QAction * selAct = menu.exec(event->globalPos());
296 //Act on selection:
297 if (!selAct)
298 return;
299 if (selAct==pFullScreenAction) {
300 m_d->tabmanager->showChannelFullScreen(m_d->channelwidget);
301 return;
302 }
303 if (selAct==pRemoveAction) {
304 m_d->tabmanager->removeChannelAfterQueueEmpties(m_d->channelwidget->unique_name());
305 return;
306 }
307 if (selAct->data()=="MOVECHAN") {
308 m_d->tabmanager->moveChannelToTab(m_d->channelwidget->unique_name(),selAct->text());
309 return;
310 }
311 std::cout<<"ERROR in VP1DockWidget::contextMenuEvent!!!!!"<<std::endl;
312
313}
314
315//______________________________________________________________________
316void VP1DockWidget::resizeEvent ( QResizeEvent * event )
317{
318 m_d->channelwidget->dockResized();
319 QDockWidget::resizeEvent(event);
320}
const QString & name() const
void installEventFilterRecursively(QObject *child, const bool &remove=false)
QSet< QEvent::Type > m_activationevents
bool eventFilter(QObject *watched, QEvent *event)
Imp(const Imp &)=delete
FilterItem * filteritem
VP1DockWidget * dw
QVBoxLayout * vboxLayout
Imp(VP1DockWidget *_dw, IVP1ChannelWidget *cw, VP1TabManager *tabmanager)
IVP1ChannelWidget * channelwidget
Imp & operator=(const Imp &)=delete
VP1TabManager * tabmanager
virtual ~VP1DockWidget()
IVP1ChannelWidget * channelWidget() const
static QString highlightStyle()
bool isSelected() const
void ensureCWHasNoParent()
void resizeEvent(QResizeEvent *event)
void contextMenuEvent(QContextMenuEvent *event)
VP1DockWidget(IVP1ChannelWidget *cw, VP1TabManager *tm)
void systemRefreshInfoChanged(const QString &sysrefreshing, int nsysOn, int nsysOnRefreshed)
make the sidebar many part of the config
Definition hcg.cxx:552