1 //===========================================
2 //  Lumina Desktop Source Code
3 //  Copyright (c) 2016, Ken Moore
4 //  Available under the 3-clause BSD license
5 //  See the LICENSE file for full details
6 //===========================================
7 #include "page_defaultapps.h"
8 #include "ui_page_defaultapps.h"
9 #include "../AppDialog.h"
10 
11 //==========
12 //    PUBLIC
13 //==========
page_defaultapps(QWidget * parent)14 page_defaultapps::page_defaultapps(QWidget *parent) : PageWidget(parent), ui(new Ui::page_defaultapps()){
15   ui->setupUi(this);
16 
17   connect(ui->tool_default_filemanager, SIGNAL(clicked()), this, SLOT(changeDefaultFileManager()) );
18   connect(ui->tool_default_terminal, SIGNAL(clicked()), this, SLOT(changeDefaultTerminal()) );
19   connect(ui->tool_default_webbrowser, SIGNAL(clicked()), this, SLOT(changeDefaultBrowser()) );
20   connect(ui->tool_default_email, SIGNAL(clicked()), this, SLOT(changeDefaultEmail()) );
21   connect(ui->tool_defaults_clear, SIGNAL(clicked()), this, SLOT(cleardefaultitem()) );
22   connect(ui->tool_defaults_set, SIGNAL(clicked()), this, SLOT(setdefaultitem()) );
23   connect(ui->tool_defaults_setbin, SIGNAL(clicked()), this, SLOT(setdefaultbinary()) );
24   connect(ui->tree_defaults, SIGNAL(itemSelectionChanged()), this, SLOT(checkdefaulticons()) );
25   updateIcons();
26   ui->tabWidget_apps->setCurrentWidget(ui->tab_auto);
27 }
28 
~page_defaultapps()29 page_defaultapps::~page_defaultapps(){
30 
31 }
32 
33 //================
34 //    PUBLIC SLOTS
35 //================
SaveSettings()36 void page_defaultapps::SaveSettings(){
37 
38 }
39 
LoadSettings(int)40 void page_defaultapps::LoadSettings(int){
41   emit HasPendingChanges(false);
42   emit ChangePageTitle( tr("Default Applications") );
43 
44   //First load the lumina-open specific defaults
45   //  - Default File Manager
46   defaultFileManager = LXDG::findDefaultAppForMime("inode/directory");
47   if(defaultFileManager.isEmpty()){ defaultFileManager = "lumina-fm"; }
48   updateDefaultButton(ui->tool_default_filemanager, defaultFileManager);
49 
50   // - Default Terminal
51   defaultTerminal = LXDG::findDefaultAppForMime("application/terminal"); //sessionsettings->value("default-terminal", "xterm").toString();
52   updateDefaultButton(ui->tool_default_terminal, defaultTerminal);
53 
54   // - Default Web Browser
55   defaultBrowser = LXDG::findDefaultAppForMime("x-scheme-handler/http"); //appsettings->value("default/webbrowser", "").toString();
56   updateDefaultButton(ui->tool_default_webbrowser, defaultBrowser);
57 
58   // - Default Email Client
59   defaultEmail = LXDG::findDefaultAppForMime("application/email"); //appsettings->value("default/email", "").toString();
60   updateDefaultButton(ui->tool_default_email, defaultEmail);
61 
62   //Now load the XDG mime defaults
63   ui->tree_defaults->clear();
64   QStringList defMimeList = LXDG::listFileMimeDefaults();
65   //qDebug() << "Mime List:\n" << defMimeList.join("\n");
66   defMimeList.sort(); //sort by group/mime
67   //Now fill the tree by group/mime
68   QTreeWidgetItem *group = 0;
69   QString ccat;
70   for(int i=0; i<defMimeList.length(); i++){
71     //Get the info from this entry
72     QString mime = defMimeList[i].section("::::",0,0);
73     QString cat = mime.section("/",0,0);
74     QString extlist = defMimeList[i].section("::::",1,1);
75     QString def = defMimeList[i].section("::::",2,2);
76     QString comment = defMimeList[i].section("::::",3,50);
77     //Now check if this is a new category
78     if(group == 0 || ccat!=cat){
79 	    //New group
80 	    group = new QTreeWidgetItem(0);
81 	    group->setText(0, cat); //add translations for known/common groups later
82     	ui->tree_defaults->addTopLevelItem(group);
83     	ccat = cat;
84     }
85     //Now create the entry
86     QTreeWidgetItem *it = new QTreeWidgetItem();
87     it->setWhatsThis(0,mime); // full mimetype
88     it->setText(0, QString(tr("%1 (%2)")).arg(mime.section("/",-1), extlist) );
89     it->setText(2,comment);
90     it->setToolTip(0, comment); it->setToolTip(1,comment);
91     //Now load the default (if there is one)
92     it->setWhatsThis(1,def); //save for later
93     it->setData(1, Qt::UserRole, def);
94     if(def.endsWith(".desktop")){
95       XDGDesktop file(def);
96       if(file.type == XDGDesktop::BAD){
97         //Might be a binary - just print out the raw "path"
98         it->setText(1, def.section("/",-1));
99         it->setIcon(1, LXDG::findIcon("application-x-executable","") );
100       }else{
101         it->setText(1, file.name);
102         it->setIcon(1, LXDG::findIcon(file.icon,"") );
103       }
104     }else if(!def.isEmpty()){
105       //Binary/Other default
106       it->setText(1, def.section("/",-1));
107       it->setIcon(1, LXDG::findIcon("application-x-executable","") );
108     }
109     group->addChild(it);
110   }
111 
112   ui->tree_defaults->sortItems(0,Qt::AscendingOrder);
113 
114   checkdefaulticons();
115 }
116 
updateIcons()117 void page_defaultapps::updateIcons(){
118   ui->tool_defaults_clear->setIcon( LXDG::findIcon("edit-clear","") );
119   ui->tool_defaults_set->setIcon( LXDG::findIcon("system-run","") );
120   ui->tool_defaults_setbin->setIcon( LXDG::findIcon("application-x-executable","") );
121   ui->tabWidget_apps->setTabIcon( ui->tabWidget_apps->indexOf(ui->tab_auto), LXDG::findIcon("system-run", "") );
122   ui->tabWidget_apps->setTabIcon( ui->tabWidget_apps->indexOf(ui->tab_defaults), LXDG::findIcon("preferences-desktop-filetype-association", "") );
123 }
124 
125 //=================
126 //         PRIVATE
127 //=================
getSysApp(bool allowreset,QString defaultPath)128 QString page_defaultapps::getSysApp(bool allowreset, QString defaultPath){
129   AppDialog dlg(this, defaultPath);
130     dlg.allowReset(allowreset);
131     dlg.exec();
132   if(dlg.appreset && allowreset){
133     return "reset";
134   }else{
135     return dlg.appselected;
136   }
137 }
138 
updateDefaultButton(QToolButton * button,QString app)139 void page_defaultapps::updateDefaultButton(QToolButton *button, QString app){
140   if( !QFile::exists(app) && !LUtils::isValidBinary(app) ){ qDebug() << "Invalid Settings:" << app; app.clear(); } //invalid settings
141   if(app.endsWith(".desktop")){
142     XDGDesktop file(app);
143     if(file.type == XDGDesktop::BAD){
144       //Might be a binary - just print out the raw "path"
145       button->setText(app.section("/",-1));
146       button->setIcon( LXDG::findIcon("application-x-executable","") );
147     }else{
148       button->setText(file.name);
149       button->setIcon(LXDG::findIcon(file.icon,"") );
150     }
151   }else if(app.isEmpty()){
152     button->setText(tr("Click to Set"));
153     button->setIcon( LXDG::findIcon("system-help","") );
154   }else{
155     //Might be a binary - just print out the raw "path"
156       button->setText(app.section("/",-1));
157       button->setIcon( LXDG::findIcon("application-x-executable","") );
158   }
159 }
160 
161 //=================
162 //    PRIVATE SLOTS
163 //=================
changeDefaultBrowser()164 void page_defaultapps::changeDefaultBrowser(){
165   //Prompt for the new app
166   QString app = getSysApp(true, defaultBrowser);
167   if(app.isEmpty()){ return; }//nothing selected
168   if(app=="reset"){ app.clear(); }
169   //save the new app setting and adjust the button appearance
170   defaultBrowser = app;
171   LXDG::setDefaultAppForMime("x-scheme-handler/http", app.section("/",-1));
172   LXDG::setDefaultAppForMime("x-scheme-handler/https", app.section("/",-1));
173   updateDefaultButton(ui->tool_default_webbrowser, app);
174 }
175 
changeDefaultEmail()176 void page_defaultapps::changeDefaultEmail(){
177   //Prompt for the new app
178   QString app = getSysApp(true, defaultEmail);
179   if(app.isEmpty()){ return; }//nothing selected
180   if(app=="reset"){ app.clear(); }
181   //save the new app setting and adjust the button appearance
182   defaultEmail = app;
183   LXDG::setDefaultAppForMime("application/email",app.section("/",-1));
184   updateDefaultButton(ui->tool_default_email, app);
185 }
186 
changeDefaultFileManager()187 void page_defaultapps::changeDefaultFileManager(){
188   //Prompt for the new app
189   QString app = getSysApp(true, defaultFileManager);
190   if(app.isEmpty()){ return; }//nothing selected
191   if(app=="reset"){ app = "lumina-fm"; }
192   //save the new app setting and adjust the button appearance
193   defaultFileManager = app;
194   LXDG::setDefaultAppForMime("inode/directory", app.section("/",-1));
195   updateDefaultButton(ui->tool_default_filemanager, app);
196 }
197 
changeDefaultTerminal()198 void page_defaultapps::changeDefaultTerminal(){
199   //Prompt for the new app
200   QString app = getSysApp(true, defaultTerminal);
201   if(app.isEmpty()){ return; }//nothing selected
202   if(app=="reset"){ app = "xterm"; }
203   //save the new app setting and adjust the button appearance
204   defaultTerminal = app;
205   LXDG::setDefaultAppForMime("application/terminal", app.section("/",-1) );
206   updateDefaultButton(ui->tool_default_terminal, app);
207 }
208 
cleardefaultitem()209 void page_defaultapps::cleardefaultitem(){
210   QTreeWidgetItem *it = ui->tree_defaults->currentItem();
211   if(it==0){ return; } //no item selected
212   QList<QTreeWidgetItem*> list;
213   for(int i=0; i<it->childCount(); i++){
214     list << it->child(i);
215   }
216   if(list.isEmpty()){ list << it; } //just do the current item
217   //Now clear the items
218   for(int i=0; i<list.length(); i++){
219     //Clear it in the back end
220     LXDG::setDefaultAppForMime(list[i]->whatsThis(0), "");
221     //Now clear it in the UI
222     list[i]->setWhatsThis(1,""); //clear the app path
223     list[i]->setIcon(1,QIcon()); //clear the icon
224     list[i]->setText(1,""); //clear the name
225   }
226 
227 }
228 
setdefaultitem()229 void page_defaultapps::setdefaultitem(){
230   QTreeWidgetItem *it = ui->tree_defaults->currentItem();
231   QString path;
232   if(it==0){ return; } //no item selected
233   QList<QTreeWidgetItem*> list;
234   for(int i=0; i<it->childCount(); i++){
235     list << it->child(i);
236   }
237   if(list.isEmpty()){
238     //just do the current item
239     list << it;
240     path = it->data(1, Qt::UserRole).toString();
241   }
242   //Prompt for which application to use
243   QString app = getSysApp(false, path); //no "reset"  option
244     if(app.isEmpty()){ return; }//nothing selected
245   //Now set the items
246   for(int i=0; i<list.length(); i++){
247     //Set it in the back end
248     LXDG::setDefaultAppForMime(list[i]->whatsThis(0), app);
249     //Set it in the UI
250     XDGDesktop desk(app);
251     list[i]->setWhatsThis(1,app); //app path
252     list[i]->setIcon(1,LXDG::findIcon(desk.icon,"")); //reset the icon
253     list[i]->setText(1,desk.name); //reset the name
254     list[i]->setData(1, Qt::UserRole, app);
255   }
256 
257 }
258 
setdefaultbinary()259 void page_defaultapps::setdefaultbinary(){
260   QTreeWidgetItem *it = ui->tree_defaults->currentItem();
261   if(it==0){ return; } //no item selected
262   QList<QTreeWidgetItem*> list;
263   for(int i=0; i<it->childCount(); i++){
264     list << it->child(i);
265   }
266   if(list.isEmpty()){ list << it; } //just do the current item
267   //Prompt for which binary to use
268   QFileDialog dlg(this);
269     //dlg.setFilter(QDir::Executable | QDir::Files); //Does not work! Filters executable files as well as breaks browsing capabilities
270     dlg.setFileMode(QFileDialog::ExistingFile);
271     dlg.setDirectory( LOS::AppPrefix()+"bin" );
272     dlg.setWindowTitle(tr("Select Binary"));
273   if( !dlg.exec() || dlg.selectedFiles().isEmpty() ){
274     return; //cancelled
275   }
276   QString path = dlg.selectedFiles().first();
277   //Make sure it is executable
278   if( !QFileInfo(path).isExecutable()){
279     QMessageBox::warning(this, tr("Invalid Binary"), tr("The selected binary is not executable!"));
280     return;
281   }
282   //Now set the items
283   for(int i=0; i<list.length(); i++){
284     //Set it in the back end
285     LXDG::setDefaultAppForMime(list[i]->whatsThis(0), path);
286     //Set it in the UI
287     list[i]->setWhatsThis(1,path); //app path
288     list[i]->setIcon(1,LXDG::findIcon("application-x-executable","")); //clear the icon
289     list[i]->setText(1,path.section("/",-1)); //clear the name
290   }
291 }
292 
checkdefaulticons()293 void page_defaultapps::checkdefaulticons(){
294   QTreeWidgetItem *it = ui->tree_defaults->currentItem();
295   ui->tool_defaults_set->setEnabled(it!=0);
296   ui->tool_defaults_clear->setEnabled(it!=0);
297   ui->tool_defaults_setbin->setEnabled(it!=0);
298 }
299