1 /**************************************************************************
2 *   Copyright (C) 2005-2020 by Oleksandr Shneyder                         *
3 *                              <o.shneyder@phoca-gmbh.de>                 *
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 2 of the License, or     *
8 *   (at your option) any later version.                                   *
9 *   This program is distributed in the hope that it will be useful,       *
10 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12 *   GNU General Public License for more details.                          *
13 *                                                                         *
14 *   You should have received a copy of the GNU General Public License     *
15 *   along with this program.  If not, see <https://www.gnu.org/licenses/>. *
16 ***************************************************************************/
17 
18 #include "sessionbutton.h"
19 #include "x2goclientconfig.h"
20 #include "x2goutils.h"
21 
22 #include <QFont>
23 #include <QPixmap>
24 #include <QLabel>
25 #include "x2gosettings.h"
26 #include <QDir>
27 #include <QLayout>
28 #include <QComboBox>
29 #include <QMouseEvent>
30 #include <QMenu>
31 #include <QPushButton>
32 #include "onmainwindow.h"
33 #include "x2gologdebug.h"
34 #include <QApplication>
35 #include <QDesktopWidget>
36 #include <QSvgRenderer>
37 #include <QPainter>
38 #include <QImage>
39 #include <QPixmap>
40 #include <QPolygon>
41 #include "sessionexplorer.h"
42 
43 
SessionButton(ONMainWindow * mw,QWidget * parent,QString id)44 SessionButton::SessionButton ( ONMainWindow* mw,QWidget *parent, QString id )
45     : SVGFrame ( ":/img/svg/sessionbut.svg",false,parent )
46 {
47     editable=mw->sessionEditEnabled();
48 
49 
50     QPalette pal=palette();
51     pal.setColor ( QPalette::Active, QPalette::WindowText, QPalette::Mid );
52     pal.setColor ( QPalette::Active, QPalette::ButtonText, QPalette::Mid );
53     pal.setColor ( QPalette::Active, QPalette::Text, QPalette::Mid );
54     pal.setColor ( QPalette::Inactive, QPalette::WindowText, QPalette::Mid );
55     pal.setColor ( QPalette::Inactive, QPalette::ButtonText, QPalette::Mid );
56     pal.setColor ( QPalette::Inactive, QPalette::Text, QPalette::Mid );
57 
58     setPalette(pal);
59 
60 
61 
62     QFont fnt=font();
63     if ( mw->retMiniMode() )
64 #ifdef Q_WS_HILDON
65         fnt.setPointSize ( 10 );
66 #else
67         fnt.setPointSize ( 9 );
68 #endif
69     setFont ( fnt );
70     setFocusPolicy ( Qt::NoFocus );
71     bool miniMode=mw->retMiniMode();
72     if ( !miniMode )
73         setFixedSize ( 340,190 );
74     else
75         setFixedSize ( 250,145 );
76 
77 
78     par= mw;
79     connect ( this,SIGNAL ( clicked() ),this,SLOT ( slotClicked() ) );
80 
81     sid=id;
82 
83     cmdBox=new QComboBox ( this );
84     cmdBox->setMouseTracking ( true );
85     cmdBox->setFrame ( false );
86     QPalette cpal=cmdBox->palette();
87 
88     cpal.setColor ( QPalette::Button,QColor ( 255,255,255 ) );
89     cpal.setColor ( QPalette::Base,QColor ( 255,255,255 ) );
90     cpal.setColor ( QPalette::Window,QColor ( 255,255,255 ) );
91     cmdBox->setPalette ( cpal );
92 
93     geomBox=new QComboBox ( this );
94     geomBox->setMouseTracking ( true );
95     geomBox->setFrame ( false );
96     geomBox->setEditable ( true );
97     geomBox->setEditable ( false );
98     geomBox->update();
99     geomBox->setPalette ( cpal );
100 
101     sessName=new QLabel ( this );
102     sessStatus=new QLabel ( this );
103     fnt=sessName->font();
104     fnt.setBold ( true );
105     sessName->setFont ( fnt );
106     icon=new QLabel ( this );
107     cmd=new QLabel ( this );
108     cmd->setMouseTracking ( true );
109     serverIcon=new QLabel ( this );
110     geomIcon=new QLabel ( this );
111     geomIcon->setMouseTracking ( true );
112     cmdIcon=new QLabel ( this );
113     cmdIcon->setMouseTracking ( true );
114     server=new QLabel ( this );
115     geom=new QLabel ( this );
116     geom->setMouseTracking ( true );
117 
118     sound=new QPushButton ( this );
119     soundIcon=new QLabel ( this );
120     sound->setPalette ( cpal );
121     sound->setFlat ( true );
122     sound->setMouseTracking ( true );
123     connect ( sound,SIGNAL ( clicked() ),this,
124               SLOT ( slot_soundClicked() ) );
125 
126     editBut=new QPushButton ( this );
127     editBut->setMouseTracking ( true );
128     connect ( editBut,SIGNAL ( pressed() ),this,SLOT ( slotShowMenu() ) );
129 
130     /* Load our edit button SVG file. */
131     QSvgRenderer svg_renderer (par->images_resource_path ("/svg/hamburger.svg"));
132 
133     /* Prepare image to render to with full transparency. */
134     QImage tmp_image (16, 16, QImage::Format_ARGB32);
135     tmp_image.fill (0x00000000);
136 
137     /* Paint icon to the image. */
138     QPainter tmp_painter (&tmp_image);
139     svg_renderer.render (&tmp_painter);
140 
141     editBut->setIcon ( QIcon ( QPixmap::fromImage (tmp_image) ) );
142     editBut->setIconSize ( QSize ( 16,16 ) );
143     editBut->setFixedSize ( 24,24 );
144     editBut->setFlat ( true );
145     editBut->setPalette ( cpal );
146     sessMenu=new QMenu ( this );
147 
148     connect ( sessMenu,SIGNAL ( aboutToHide() ),this,
149               SLOT ( slotMenuHide() ) );
150 
151     act_edit=sessMenu->addAction (
152                  QIcon (
153                      mw->iconsPath ( "/16x16/edit.png" ) ),
154                  tr ( "Session preferences ..." ) );
155 #if (!defined Q_WS_HILDON) && (!defined Q_OS_DARWIN)
156     act_createIcon=sessMenu->addAction (
157                        QIcon ( mw->iconsPath ( "/16x16/create_file.png" ) ),
158                        tr (
159                            "Create session icon on desktop ..." ) );
160 #endif
161     act_remove=sessMenu->addAction (
162                    QIcon ( mw->iconsPath ( "/16x16/delete.png" ) ),
163                    tr ( "Delete session" ) );
164 
165 
166     connect ( act_edit,SIGNAL ( triggered ( bool ) ),this,
167               SLOT ( slotEdit() ) );
168 
169     connect ( act_remove,SIGNAL ( triggered ( bool ) ),this,
170               SLOT ( slotRemove() ) );
171 #if (!defined Q_WS_HILDON) && (!defined Q_OS_DARWIN)
172     connect ( act_createIcon,SIGNAL ( triggered ( bool ) ),this,
173               SLOT ( slotCreateSessionIcon() ) );
174 #endif
175 
176     editBut->setToolTip ( tr ( "Session actions" ) );
177     cmdBox->setToolTip ( tr ( "Select type" ) );
178 
179     geomBox->setToolTip ( tr ( "Select resolution" ) );
180     sound->setToolTip ( tr ( "Toggle sound support" ) );
181     icon->move ( 10,10 );
182 
183     if ( !miniMode )
184     {
185         sessName->move ( 80,34 );
186         sessStatus->move(80,50);
187         editBut->move ( 307,156 );
188         serverIcon->move ( 58,84 );
189         server->move ( 80,84 );
190         cmdIcon->move ( 58,108 );
191         cmd->move ( 80,108 );
192         cmdBox->move ( 80,108 );
193         geomIcon->move ( 58,132 );
194         geom->move ( 80,132 );
195         geomBox->move ( 80,132 );
196         soundIcon->move ( 58,156 );
197         sound->move ( 76,156 );
198     }
199     else
200     {
201         editBut->move ( 218,113 );
202         sessName->move ( 64,11 );
203         sessStatus->hide();
204         serverIcon->move ( 66,44 );
205         server->move ( 88,44 );
206         cmdIcon->move ( 66,68 );
207         cmd->move ( 88,68 );
208         cmdBox->move ( 88,68 );
209         geomIcon->move ( 66,92 );
210         geom->move ( 88,92 );
211         geomBox->move ( 88,92 );
212         soundIcon->move ( 66,116 );
213         sound->move ( 86,116 );
214     }
215 
216     if (mw->brokerMode)
217     {
218         icon->move(10,30);
219         sessName->move(90,50);
220         sessStatus->move(90,70);
221         setFixedHeight(120);
222     }
223 
224 
225     cmdBox->hide();
226     geomBox->hide();
227     QPixmap spix;
228     spix.load ( par->iconsPath ( "/16x16/session.png" ) );
229     serverIcon->setPixmap ( spix );
230     serverIcon->setFixedSize ( 16,16 );
231 
232     QPixmap rpix;
233     rpix.load ( par->iconsPath ( "/16x16/resolution.png" ) );
234     geomIcon->setPixmap ( rpix );
235     geomIcon->setFixedSize ( 16,16 );
236 
237     QPixmap apix;
238     apix.load ( par->iconsPath ( "/16x16/audio.png" ) );
239     soundIcon->setPixmap ( apix );
240     soundIcon->setFixedSize ( 16,16 );
241     redraw();
242 
243     connect ( cmdBox,SIGNAL ( activated ( const QString& ) ),this,
244               SLOT ( slot_cmd_change ( const QString& ) ) );
245     connect ( geomBox,SIGNAL ( activated ( const QString& ) ),this,
246               SLOT ( slot_geom_change ( const QString& ) ) );
247 
248     editBut->setFocusPolicy ( Qt::NoFocus );
249     sound->setFocusPolicy ( Qt::NoFocus );
250     cmdBox->setFocusPolicy ( Qt::NoFocus );
251     geomBox->setFocusPolicy ( Qt::NoFocus );
252     setMouseTracking(true);
253 
254     if (!editable)
255     {
256         editBut->hide();
257         cmdBox->hide();
258         geomBox->hide();
259         sessMenu->hide();
260         sound->setEnabled(false);
261     }
262     if (mw->brokerMode)
263     {
264         cmd->hide();
265         cmdIcon->hide();
266         server->hide();
267         serverIcon->hide();
268         geom->hide();
269         geomIcon->hide();
270         sound->hide();
271         soundIcon->hide();
272     }
273 }
274 
~SessionButton()275 SessionButton::~SessionButton()
276 {}
277 
slotClicked()278 void SessionButton::slotClicked()
279 {
280     emit sessionSelected ( this );
281 }
282 
slotEdit()283 void SessionButton::slotEdit()
284 {
285 // 	editBut->setFlat ( true );
286     emit signal_edit ( this );
287 }
288 
slotRemove()289 void SessionButton::slotRemove()
290 {
291     emit ( signal_remove ( this ) );
292 }
293 
redraw()294 void SessionButton::redraw()
295 {
296     bool snd;
297 
298 
299     X2goSettings *st;
300 
301     if (par->brokerMode)
302         st=new X2goSettings(par->config.iniFile,QSettings::IniFormat);
303     else
304         st= new X2goSettings( "sessions" );
305 
306     QString name=st->setting()->value ( sid+"/name",
307                                         ( QVariant ) tr ( "New Session" ) ).toString();
308 
309 
310     QStringList tails=name.split("/",QString::SkipEmptyParts);
311     if(tails.count()>0)
312     {
313         name=tails.last();
314         tails.pop_back();
315         path=tails.join("/");
316     }
317 
318     QFontMetrics metr(sessName->font());
319     nameofSession=name;
320 
321     QString elName=metr.elidedText(name, Qt::ElideRight, 250);
322     sessName->setText (elName);
323     sessName->setToolTip(nameofSession);
324 
325     QString status=st->setting()->value ( sid+"/status",
326                                           ( QVariant ) QString::null ).toString();
327     if (status == "R")
328     {
329         sessStatus->setText("("+tr("running")+")");
330     }
331     if (status == "S")
332     {
333         sessStatus->setText("("+tr("suspended")+")");
334     }
335 
336     int suspended=st->setting()->value ( sid+"/suspended",
337                                          ( QVariant ) QString::null ).toUInt();
338 
339     int running=st->setting()->value ( sid+"/running",
340                                          ( QVariant ) QString::null ).toUInt();
341     if(suspended || running)
342     {
343         QStringList parts;
344         if(suspended)
345         {
346             parts<<tr("suspended")+" - "+QString::number(suspended);
347         }
348         if(running)
349         {
350             parts<<tr("running")+" - "+QString::number(running);
351         }
352         sessStatus->setText(parts.join(", "));
353     }
354 
355     QString sessIcon = wrap_legacy_resource_URIs (st->setting()->value (sid+"/icon",
356                        (QVariant) ":/img/icons/128x128/x2gosession.png"
357                                                                        ).toString ());
358     sessIcon = expandHome(sessIcon);
359     QPixmap* pix;
360 
361     x2goDebug << "Creating QPixmap with session icon: " << sessIcon.toLatin1 () << ".";
362     if (!par->brokerMode || sessIcon == ":/img/icons/128x128/x2gosession.png")
363         pix=new QPixmap( sessIcon );
364     else
365     {
366         pix=new QPixmap;
367         pix->loadFromData(QByteArray::fromBase64(sessIcon.toLatin1()));
368     }
369     if ( !par->retMiniMode() )
370         icon->setPixmap ( pix->scaled ( 64,64,Qt::IgnoreAspectRatio,
371                                         Qt::SmoothTransformation ) );
372     else
373         icon->setPixmap ( pix->scaled ( 48,48,Qt::IgnoreAspectRatio,
374                                         Qt::SmoothTransformation ) );
375 
376     delete pix;
377     QString sv=st->setting()->value ( sid+"/host", ( QVariant )
378                                       QString::null ).toString();
379     QString uname=st->setting()->value ( sid+"/user", ( QVariant )
380                                          QString::null ).toString();
381     server->setText ( uname+"@"+sv );
382 
383     QString command=st->setting()->value ( sid+"/command",
384                                            ( QVariant )
385                                            tr (
386                                                    "KDE" ) ).
387                     toString();
388     rootless=st->setting()->value ( sid+"/rootless",
389                                     false ).toBool();
390     published=st->setting()->value ( sid+"/published",
391                                      false ).toBool();
392 
393 
394     cmdBox->clear();
395     cmdBox->addItem ( "KDE" );
396     cmdBox->addItem ( "GNOME" );
397     cmdBox->addItem ( "LXDE" );
398     cmdBox->addItem ("LXQt");
399     cmdBox->addItem ( "XFCE" );
400     cmdBox->addItem ( "MATE" );
401     cmdBox->addItem ( "UNITY" );
402     cmdBox->addItem ( "CINNAMON" );
403     cmdBox->addItem ( "TRINITY" );
404     cmdBox->addItem ( "OPENBOX" );
405     cmdBox->addItem ( "ICEWM" );
406     cmdBox->addItem ( tr ( "RDP connection" ) );
407     cmdBox->addItem ( tr ( "XDMCP" ) );
408     cmdBox->addItem ( tr ( "Connection to local desktop" ) );
409     cmdBox->addItem ( tr ( "Published applications" ) );
410 
411     cmdBox->addItems ( par->transApplicationsNames() );
412 
413     bool directRDP=false;
414     QPixmap cmdpix;
415     if ( command=="KDE" )
416     {
417         cmdpix.load ( par->iconsPath ( "/16x16/kde.png" ) );
418         cmdBox->setCurrentIndex ( KDE );
419     }
420     else if ( command =="GNOME" )
421     {
422         cmdpix.load ( par->iconsPath ( "/16x16/gnome.png" ) );
423         cmdBox->setCurrentIndex ( GNOME );
424     }
425     else if ( command =="UNITY" )
426     {
427         cmdpix.load ( par->iconsPath ( "/16x16/unity.png" ) );
428         cmdBox->setCurrentIndex ( UNITY );
429     }
430     else if ( command == "XFCE" )
431     {
432         cmdpix.load ( par->iconsPath ( "/16x16/xfce.png" ) );
433         cmdBox->setCurrentIndex ( XFCE );
434     }
435     else if ( command == "MATE" )
436     {
437         cmdpix.load ( par->iconsPath ( "/16x16/mate.png" ) );
438         cmdBox->setCurrentIndex ( MATE );
439     }
440     else if ( command =="LXDE" )
441     {
442         cmdpix.load ( par->iconsPath ( "/16x16/lxde.png" ) );
443         cmdBox->setCurrentIndex ( LXDE );
444     }
445     else if (command == "LXQt")
446     {
447         cmdpix.load (par->iconsPath ("/16x16/lxqt.png"));
448         cmdBox->setCurrentIndex (LXQt);
449     }
450     else if ( command == "CINNAMON" )
451     {
452         cmdpix.load ( par->iconsPath ( "/16x16/cinnamon.png" ) );
453         cmdBox->setCurrentIndex ( CINNAMON );
454     }
455     else if ( command == "TRINITY" )
456     {
457         cmdpix.load ( par->iconsPath ( "/16x16/trinity.png" ) );
458         cmdBox->setCurrentIndex ( TRINITY );
459     }
460     else if ( command == "OPENBOX" )
461     {
462         cmdpix.load ( par->iconsPath ( "/16x16/openbox.png" ) );
463         cmdBox->setCurrentIndex ( OPENBOX );
464     }
465     else if ( command == "ICEWM" )
466     {
467         cmdpix.load ( par->iconsPath ( "/16x16/icewm.png" ) );
468         cmdBox->setCurrentIndex ( ICEWM );
469     }
470     else if ( command =="SHADOW" )
471     {
472         cmdpix.load ( par->iconsPath ( "/16x16/X.png" ) );
473         cmdBox->setCurrentIndex ( SHADOW );
474         command=tr ( "Connection to local desktop" );
475     }
476     else if ( command =="RDP" )
477     {
478 #ifdef Q_OS_UNIX
479         if (st->setting()->value ( sid+"/directrdp",
480                                    ( QVariant ) false ).toBool())
481             directRDP=true;
482 #endif
483         cmdpix.load ( par->iconsPath ( "/16x16/rdp.png" ) );
484         cmdBox->setCurrentIndex ( RDP );
485         command=tr ( "RDP connection" );
486     }
487     else if ( command =="XDMCP" )
488     {
489 #ifdef Q_OS_UNIX
490         if (st->setting()->value ( sid+"/directxdmcp",
491                                    ( QVariant ) false ).toBool()) {
492             directRDP=true;
493             server->setText ( "XDM@"+sv );
494         }
495 #endif
496         cmdpix.load ( par->iconsPath ( "/16x16/X.png" ) );
497         cmdBox->setCurrentIndex ( XDMCP );
498         command=tr ( "XDMCP" );
499     }
500     else if (published)
501     {
502         cmdpix.load ( par->iconsPath ( "/16x16/X.png" ) );
503         command=tr ("Published applications");
504         cmdBox->setCurrentIndex (PUBLISHED);
505     }
506     else
507     {
508         cmdpix.load ( par->iconsPath ( "/16x16/X.png" ) );
509         command=par->transAppName ( command );
510         int id= cmdBox->findText ( command );
511         if ( id ==-1 )
512         {
513             cmdBox->addItem ( command );
514             cmdBox->setCurrentIndex ( cmdBox->count()-1 );
515         }
516         else
517             cmdBox->setCurrentIndex ( id );
518     }
519 
520 
521 
522     cmdIcon->setPixmap ( cmdpix );
523     cmd->setText ( command );
524 
525 
526     geomBox->clear();
527     geomBox->addItem ( tr ( "fullscreen" ) );
528     uint displays=QApplication::desktop()->numScreens();
529     if (!directRDP)
530         for (uint i=0; i<displays; ++i)
531         {
532             geomBox->addItem ( tr( "Display " )+QString::number(i+1));
533 
534             //add maximun available area
535             geomBox->addItem( QString::number(QApplication::desktop()->availableGeometry(i).width()) + "x" + QString::number(QApplication::desktop()->availableGeometry(i).height()));
536 
537 
538         }
539 #ifndef Q_WS_HILDON
540 
541 
542     geomBox->addItem ( "1440x900" );
543     geomBox->addItem ( "1280x1024" );
544     geomBox->addItem ( "1024x768" );
545     geomBox->addItem ( "800x600" );
546 #else
547     geomBox->addItem ( tr ( "window" ) );
548 #endif
549     if ( st->setting()->value ( sid+"/fullscreen",
550                                 ( QVariant ) false ).toBool() )
551     {
552         geom->setText ( tr ( "fullscreen" ) );
553     }
554     else if (st->setting()->value ( sid+"/multidisp",
555                                     ( QVariant ) false ).toBool() && !directRDP)
556     {
557         uint disp=st->setting()->value ( sid+"/display",
558                                          ( QVariant ) 1 ).toUInt();
559         if (disp<=displays)
560         {
561             geom->setText( tr( "Display " )+QString::number(disp));
562         }
563         else
564         {
565             geom->setText( tr( "Display " )+QString::number(1));
566         }
567         for (int i=0; i<geomBox->count(); ++i)
568             if (geomBox->itemText(i)==geom->text())
569             {
570                 geomBox->setCurrentIndex(i);
571                 break;
572             }
573     }
574     else
575     {
576 #ifndef	Q_WS_HILDON
577         QString g=QString::number ( st->setting()->value (
578                                         sid+"/width" ).toInt() );
579         g+="x"+QString::number ( st->setting()->value (
580                                      sid+"/height" ).toInt() );
581         geom->setText ( g );
582         if ( geomBox->findText ( g ) ==-1 )
583             geomBox->addItem ( g );
584         geomBox->setCurrentIndex ( geomBox->findText ( g ) );
585 #else
586         geom->setText ( tr ( "window" ) );
587         geomBox->setCurrentIndex ( 1 );
588 #endif
589     }
590 
591     if (directRDP)
592     {
593         geomBox->addItem ( tr("Maximum") );
594         if (st->setting()->value ( sid+"/maxdim",
595                                    ( QVariant ) false ).toBool())
596         {
597             geom->setText ( tr("Maximum") );
598             geomBox->setCurrentIndex ( geomBox->findText ( tr("Maximum") ));
599         }
600     }
601 
602 
603     snd=st->setting()->value ( sid+"/sound", ( QVariant ) true ).toBool();
604     if(directRDP)
605         snd=false;
606     if ( snd )
607         sound->setText ( tr ( "Enabled" ) );
608     else
609         sound->setText ( tr ( "Disabled" ) );
610     soundIcon->setEnabled ( snd );
611     QFontMetrics fm ( sound->font() );
612     sound->setFixedSize ( fm.size ( Qt::TextSingleLine,sound->text() ) +
613                           QSize ( 8,4 ) );
614 
615     sessName->setMinimumSize ( sessName->sizeHint() );
616     geom->setMinimumSize ( geom->sizeHint() );
617     cmd->setMinimumSize ( cmd->sizeHint() );
618     server->setMinimumSize ( server->sizeHint() );
619     delete st;
620 }
621 
mousePressEvent(QMouseEvent * event)622 void SessionButton::mousePressEvent ( QMouseEvent * event )
623 {
624     SVGFrame::mousePressEvent ( event );
625     loadBg ( ":/img/svg/sessionbut_grey.svg" );
626 }
627 
mouseReleaseEvent(QMouseEvent * event)628 void SessionButton::mouseReleaseEvent ( QMouseEvent * event )
629 {
630     SVGFrame::mouseReleaseEvent ( event );
631     loadBg ( ":/img/svg/sessionbut.svg" );
632 
633     QPoint click_pos (event->x (), event->y ());
634 
635     QRect sensitive_area (0, 0, width (), height ());
636 
637     bool recognized_click = false;
638 
639     /*
640      * If button is editable, let only the top "half"
641      * of the button be clickable to trigger an event.
642      *
643      * Actually, the area will look something like that:
644      * ----------------------------
645      * |                          |
646      * |    -----------------------
647      * |    |
648      * |    |
649      * |    |
650      * ------
651      *
652      */
653     if (editable) {
654         bool mini_mode = par->retMiniMode ();
655 
656         QRect sensitive_area2;
657 
658         if (!mini_mode) {
659           sensitive_area.setHeight (84);
660           sensitive_area2 = QRect (0, 83, 58, height () - 84);
661         }
662         else {
663           sensitive_area.setHeight (44);
664           sensitive_area2 = QRect (0, 43, 66, height () - 44);
665         }
666 
667         QPolygon real_sensitive_area;
668         real_sensitive_area << sensitive_area.topLeft () << sensitive_area.topRight ()
669                             << sensitive_area.bottomRight () << sensitive_area2.topRight ()
670                             << sensitive_area2.bottomRight () << sensitive_area2.bottomLeft ()
671                             << sensitive_area.topLeft ();
672 
673         recognized_click = real_sensitive_area.containsPoint (click_pos, Qt::WindingFill);
674     }
675     else {
676         recognized_click = sensitive_area.contains (click_pos);
677     }
678 
679     if (recognized_click) {
680         emit clicked ();
681     }
682 }
683 
mouseMoveEvent(QMouseEvent * event)684 void SessionButton::mouseMoveEvent ( QMouseEvent * event )
685 {
686 
687     SVGFrame::mouseMoveEvent ( event );
688     if (!editable)
689         return;
690     if ( cmd->isVisible() )
691         if ( event->x() > cmd->x() && event->x() < cmd->x() +
692                 cmd->width() &&
693                 event->y() >cmd->y() && event->y() <cmd->y() +
694                 cmd->height() )
695         {
696             if ( cmdBox->width() <cmd->width() )
697                 cmdBox->setFixedWidth ( cmd->width() +20 );
698             if ( cmdBox->height() !=cmd->height() )
699                 cmdBox->setFixedHeight ( cmd->height() );
700             cmd->hide();
701             cmdBox->show();
702         }
703     if ( cmdBox->isVisible() )
704         if ( event->x() < cmdBox->x() || event->x() > cmdBox->x() +
705                 cmdBox->width() ||
706                 event->y() <cmdBox->y() || event->y() >cmdBox->y() +
707                 cmdBox->height() )
708         {
709             cmdBox->hide();
710             cmd->show();
711         }
712 
713 
714     if ( sound->isFlat() )
715     {
716         if ( event->x() > sound->x() && event->x() < sound->x() +
717                 sound->width() &&
718                 event->y() >sound->y() && event->y() <sound->y() +
719                 sound->height() )
720         {
721             sound->setFlat ( false );
722         }
723     }
724     else
725     {
726         if ( event->x() < sound->x() || event->x() > sound->x() +
727                 sound->width() ||
728                 event->y() <sound->y() || event->y() >sound->y() +
729                 sound->height() )
730         {
731             sound->setFlat ( true );
732         }
733     }
734 
735 
736     if ( editBut->isFlat() )
737     {
738         if ( event->x() > editBut->x() && event->x() < editBut->x() +
739                 editBut->width() &&
740                 event->y() >editBut->y() && event->y() <editBut->y() +
741                 editBut->height() )
742             editBut->setFlat ( false );
743     }
744     else
745     {
746         if ( event->x() < editBut->x() || event->x() > editBut->x() +
747                 editBut->width() ||
748                 event->y() <editBut->y() || event->y() >editBut->y() +
749                 editBut->height() )
750             editBut->setFlat ( true );
751     }
752 
753     if ( geom->isVisible() )
754         if ( event->x() > geom->x() && event->x() < geom->x() +
755                 geom->width() &&
756                 event->y() >geom->y() && event->y() <geom->y() +
757                 geom->height() )
758         {
759             if ( geomBox->width() <geom->width() )
760                 geomBox->setFixedWidth ( geom->width() +20 );
761             if ( geomBox->height() !=geom->height() )
762                 geomBox->setFixedHeight ( geom->height() );
763             geom->hide();
764             geomBox->show();
765         }
766     if ( geomBox->isVisible() )
767         if ( event->x() < geomBox->x() || event->x() > geomBox->x() +
768                 geomBox->width() ||
769                 event->y() <geomBox->y() || event->y() >geomBox->y() +
770                 geomBox->height() )
771         {
772             geomBox->hide();
773             geom->show();
774         }
775 }
776 
777 
slot_soundClicked()778 void SessionButton::slot_soundClicked()
779 {
780     bool snd=!soundIcon->isEnabled();
781     soundIcon->setEnabled ( snd );
782     if ( snd )
783         sound->setText ( tr ( "Enabled" ) );
784     else
785         sound->setText ( tr ( "Disabled" ) );
786     QFontMetrics fm ( sound->font() );
787     sound->setFixedSize ( fm.size ( Qt::TextSingleLine,sound->text() ) +
788                           QSize ( 8,4 ) );
789 
790     X2goSettings st ( "sessions" );
791     st.setting()->setValue ( sid+"/sound", ( QVariant ) snd );
792     st.setting()->sync();
793 
794 
795 }
796 
slot_cmd_change(const QString & command)797 void SessionButton::slot_cmd_change ( const QString& command )
798 {
799     cmd->setText ( command );
800     QPixmap pix;
801     bool newRootless=rootless;
802     published=false;
803     QString cmd=command;
804     if ( command=="KDE" )
805     {
806         newRootless=false;
807         pix.load ( par->iconsPath ( "/16x16/kde.png" ) );
808     }
809     else if ( command =="GNOME" )
810     {
811         newRootless=false;
812         pix.load ( par->iconsPath ( "/16x16/gnome.png" ) );
813     }
814     else if ( command =="LXDE" )
815     {
816         newRootless=false;
817         pix.load ( par->iconsPath ( "/16x16/lxde.png" ) );
818     }
819     else if (command == "LXQt")
820     {
821         newRootless = false;
822         pix.load (par->iconsPath ("/16x16/lxqt.png"));
823     }
824     else if ( command =="UNITY" )
825     {
826         newRootless=false;
827         pix.load ( par->iconsPath ( "/16x16/unity.png" ) );
828     }
829     else if ( command == "XFCE" )
830     {
831         newRootless=false;
832         pix.load ( par->iconsPath ( "/16x16/xfce.png" ) );
833     }
834     else if ( command == "MATE" )
835     {
836         newRootless=false;
837         pix.load ( par->iconsPath ( "/16x16/mate.png" ) );
838     }
839     else if ( command == "CINNAMON" )
840     {
841         newRootless=false;
842         // As of 2014-10-01, Cinnamon does not have a logo. This icon is the
843         // gear, which is the default start menu icon as of 2.2.
844         pix.load ( par->iconsPath ( "/16x16/cinnamon.png" ) );
845     }
846     else if ( command == "TRINITY" )
847     {
848         newRootless=false;
849         pix.load ( par->iconsPath ( "/16x16/trinity.png" ) );
850     }
851     else if ( command == "OPENBOX" )
852     {
853         newRootless=false;
854         pix.load ( par->iconsPath ( "/16x16/openbox.png" ) );
855     }
856     else if ( command == "ICEWM" )
857     {
858         newRootless=false;
859         pix.load ( par->iconsPath ( "/16x16/icewm.png" ) );
860     }
861     else if ( command ==tr ( "Connection to local desktop" ) )
862     {
863         newRootless=false;
864         pix.load ( par->iconsPath ( "/16x16/X.png" ) );
865         cmd="SHADOW";
866     }
867     else if ( command == tr ( "RDP connection" ) )
868     {
869         newRootless=false;
870         pix.load ( par->iconsPath ( "/16x16/rdp.png" ) );
871         cmd="RDP";
872     }
873     else if ( command == tr ( "XDMCP" ) )
874     {
875         newRootless=false;
876         pix.load ( par->iconsPath ( "/16x16/X.png" ) );
877         cmd="XDMCP";
878     }
879     else
880         pix.load ( par->iconsPath ( "/16x16/X.png" ) );
881     cmdIcon->setPixmap ( pix );
882 
883     X2goSettings st ( "sessions" );
884     if ( command=="startkde" )
885     {
886         cmd="KDE";
887         newRootless=false;
888     }
889     if ( command=="gnome-session" )
890     {
891         cmd="GNOME";
892         newRootless=false;
893     }
894     if ( command=="LXDE" )
895     {
896         cmd="LXDE";
897         newRootless=false;
898     }
899     if (command == "LXQt")
900     {
901         cmd = "LXQt";
902         newRootless = false;
903     }
904     if ( command=="unity" )
905     {
906         cmd="UNITY";
907         newRootless=false;
908     }
909     if ( command=="xfce4-session" )
910     {
911         cmd="XFCE";
912         newRootless=false;
913     }
914     if ( command=="mate-session" )
915     {
916         cmd="MATE";
917         newRootless=false;
918     }
919     if ( command=="cinnamon-session" )
920     {
921         cmd="CINNAMON";
922         newRootless=false;
923     }
924     if (command== tr("Published applications"))
925     {
926         published=true;
927         cmd="PUBLISHED";
928     }
929     bool found=false;
930     cmd=par->internAppName ( cmd,&found );
931     if ( found )
932         newRootless=true;
933     st.setting()->setValue ( sid+"/command", ( QVariant ) cmd );
934     st.setting()->setValue ( sid+"/rootless", ( QVariant ) newRootless );
935     st.setting()->setValue ( sid+"/published", ( QVariant ) published );
936     st.setting()->sync();
937 
938 }
939 
940 
slot_geom_change(const QString & new_g)941 void SessionButton::slot_geom_change ( const QString& new_g )
942 {
943     geom->setText ( new_g );
944     X2goSettings st ( "sessions" );
945     if ( new_g==tr ( "fullscreen" ) )
946     {
947         st.setting()->setValue ( sid+"/fullscreen", ( QVariant ) true );
948         st.setting()->setValue ( sid+"/multidisp", ( QVariant ) false );
949         st.setting()->setValue ( sid+"/maxdim", ( QVariant ) false );
950     }
951     else if ( new_g==tr ( "Maximum" ))
952     {
953         st.setting()->setValue ( sid+"/fullscreen", ( QVariant ) false );
954         st.setting()->setValue ( sid+"/multidisp", ( QVariant ) false );
955         st.setting()->setValue ( sid+"/maxdim", ( QVariant ) true );
956     }
957     else if (new_g.indexOf(tr("Display "))==0)
958     {
959         QString g= new_g;
960         g.replace(tr("Display "),"");
961         st.setting()->setValue ( sid+"/multidisp", ( QVariant ) true );
962         st.setting()->setValue ( sid+"/display", ( QVariant ) g.toUInt());
963         st.setting()->setValue ( sid+"/fullscreen", ( QVariant ) false );
964         st.setting()->setValue ( sid+"/maxdim", ( QVariant ) false );
965     }
966     else
967     {
968         QString new_geom=new_g;
969 #ifdef Q_WS_HILDON
970         new_geom="800x600";
971 #endif
972         st.setting()->setValue ( sid+"/fullscreen", ( QVariant ) false );
973         st.setting()->setValue ( sid+"/multidisp", ( QVariant ) false );
974         st.setting()->setValue ( sid+"/maxdim", ( QVariant ) false );
975         QStringList lst=new_geom.split ( 'x' );
976         st.setting()->setValue ( sid+"/width", ( QVariant ) lst[0] );
977         st.setting()->setValue ( sid+"/height", ( QVariant ) lst[1] );
978     }
979     st.setting()->sync();
980 }
981 
lessThen(const SessionButton * b1,const SessionButton * b2)982 bool SessionButton::lessThen ( const SessionButton* b1,
983                                const SessionButton* b2 )
984 {
985     return b1->sessName->text().toLower().localeAwareCompare (
986                b2->sessName->text().toLower() ) <0;
987 }
988 
name()989 QString SessionButton::name()
990 {
991     return nameofSession;
992 }
993 
slotMenuHide()994 void SessionButton::slotMenuHide()
995 {
996     editBut->setDown ( false );
997     editBut->setFlat ( true );
998 }
999 
1000 
slotShowMenu()1001 void SessionButton::slotShowMenu()
1002 {
1003     sessMenu->popup ( mapToGlobal ( QPoint ( editBut->x() +editBut->width(),
1004                                     editBut->y() +editBut->height() ) ) );
1005 }
1006 
1007 
slotCreateSessionIcon()1008 void SessionButton::slotCreateSessionIcon()
1009 {
1010     par->getSessionExplorer()->slotCreateDesktopIcon ( this );
1011 }
1012