1 //===========================================
2 // Lumina-DE source code
3 // Copyright (c) 2015, Ken Moore
4 // Available under the 3-clause BSD license
5 // See the LICENSE file for full details
6 //===========================================
7 #include "TrayIcon.h"
8
9 #include <QDir>
10 #include <QDesktopWidget>
11
12 #include <LUtils.h>
13
TrayIcon()14 TrayIcon::TrayIcon() : QSystemTrayIcon(){
15 //Create the child widgets here
16 settings = new QSettings("lumina-desktop","lumina-terminal");
17 this->setContextMenu(new QMenu());
18 ScreenMenu = new QMenu();
19 connect(ScreenMenu, SIGNAL(triggered(QAction*)), this, SLOT(ChangeScreen(QAction*)) );
20 TERM = new TermWindow(settings);
21 //Load the current settings
22 TERM->setTopOfScreen(settings->value("TopOfScreen",true).toBool());
23 TERM->setCurrentScreen(settings->value("OnScreen",0).toInt());
24 connect(TERM, SIGNAL(TerminalHidden()), this, SLOT(TermHidden()));
25 connect(TERM, SIGNAL(TerminalVisible()), this, SLOT(TermVisible()));
26 connect(TERM, SIGNAL(TerminalClosed()), this, SLOT(startCleanup()));
27 connect(TERM, SIGNAL(TerminalFinished()), this, SLOT(stopApplication()));
28 connect(this, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(TrayActivated(QSystemTrayIcon::ActivationReason)) );
29 }
30
~TrayIcon()31 TrayIcon::~TrayIcon(){
32 delete TERM;
33 delete ScreenMenu;
34 }
35
36 // =============
37 // PUBLIC
38 // =============
parseInputs(QStringList inputs)39 void TrayIcon::parseInputs(QStringList inputs){
40 //Note that this is only run on the primary process - otherwise inputs are sent to the slotSingleInstance() below
41 termVisible = !inputs.contains("-toggle"); //will automatically show the terminal on first run, even if "-toggle" is set
42
43 setupContextMenu();
44 updateIcons();
45 inputs = adjustInputs(inputs); //will adjust termVisible as necessary
46 if(inputs.isEmpty()){ inputs << QDir::homePath(); } //always start up with one terminal minimum
47 TERM->OpenDirs(inputs);
48 if(termVisible){ QTimer::singleShot(0, TERM, SLOT(ShowWindow())); }
49 }
50
51 // =================
52 // PUBLIC SLOTS
53 // =================
slotSingleInstance(QStringList inputs)54 void TrayIcon::slotSingleInstance(QStringList inputs){
55 //Note that this is only run for a secondary process forwarding its inputs
56 //qDebug() << "Single Instance Event:" << inputs << termVisible;
57 bool visible = termVisible;
58 inputs = adjustInputs(inputs); //will adjust termVisible as necessary
59 if(!inputs.isEmpty()){ TERM->OpenDirs(inputs); }
60 //Only adjust the window if there was a change in the visibility status
61 //qDebug() << "Set Visible:" << termVisible;
62 if(!visible && termVisible){ QTimer::singleShot(0, TERM, SLOT(ShowWindow())); }
63 else if(visible && !termVisible){ QTimer::singleShot(0, TERM, SLOT(HideWindow())); }
64 }
65
updateIcons()66 void TrayIcon::updateIcons(){
67 this->setIcon(LXDG::findIcon("utilities-terminal",""));
68 }
69
70 // ================
71 // PRIVATE
72 // ================
adjustInputs(QStringList inputs)73 QStringList TrayIcon::adjustInputs(QStringList inputs){
74 bool hasHide = false;
75 //Look for the special CLI flags just for the tray icon and trim them out
76 for(int i=0; i<inputs.length(); i++){
77 if(inputs[i]=="-toggle"){ hasHide = termVisible; inputs.removeAt(i); i--; } //toggle the visibility
78 else if(inputs[i]=="-show"){ hasHide = false; inputs.removeAt(i); i--; } //change the visibility
79 else if(inputs[i]=="-hide"){ hasHide = true; inputs.removeAt(i); i--; } //change the visibility
80 else{
81 //Must be a directory - convert to an absolute path and check for existance
82 inputs[i] = LUtils::PathToAbsolute(inputs[i]);
83 QFileInfo info(inputs[i]);
84 if(!info.exists()){
85 qDebug() << "Directory does not exist: " << inputs[i];
86 inputs.removeAt(i);
87 i--;
88 }else if(!info.isDir()){
89 //Must be some kind of file, open the parent directory
90 inputs[i] = inputs[i].section("/",0,-2);
91 }
92 }
93 }
94 termVisible = !hasHide;
95 return inputs;
96 }
97
98 // ================
99 // PRIVATE SLOTS
100 // ================
startCleanup()101 void TrayIcon::startCleanup(){
102 TERM->cleanup();
103 }
104
stopApplication()105 void TrayIcon::stopApplication(){
106 QApplication::exit(0);
107 }
108
ChangeTopBottom(bool ontop)109 void TrayIcon::ChangeTopBottom(bool ontop){
110 TERM->setTopOfScreen(ontop);
111 settings->setValue("TopOfScreen",ontop); //save for later
112 }
113
ChangeScreen(QAction * act)114 void TrayIcon::ChangeScreen(QAction *act){
115 int screen = act->whatsThis().toInt();
116 TERM->setCurrentScreen(screen);
117 settings->setValue("OnScreen",screen);
118 updateScreenMenu();
119 }
120
setupContextMenu()121 void TrayIcon::setupContextMenu(){
122 this->contextMenu()->clear();
123 this->contextMenu()->addAction(LXDG::findIcon("edit-select",""), tr("Trigger Terminal"), this, SLOT(ToggleVisibility()) );
124 this->contextMenu()->addSeparator();
125 QAction * act = this->contextMenu()->addAction(tr("Top of Screen"), this, SLOT(ChangeTopBottom(bool)) );
126 act->setCheckable(true);
127 act->setChecked(settings->value("TopOfScreen",true).toBool() );
128 this->contextMenu()->addMenu(ScreenMenu);
129 this->contextMenu()->addSeparator();
130 this->contextMenu()->addAction(LXDG::findIcon("application-exit",""), tr("Close Terminal"), this, SLOT(stopApplication()) );
131 updateScreenMenu();
132 }
133
updateScreenMenu()134 void TrayIcon::updateScreenMenu(){
135 ScreenMenu->clear();
136 QDesktopWidget *desk = QApplication::desktop();
137 int cscreen = settings->value("OnScreen",0).toInt();
138 if(cscreen>=desk->screenCount()){ cscreen = desk->primaryScreen(); }
139 ScreenMenu->setTitle(tr("Move To Monitor"));
140 for(int i=0; i<desk->screenCount(); i++){
141 if(i!=cscreen){
142 QAction *act = new QAction( QString(tr("Monitor %1")).arg(QString::number(i+1)),ScreenMenu);
143 act->setWhatsThis(QString::number(i));
144 ScreenMenu->addAction(act);
145 }
146 }
147 ScreenMenu->setVisible(!ScreenMenu->isEmpty());
148 ScreenMenu->setEnabled(!ScreenMenu->isEmpty());
149 }
150
TrayActivated(QSystemTrayIcon::ActivationReason reason)151 void TrayIcon::TrayActivated(QSystemTrayIcon::ActivationReason reason){
152 switch(reason){
153 case QSystemTrayIcon::Context:
154 this->contextMenu()->popup(this->geometry().center());
155 break;
156 default:
157 ToggleVisibility();
158 }
159 }
160
161 //Slots for the window visibility
ToggleVisibility()162 void TrayIcon::ToggleVisibility(){
163 if(termVisible){ QTimer::singleShot(0, TERM, SLOT(HideWindow())); }
164 else{ QTimer::singleShot(0, TERM, SLOT(ShowWindow())); }
165 }
166
TermHidden()167 void TrayIcon::TermHidden(){
168 termVisible = false;
169 }
170
TermVisible()171 void TrayIcon::TermVisible(){
172 termVisible = true;
173 }
174