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 <QtConcurrent/QtConcurrentRun>
8 #include "MainUI.h"
9 #include "ui_MainUI.h"
10
11 #include <QVideoFrame>
12 #include <QFileDialog>
13 #include <QMessageBox>
14
15 #include <LUtils.h>
16 #include <LuminaOS.h>
17
MainUI()18 MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){
19 ui->setupUi(this); //load the designer form
20 canwrite = false;
21 terminate_thread = false;
22 INFO = new LFileInfo();
23 UpdateIcons(); //Set all the icons in the dialog
24 SetupConnections();
25
26 //Disable buttons that are not working yet
27 //ui->actionOpen_File->setVisible(false);
28 //ui->actionOpen_Directory->setVisible(false);
29 //ui->menuSave_As->setEnabled(false);
30 }
31
~MainUI()32 MainUI::~MainUI(){
33 terminate_thread = true;
34 this->close();
35 }
36
37 //=============
38 // PUBLIC
39 //=============
LoadFile(QString path,QString type)40 void MainUI::LoadFile(QString path, QString type){
41
42 //Do the first file information tab
43 qDebug() << "Load File:" << path << type;
44 INFO = new LFileInfo(path);
45 //First load the general file information
46 if(!INFO->filePath().isEmpty()){
47 SyncFileInfo();
48 }else{
49 SetupNewFile();
50 }
51 }
52
UpdateIcons()53 void MainUI::UpdateIcons(){
54
55 }
56
57 //==============
58 // PRIVATE
59 //==============
ReloadAppIcon()60 void MainUI::ReloadAppIcon(){
61 //qDebug() << "Reload App Icon:";
62 ui->label_xdg_icon->setPixmap( LXDG::findIcon(ui->line_xdg_icon->text(),"").pixmap(64,64) );
63 //qDebug() << "Check Desktop File entry";
64 if(INFO->iconfile()!=ui->line_xdg_icon->text()){
65 xdgvaluechanged();
66 }
67 //qDebug() << "Done with app icon";
68 }
69
stopDirSize()70 void MainUI::stopDirSize(){
71 if(sizeThread.isRunning()){
72 terminate_thread = true;
73 sizeThread.waitForFinished();
74 QApplication::processEvents(); //throw away any last signals waiting to be processed
75 }
76 terminate_thread = false;
77 }
78
GetDirSize(const QString dirname) const79 void MainUI::GetDirSize(const QString dirname) const {
80 const quint16 update_frequency = 2000; //For reducing the number of folder_size_changed calls
81 quint64 filesize = 0;
82 quint64 file_number = 0;
83 quint64 dir_number = 1;
84 QDir folder(dirname);
85 QFileInfoList file_list;
86 QString dir_name;
87 QList<QString> head;
88 folder.setFilter(QDir::Hidden|QDir::AllEntries|QDir::NoDotAndDotDot);
89 file_list = folder.entryInfoList();
90 for(int i=0; i<file_list.size(); ++i) {
91 if(terminate_thread)
92 break;
93 if(file_list[i].isDir() && !file_list[i].isSymLink()) {
94 ++dir_number;
95 head.prepend(file_list[i].absoluteFilePath());
96 }
97 else
98 ++file_number;
99 if(!file_list[i].isSymLink())
100 filesize += file_list[i].size();
101 }
102 while(!head.isEmpty()) {
103 if(terminate_thread)
104 break;
105 dir_name = head.takeFirst();
106 if(!folder.cd(dir_name)) {
107 qDebug() << "The folder " << dir_name << " doesn't exist";
108 continue;
109 }
110 file_list = folder.entryInfoList();
111 for(int i=0; i<file_list.size(); ++i) {
112 if(file_list[i].isDir() && !file_list[i].isSymLink()) {
113 ++dir_number;
114 head.prepend(file_list[i].absoluteFilePath());
115 }
116 else
117 ++file_number;
118 if(!file_list[i].isSymLink())
119 filesize += file_list[i].size();
120 if(i%update_frequency == 0)
121 emit folder_size_changed(filesize, file_number, dir_number, false);
122 }
123 }
124 emit folder_size_changed(filesize, file_number, dir_number, true);
125 }
126
SyncFileInfo()127 void MainUI::SyncFileInfo(){
128 qDebug() << "Sync File Info";
129 stopDirSize();
130 if(INFO->filePath().isEmpty()){ return; }
131 if(INFO->exists()){ canwrite = INFO->isWritable(); }
132 else{
133 //See if the containing directory can be written
134 QFileInfo chk(INFO->absolutePath());
135 canwrite = (chk.isDir() && chk.isWritable());
136 }
137 ui->label_file_name->setText( INFO->fileName() );
138 ui->label_file_mimetype->setText( INFO->mimetype() );
139 if(!INFO->isDir()){ ui->label_file_size->setText( LUtils::BytesToDisplaySize( INFO->size() ) ); }
140 else {
141 ui->label_file_size->setText(tr("---Calculating---"));
142 sizeThread = QtConcurrent::run(this, &MainUI::GetDirSize, INFO->absoluteFilePath());
143 }
144 ui->label_file_owner->setText(INFO->owner());
145 ui->label_file_group->setText(INFO->group());
146 ui->label_file_created->setText( INFO->birthTime().toString(Qt::SystemLocaleLongDate) );
147 ui->label_file_modified->setText( INFO->lastModified().toString(Qt::SystemLocaleLongDate) );
148 //Get the file permissions
149 QString perms;
150 if(INFO->isReadable() && INFO->isWritable()){ perms = tr("Read/Write"); }
151 else if(INFO->isReadable()){ perms = tr("Read Only"); }
152 else if(INFO->isWritable()){ perms = tr("Write Only"); }
153 else{ perms = tr("No Access"); }
154 ui->label_file_perms->setText(perms);
155 //Now the special "type" for the file
156 QString ftype;
157 if(INFO->suffix().toLower()=="desktop"){ ftype = tr("XDG Shortcut"); }
158 else if(INFO->isDir()){ ftype = tr("Directory"); }
159 else if(INFO->isExecutable()){ ftype = tr("Binary"); }
160 else{ ftype = INFO->suffix().toUpper(); }
161 if(INFO->isHidden()){ ftype = QString(tr("Hidden %1")).arg(ftype); }
162 ui->label_file_type->setText(ftype);
163
164 //Now load the icon for the file
165 if(INFO->isImage()){
166 QPixmap pix(INFO->absoluteFilePath());
167 ui->label_file_icon->setPixmap(pix.scaledToHeight(64));
168 ui->label_file_size->setText( ui->label_file_size->text()+" ("+QString::number(pix.width())+" x "+QString::number(pix.height())+" px)" );
169 }else if(INFO->isVideo()){
170 ui->label_file_icon->hide();
171 LVideoLabel *mediaLabel = new LVideoLabel(INFO->absoluteFilePath(), true, ui->tab_file);
172 mediaLabel->setFixedSize(64,64);
173 ui->formLayout->replaceWidget(ui->label_file_icon, mediaLabel);
174 }else{
175 ui->label_file_icon->setPixmap( LXDG::findIcon( INFO->iconfile(), "unknown").pixmap(QSize(64,64)) );
176 }
177
178 //qDebug() << "Check XDG Info:"
179 //qDebug() << INFO->isDesktopFile() << type;
180 syncXdgStruct(INFO->XDG());
181 //Make sure the right tabs are available
182 if(ui->tabWidget->indexOf(ui->tab_file)<0){
183 //qDebug() << "Add File Info Tab";
184 ui->tabWidget->insertTab(0, ui->tab_file, tr("File Information"));
185 }
186 if(!INFO->isDesktopFile()){
187 if(ui->tabWidget->indexOf(ui->tab_deskedit)>=0){
188 ui->tabWidget->removeTab( ui->tabWidget->indexOf(ui->tab_deskedit) );
189 }
190 }else if(ui->tabWidget->indexOf(ui->tab_deskedit)<0){
191 ui->tabWidget->addTab( ui->tab_deskedit, tr("XDG Shortcut") );
192 }
193 ui->tabWidget->setCurrentIndex(ui->tabWidget->indexOf(ui->tab_file) );
194 SyncZfsInfo();
195 }
196
SyncZfsInfo()197 void MainUI::SyncZfsInfo(){
198 bool showtab = false;
199 if(INFO->zfsPool().isEmpty()){
200 //Not on a ZFS pool - hide the tab if it is available
201 showtab = false;
202 }else{
203 qDebug() << "Is a ZFS Dataset:" << INFO->isZfsDataset();
204 ui->label_zfs_pool->setText(INFO->zfsPool());
205 if(INFO->isZfsDataset()){
206 ui->tree_zfs_props->clear();
207 QJsonObject props = INFO->zfsProperties();
208 QStringList keys = props.keys();
209 for(int i=0; i<keys.length(); i++){
210 ui->tree_zfs_props->addTopLevelItem( new QTreeWidgetItem(QStringList() << keys[i] << props.value(keys[i]).toObject().value("value").toString() << props.value(keys[i]).toObject().value("source").toString() ) );
211 ui->tree_zfs_props->resizeColumnToContents(0);
212 ui->tree_zfs_props->resizeColumnToContents(1);
213 }
214 ui->tree_zfs_props->setVisible(!keys.isEmpty());
215 showtab = !keys.isEmpty();
216 }else{
217 ui->tree_zfs_props->setVisible(false);
218 }
219 QStringList snaps = INFO->zfsSnapshots();
220 ui->tree_zfs_snaps->clear();
221 for(int i=0; i<snaps.length(); i++){
222 QFileInfo finfo(snaps[i].section("::::",1,-1));
223 ui->tree_zfs_snaps->addTopLevelItem( new QTreeWidgetItem(QStringList() << snaps[i].section("::::",0,0) << finfo.birthTime().toString(Qt::SystemLocaleShortDate) << finfo.lastModified().toString(Qt::SystemLocaleShortDate) ) );
224 ui->tree_zfs_snaps->resizeColumnToContents(0);
225 }
226 ui->tree_zfs_snaps->setVisible(!snaps.isEmpty());
227 showtab = showtab || !snaps.isEmpty();
228 }
229 if(showtab){
230 //Make sure the tab is visible
231 if(ui->tabWidget->indexOf(ui->tab_zfs)<0){
232 ui->tabWidget->addTab( ui->tab_zfs, tr("Advanced") );
233 }
234 }else{
235 //hide the tab if it is visible right now
236 if(ui->tabWidget->indexOf(ui->tab_zfs)>=0){
237 ui->tabWidget->removeTab( ui->tabWidget->indexOf(ui->tab_zfs) );
238 }
239 }
240 }
241
SetupNewFile()242 void MainUI::SetupNewFile(){
243 //qDebug() << "Setup New File";
244 if(!INFO->filePath().isEmpty()){
245 INFO = new LFileInfo();
246 }
247 stopDirSize();
248 canwrite = true; //can always write a new file
249 syncXdgStruct(INFO->XDG());
250 //Make sure the right tabs are enabled
251 if(ui->tabWidget->indexOf(ui->tab_file)>=0){
252 ui->tabWidget->removeTab( ui->tabWidget->indexOf(ui->tab_file) );
253 }
254 if(ui->tabWidget->indexOf(ui->tab_deskedit)<0){
255 //qDebug() << "Adding the deskedit tab";
256 ui->tabWidget->addTab(ui->tab_deskedit, tr("XDG Shortcut"));
257 }
258 //Not on a ZFS pool - hide the tab if it is available
259 if(ui->tabWidget->indexOf(ui->tab_zfs)>=0){
260 ui->tabWidget->removeTab( ui->tabWidget->indexOf(ui->tab_zfs) );
261 }
262 ui->tabWidget->setCurrentIndex(ui->tabWidget->indexOf(ui->tab_deskedit) );
263 }
264
syncXdgStruct(XDGDesktop * XDG)265 void MainUI::syncXdgStruct(XDGDesktop *XDG){
266 bool cleanup = false;
267 if(XDG==0){ XDG = new XDGDesktop(); cleanup = true;} //make sure nothing crashes
268 if(XDG->type == XDGDesktop::APP){
269 ui->line_xdg_command->setText(XDG->exec);
270 ui->line_xdg_wdir->setText(XDG->path);
271 ui->check_xdg_useTerminal->setChecked( XDG->useTerminal );
272 ui->check_xdg_startupNotify->setChecked( XDG->startupNotify );
273 }else if(XDG->type==XDGDesktop::LINK){
274 //Hide the options that are unavailable for links
275 //Command line (exec)
276 ui->line_xdg_command->setVisible(false);
277 ui->tool_xdg_getCommand->setVisible(false);
278 ui->lblCommand->setVisible(false);
279 //Options
280 ui->lblOptions->setVisible(false);
281 ui->check_xdg_useTerminal->setVisible(false);
282 ui->check_xdg_startupNotify->setVisible(false);
283 //Now load the variables for this type of shortcut
284 ui->lblWorkingDir->setText(tr("URL:"));
285 ui->line_xdg_wdir->setText( XDG->url );
286 ui->tool_xdg_getDir->setVisible(false); //the dir selection button
287 }
288 ui->line_xdg_name->setText(XDG->name);
289 ui->line_xdg_comment->setText(XDG->comment);
290 ui->line_xdg_icon->setText( XDG->icon );
291 ReloadAppIcon();
292 ui->actionSave_Shortcut->setVisible(true);
293 ui->actionSave_Shortcut->setEnabled(false);
294 if(cleanup){ delete XDG; }
295 checkXDGValidity();
296 }
297
saveFile(QString path)298 bool MainUI::saveFile(QString path){
299 //qDebug() << "Request save file:" << path;
300 XDGDesktop *XDG = INFO->XDG();
301 if(XDG==0){ XDG = new XDGDesktop(); }
302 if(XDG->type == XDGDesktop::BAD){ XDG->type = XDGDesktop::APP; }
303 //Update the file path in the data structure
304 XDG->filePath = path;
305 //Now change the structure
306 XDG->name = ui->line_xdg_name->text();
307 XDG->genericName = ui->line_xdg_name->text().toLower();
308 XDG->comment = ui->line_xdg_comment->text();
309 XDG->icon = ui->line_xdg_icon->text();
310 //Now do the type-specific fields
311 if(XDG->type == XDGDesktop::APP){
312 XDG->exec = ui->line_xdg_command->text();
313 XDG->tryexec = ui->line_xdg_command->text().section(" ",0,0); //use the first word/binary for the existance check
314 XDG->path = ui->line_xdg_wdir->text(); //working dir/path
315 XDG->useTerminal = ui->check_xdg_useTerminal->isChecked();
316 XDG->startupNotify = ui->check_xdg_startupNotify->isChecked();
317 }else if(XDG->type==XDGDesktop::LINK){
318 XDG->url = ui->line_xdg_wdir->text(); //we re-used this field
319 }
320 //Clear any info which this utility does not support at the moment
321 XDG->actionList.clear();
322 XDG->actions.clear();
323 //Now save the structure to file
324 //qDebug() << "Saving File:" << XDG->filePath;
325 return XDG->saveDesktopFile(true); //Try to merge the file/structure as necessary
326 }
327
findOpenDirFile(bool isdir)328 QString MainUI::findOpenDirFile(bool isdir){
329 static QList<QUrl> urls;
330 if(urls.isEmpty()){
331 urls << QUrl::fromLocalFile("/");
332 QStringList dirs = QString(getenv("XDG_DATA_DIRS")).split(":");
333 for(int i=0; i<dirs.length(); i++){
334 if(QFile::exists(dirs[i]+"/applications")){ urls << QUrl::fromLocalFile(dirs[i]+"/applications"); }
335 }
336 //Now do the home-directory folders
337 urls << QUrl::fromLocalFile(QDir::homePath());
338 QString localapps = QString(getenv("XDG_DATA_HOME"))+"/applications";
339 if(QFile::exists(localapps)){ urls << QUrl::fromLocalFile(localapps); }
340 }
341 static QString lastdir = QDir::homePath();
342 QFileDialog dlg(this);
343 dlg.setAcceptMode(QFileDialog::AcceptOpen);
344 dlg.setFileMode( isdir ? QFileDialog::Directory : QFileDialog::ExistingFiles );
345 dlg.setOptions(QFileDialog::ReadOnly | QFileDialog::HideNameFilterDetails);
346 dlg.setViewMode(QFileDialog::Detail);
347 dlg.setSidebarUrls( urls );
348 dlg.setDirectory(lastdir);
349 if(!dlg.exec() ){ return ""; } //cancelled
350 if(dlg.selectedFiles().isEmpty()){ return ""; }
351 QString path = dlg.selectedFiles().first();
352 //Update the last used directory
353 if(isdir){ lastdir = path; } //save this for next time
354 else{ lastdir = path.section("/",0,-2); }
355 //return the path
356 return path;
357 }
358
359
360 // Initialization procedures
SetupConnections()361 void MainUI::SetupConnections(){
362 connect(ui->actionQuit, SIGNAL(triggered()), this, SLOT(closeApplication()) );
363 connect(ui->actionSave_Shortcut, SIGNAL(triggered()), this, SLOT(save_clicked()) );
364 connect(ui->actionLocal_Shortcut, SIGNAL(triggered()), this, SLOT(save_as_local_clicked()) );
365 connect(ui->actionRegister_Shortcut, SIGNAL(triggered()), this, SLOT(save_as_register_clicked()) );
366 connect(ui->actionNew_Shortcut, SIGNAL(triggered()), this, SLOT(SetupNewFile()) );
367 connect(ui->actionOpen_File, SIGNAL(triggered()), this, SLOT(open_file_clicked()) );
368 connect(ui->actionOpen_Directory, SIGNAL(triggered()), this, SLOT(open_dir_clicked()) );
369 connect(ui->line_xdg_command, SIGNAL(editingFinished()), this, SLOT(xdgvaluechanged()) );
370 connect(ui->line_xdg_comment, SIGNAL(editingFinished()), this, SLOT(xdgvaluechanged()) );
371 connect(ui->line_xdg_icon, SIGNAL(textChanged(QString)), this, SLOT(ReloadAppIcon()) );
372 connect(ui->tool_xdg_getCommand, SIGNAL(clicked()), this, SLOT(getXdgCommand()) );
373 connect(ui->line_xdg_name, SIGNAL(editingFinished()), this, SLOT(xdgvaluechanged()) );
374 connect(ui->line_xdg_wdir, SIGNAL(editingFinished()), this, SLOT(xdgvaluechanged()) );
375 connect(ui->check_xdg_useTerminal, SIGNAL(clicked()), this, SLOT(xdgvaluechanged()) );
376 connect(ui->check_xdg_startupNotify, SIGNAL(clicked()), this, SLOT(xdgvaluechanged()) );
377 connect(this, SIGNAL(folder_size_changed(quint64, quint64, quint64, bool)), this, SLOT(refresh_folder_size(quint64, quint64, quint64, bool)));
378 }
379
380 //UI Buttons
closeApplication()381 void MainUI::closeApplication(){
382 terminate_thread = true;
383 if(ui->actionSave_Shortcut->isEnabled()){
384 //Still have unsaved changes
385 //TO-DO - prompt for whether to save the changes
386 }
387 this->close();
388 }
389
save_clicked()390 void MainUI::save_clicked(){
391 //Save all the xdg values into the structure
392 QString filePath = INFO->filePath();
393 if( !filePath.isEmpty() && !INFO->isDesktopFile() ){ return; }
394 if(filePath.isEmpty() || !canwrite){
395 //Need to prompt for where to save the file and what to call it
396 QString appdir = QString(getenv("XDG_DATA_HOME"))+"/applications/";
397 if(!QFile::exists(appdir)){ QDir dir; dir.mkpath(appdir); }
398 filePath = QFileDialog::getSaveFileName(this, tr("Save Application File"), appdir, tr("XDG Shortcuts (*.desktop)") );
399 if(filePath.isEmpty()){ return; }
400 if(!filePath.endsWith(".desktop")){ filePath.append(".desktop"); }
401 }
402 //qDebug() << " -Try Saving File:" << filePath;
403 bool saved = saveFile(filePath);
404 //qDebug() << "File Saved:" << saved;
405 ui->actionSave_Shortcut->setEnabled( !saved );
406 if(saved){
407 //Re-load the file info
408 LoadFile(filePath);
409 }
410 }
411
save_as_local_clicked()412 void MainUI::save_as_local_clicked(){
413 QString filePath = QFileDialog::getSaveFileName(this, tr("Save Application File"), QDir::homePath(), tr("XDG Shortcuts (*.desktop)") );
414 if(filePath.isEmpty()){ return; }
415 if(!filePath.endsWith(".desktop")){ filePath.append(".desktop"); }
416
417 //qDebug() << " -Try Saving File:" << filePath;
418 bool saved = saveFile(filePath);
419 //qDebug() << "File Saved:" << saved;
420 ui->actionSave_Shortcut->setEnabled( !saved );
421 if(saved){
422 //Re-load the file info
423 LoadFile(filePath);
424 }
425 }
426
save_as_register_clicked()427 void MainUI::save_as_register_clicked(){
428 QString appdir = QString(getenv("XDG_DATA_HOME"))+"/applications/";
429 if(!QFile::exists(appdir)){ QDir dir; dir.mkpath(appdir); }
430 QString filePath = QFileDialog::getSaveFileName(this, tr("Save Application File"), appdir, tr("XDG Shortcuts (*.desktop)") );
431 if(filePath.isEmpty()){ return; }
432 if(!filePath.endsWith(".desktop")){ filePath.append(".desktop"); }
433
434 //qDebug() << " -Try Saving File:" << filePath;
435 bool saved = saveFile(filePath);
436 //qDebug() << "File Saved:" << saved;
437 ui->actionSave_Shortcut->setEnabled( !saved );
438 if(saved){
439 //Re-load the file info
440 LoadFile(filePath);
441 }
442 }
443
open_dir_clicked()444 void MainUI::open_dir_clicked(){
445 QString path = findOpenDirFile(true); //directory only
446 if(path.isEmpty()){ return; }
447 LoadFile(path, "");
448 }
449
open_file_clicked()450 void MainUI::open_file_clicked(){
451 QString path = findOpenDirFile(false); //files only
452 if(path.isEmpty()){ return; }
453 LoadFile(path, "");
454 }
455
getXdgCommand(QString prev)456 void MainUI::getXdgCommand(QString prev){
457 //Find a binary to run
458 QString dir = prev; //start with the previous attempt (if there was one)
459 if(dir.isEmpty()){ ui->line_xdg_command->text(); }//then try current selection
460 if(dir.isEmpty()){ dir = LOS::AppPrefix()+"bin"; } //then open the application binaries directory
461 QString file = QFileDialog::getOpenFileName(this, tr("Select a binary"), dir );
462 if(file.isEmpty()){ return; } //cancelled
463 if(!LUtils::isValidBinary(file)){
464 QMessageBox::warning(this, tr("Error"), tr("Invalid selection: Not a valid executable"));
465 getXdgCommand(file);
466 return;
467 }
468 ui->line_xdg_command->setText(file);
469 xdgvaluechanged();
470 }
471
on_tool_xdg_getDir_clicked()472 void MainUI::on_tool_xdg_getDir_clicked(){
473 //Find a directory
474 QString dir = ui->line_xdg_wdir->text();
475 if(dir.isEmpty()){ dir = QDir::homePath(); }
476 dir = QFileDialog::getExistingDirectory(this, tr("Select a directory"), dir);
477 if(dir.isEmpty()){ return; } //cancelled
478 ui->line_xdg_wdir->setText(dir);
479 xdgvaluechanged();
480 }
481
on_push_xdg_getIcon_clicked()482 void MainUI::on_push_xdg_getIcon_clicked(){
483 //Find an image file
484 QString dir = ui->push_xdg_getIcon->whatsThis(); //then try current selection
485 if(dir.isEmpty()){ dir = QDir::homePath(); }
486 //Get the known file extensions
487 QStringList ext = LUtils::imageExtensions();
488 for(int i=0; i<ext.length(); i++){ ext[i].prepend("*."); } //turn them into valid filters
489 QString file = QFileDialog::getOpenFileName(this, tr("Select an icon"), dir ,QString(tr("Images (%1);; All Files (*)")).arg(ext.join(" ")) );
490 if(file.isEmpty()){ return; } //cancelled
491 ui->line_xdg_icon->setText(file);
492 ReloadAppIcon();
493 xdgvaluechanged();
494 }
495
496 //XDG Value Changed
checkXDGValidity()497 bool MainUI::checkXDGValidity(){
498 XDGDesktop tmp;
499 tmp.type = XDGDesktop::APP; //make this adjustable later (GUI radio buttons?)
500 tmp.name = ui->line_xdg_name->text();
501 tmp.genericName = ui->line_xdg_name->text().toLower();
502 tmp.comment = ui->line_xdg_comment->text();
503 tmp.icon = ui->line_xdg_icon->text();
504 //Now do the type-specific fields
505 if(tmp.type == XDGDesktop::APP){
506 tmp.exec = ui->line_xdg_command->text();
507 tmp.tryexec = ui->line_xdg_command->text().section(" ",0,0); //use the first word/binary for the existance check
508 tmp.path = ui->line_xdg_wdir->text(); //working dir/path
509 tmp.useTerminal = ui->check_xdg_useTerminal->isChecked();
510 tmp.startupNotify = ui->check_xdg_startupNotify->isChecked();
511 }else if(tmp.type==XDGDesktop::LINK){
512 tmp.url = ui->line_xdg_wdir->text(); //we re-used this field
513 }
514 bool valid = tmp.isValid();
515 ui->label_xdg_statusicon->setPixmap( LXDG::findIcon( valid ? "dialog-ok" : "dialog-cancel", "").pixmap(32,32) );
516 ui->label_xdg_status->setText( valid ? tr("Valid Settings") : tr("Invalid Settings") );
517 return tmp.isValid();
518 }
519
xdgvaluechanged()520 void MainUI::xdgvaluechanged(){
521 //qDebug() << "xdgvaluechanged";
522 if( INFO->isDesktopFile() || INFO->filePath().isEmpty() ){
523 bool valid = checkXDGValidity();
524 //Compare the current UI values to the file values
525 ui->menuSave_As->setEnabled(valid);
526 ui->actionSave_Shortcut->setEnabled(canwrite && valid); //assume changed at this point
527
528 }else{
529 ui->actionSave_Shortcut->setEnabled(false);
530 }
531 }
532
refresh_folder_size(quint64 size,quint64 files,quint64 folders,bool finished)533 void MainUI::refresh_folder_size(quint64 size, quint64 files, quint64 folders, bool finished) {
534 if(finished)
535 ui->label_file_size->setText( LUtils::BytesToDisplaySize( size ) + " -- " + tr(" Folders: ") + QString::number(folders) + " / " + tr("Files: ") + QString::number(files) );
536 else
537 ui->label_file_size->setText( LUtils::BytesToDisplaySize( size ) + " -- " + tr(" Folders: ") + QString::number(folders) + " / " + tr("Files: ") + QString::number(files) + tr(" Calculating..." ));
538 }
539