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_wallpaper.h"
8 #include "ui_page_wallpaper.h"
9 
10 //==========
11 //    PUBLIC
12 //==========
page_wallpaper(QWidget * parent)13 page_wallpaper::page_wallpaper(QWidget *parent) : PageWidget(parent), ui(new Ui::page_wallpaper()){
14   ui->setupUi(this);
15   DEFAULTBG = LOS::LuminaShare()+"/desktop-background.jpg";
16   updateIcons();
17   connect(ui->combo_desk_bg, SIGNAL(currentIndexChanged(int)), this, SLOT(deskbgchanged()) );
18   connect(ui->radio_desk_multi, SIGNAL(toggled(bool)), this, SLOT(desktimechanged()) );
19   connect(ui->tool_desk_addbg, SIGNAL(clicked()), this, SLOT(deskbgadded()) );
20   connect(ui->tool_desk_rmbg, SIGNAL(clicked()), this, SLOT(deskbgremoved()) );
21   connect(ui->spin_desk_min, SIGNAL(valueChanged(int)), this, SLOT(desktimechanged()) );
22   connect(ui->combo_desk_layout, SIGNAL(currentIndexChanged(int)), this, SLOT(desktimechanged()) ); //just need to poke the save routines
23 }
24 
~page_wallpaper()25 page_wallpaper::~page_wallpaper(){
26 
27 }
28 
29 //================
30 //    PUBLIC SLOTS
31 //================
SaveSettings()32 void page_wallpaper::SaveSettings(){
33   QSettings settings("lumina-desktop","desktopsettings");
34   QString screenID = QApplication::screens().at(cScreen)->name();
35   QString DPrefix = "desktop-"+screenID+"/";
36   QStringList bgs; //get the list of backgrounds to use
37       if(ui->radio_desk_multi->isChecked()){
38         for(int i=0; i<ui->combo_desk_bg->count(); i++){
39 	  bgs << ui->combo_desk_bg->itemData(i).toString();
40         }
41       }else if(ui->combo_desk_bg->count() > 0){
42 	bgs << ui->combo_desk_bg->itemData( ui->combo_desk_bg->currentIndex() ).toString();
43 	bgs.removeAll("default");
44       }
45       if(bgs.isEmpty()){ bgs << "default"; } //Make sure to always fall back on the default
46       settings.setValue(DPrefix+"background/filelist", bgs);
47       settings.setValue(DPrefix+"background/minutesToChange", ui->spin_desk_min->value());
48       settings.setValue(DPrefix+"background/format", ui->combo_desk_layout->currentData().toString());
49 
50   emit HasPendingChanges(false);
51 }
52 
LoadSettings(int screennum)53 void page_wallpaper::LoadSettings(int screennum){
54   emit HasPendingChanges(false);
55   emit ChangePageTitle( tr("Wallpaper Settings") );
56   cScreen = screennum; //save for later
57   loading = true;
58   QSettings settings("lumina-desktop","desktopsettings");
59   QString screenID = QApplication::screens().at(cScreen)->name();
60   QString DPrefix = "desktop-"+screenID+"/";
61 
62   QStringList bgs = settings.value(DPrefix+"background/filelist", QStringList()<<"default").toStringList();
63   ui->combo_desk_bg->clear();
64   for(int i=0; i<bgs.length(); i++){
65     if(bgs[i]=="default"){ ui->combo_desk_bg->addItem( QIcon(DEFAULTBG), tr("System Default"), bgs[i] ); }
66     else if(bgs[i].startsWith("rgb(")){ui->combo_desk_bg->addItem(QString(tr("Solid Color: %1")).arg(bgs[i]), bgs[i]); }
67     //else{ ui->combo_desk_bg->addItem( QIcon(QPixmap(bgs[i]).scaled(64,64)), bgs[i].section("/",-1), bgs[i] ); }
68     else{ ui->combo_desk_bg->addItem( bgs[i].section("/",-1), bgs[i] ); } //disable the thumbnail - takes a long time for large collections of files
69   }
70 
71   ui->radio_desk_multi->setEnabled(bgs.length()>1);
72   if(bgs.length()>1){ ui->radio_desk_multi->setChecked(true);}
73   else{ ui->radio_desk_single->setChecked(true); }
74   ui->spin_desk_min->setValue( settings.value(DPrefix+"background/minutesToChange", 5).toInt() );
75   desktimechanged(); //ensure the display gets updated (in case the radio selection did not change);
76   QRect geom = QGuiApplication::screens().at(cScreen)->availableGeometry();
77   ui->label_desk_res->setText( tr("Screen Resolution:")+"\n"+QString::number(geom.width())+"x"+QString::number(geom.height()) );
78   int tmp = ui->combo_desk_layout->findData(settings.value(DPrefix+"background/format","stretch"));
79   if(tmp>=0){ ui->combo_desk_layout->setCurrentIndex(tmp); }
80   loading = false;
81 }
82 
updateIcons()83 void page_wallpaper::updateIcons(){
84   ui->tool_desk_addbg->setIcon( LXDG::findIcon("list-add","") );
85   ui->tool_desk_rmbg->setIcon( LXDG::findIcon("list-remove","") );
86   updateMenus();
87 }
88 
89 //=================
90 //        PRIVATE
91 //=================
getColorStyle(QString current,bool allowTransparency)92 QString page_wallpaper::getColorStyle(QString current, bool allowTransparency){
93   QString out;
94   //Convert the current color string into a QColor
95   QStringList col = current.section(")",0,0).section("(",1,1).split(",");
96   if(col.length()!=4){ col.clear(); col << "255" << "255" << "255" << "255"; }
97   QColor ccol = QColor(col[0].toInt(), col[1].toInt(), col[2].toInt(), col[3].toInt()); //RGBA
98   QColor ncol;
99     if(allowTransparency){ ncol= QColorDialog::getColor(ccol, this, tr("Select Color"), QColorDialog::ShowAlphaChannel); }
100     else{ ncol= QColorDialog::getColor(ccol, this, tr("Select Color")); }
101   //Now convert the new color into a usable string and return
102   if(ncol.isValid()){ //if the dialog was not cancelled
103     if(allowTransparency){
104       out = "rgba("+QString::number(ncol.red())+","+QString::number(ncol.green())+","+QString::number(ncol.blue())+","+QString::number(ncol.alpha())+")";
105     }else{
106       out = "rgb("+QString::number(ncol.red())+","+QString::number(ncol.green())+","+QString::number(ncol.blue())+")";
107     }
108   }
109   return out;
110 }
111 
112 //=================
113 //    PRIVATE SLOTS
114 //=================
updateMenus()115 void page_wallpaper::updateMenus(){
116   //Background file menu (different ways of loading files)
117   if(ui->tool_desk_addbg->menu()==0){ ui->tool_desk_addbg->setMenu(new QMenu(this)); }
118   ui->tool_desk_addbg->menu()->clear();
119   ui->tool_desk_addbg->menu()->addAction(LXDG::findIcon("document-new",""), tr("File(s)"), this, SLOT(deskbgadded()) );
120   ui->tool_desk_addbg->menu()->addAction(LXDG::findIcon("folder-new",""), tr("Directory (Single)"), this, SLOT(deskbgdiradded()) );
121   ui->tool_desk_addbg->menu()->addAction(LXDG::findIcon("document-open-folder",""), tr("Directory (Recursive)"), this, SLOT(deskbgdirradded()) );
122   ui->tool_desk_addbg->menu()->addAction(LXDG::findIcon("format-fill-color",""), tr("Solid Color"), this, SLOT(deskbgcoloradded()) );
123 
124   //Available Wallpaper layout options
125   ui->combo_desk_layout->clear();
126   ui->combo_desk_layout->addItem(tr("Automatic"), "stretch");
127   ui->combo_desk_layout->addItem(tr("Fullscreen"), "full");
128   ui->combo_desk_layout->addItem(tr("Fit screen"), "fit");
129   ui->combo_desk_layout->addItem(tr("Tile"), "tile");
130   ui->combo_desk_layout->addItem(tr("Center"), "center");
131   ui->combo_desk_layout->addItem(tr("Top Left"), "topleft");
132   ui->combo_desk_layout->addItem(tr("Top Right"), "topright");
133   ui->combo_desk_layout->addItem(tr("Bottom Left"), "bottomleft");
134   ui->combo_desk_layout->addItem(tr("Bottom Right"), "bottomright");
135 
136 }
137 
deskbgchanged()138 void page_wallpaper::deskbgchanged(){
139   //Load the new image preview
140   bool allow_time_set = true;
141   if(ui->combo_desk_bg->count()==0){
142     ui->label_desk_bgview->setPixmap(QPixmap());
143     ui->label_desk_bgview->setText(tr("No Background")+"\n"+tr("(use system default)"));
144     ui->label_desk_bgview->setStyleSheet("");
145     allow_time_set = false;
146   }else{
147     allow_time_set = (ui->combo_desk_bg->count()>1);
148     QString path = ui->combo_desk_bg->itemData( ui->combo_desk_bg->currentIndex() ).toString();
149     if(path=="default"){ path = DEFAULTBG; }
150     if(QFileInfo(path).isDir()){
151       allow_time_set = true; //always allow setting the time if a directory is set
152       QDir dir(path);
153       //Got a directory - go ahead and get all the valid image files
154       QStringList imgs = LUtils::imageExtensions();
155       for(int i=0; i<imgs.length(); i++){ imgs[i].prepend("*."); }
156       QStringList files = dir.entryList(imgs, QDir::Files | QDir::NoDotAndDotDot, QDir::Name);
157       //Now update the item/text
158       ui->combo_desk_bg->setItemIcon(ui->combo_desk_bg->currentIndex(), LXDG::findIcon("folder-image","folder"));
159       ui->label_desk_bgview->setPixmap(QPixmap());
160       ui->label_desk_bgview->setText( QString(tr("Image Directory: %1 valid images")).arg(QString::number(files.length()) ));
161       ui->label_desk_bgview->setStyleSheet("");
162       ui->label_desk_bgview->setToolTip(files.join("\n"));
163     }else if(QFile::exists(path)){
164       QSize sz = ui->label_desk_bgview->size();
165       sz.setWidth( sz.width() - (2*ui->label_desk_bgview->frameWidth()) );
166       sz.setHeight( sz.height() - (2*ui->label_desk_bgview->frameWidth()) );
167       //Update the preview/thumbnail for this item
168       QPixmap pix(path);
169       ui->label_desk_bgview->setPixmap( pix.scaled(sz, Qt::KeepAspectRatio, Qt::SmoothTransformation) );
170       ui->combo_desk_bg->setItemIcon(ui->combo_desk_bg->currentIndex(), pix.scaled(64,64) );
171       ui->label_desk_bgview->setStyleSheet("");
172       ui->label_desk_bgview->setToolTip("");
173     }else if(path.startsWith("rgb(")){
174       ui->label_desk_bgview->setPixmap(QPixmap());
175       ui->label_desk_bgview->setText("");
176       ui->label_desk_bgview->setStyleSheet("background-color: "+path+";");
177       ui->label_desk_bgview->setToolTip("");
178     }else{
179       ui->label_desk_bgview->setPixmap(QPixmap());
180       ui->label_desk_bgview->setText(tr("File does not exist"));
181       ui->label_desk_bgview->setStyleSheet("");
182       ui->label_desk_bgview->setToolTip("");
183     }
184   }
185   //See if this constitues a change to the current settings and enable the save button
186   if(!loading && ui->radio_desk_single->isChecked() && cBG!=ui->combo_desk_bg->currentIndex()){ emit HasPendingChanges(true); }
187   cBG = ui->combo_desk_bg->currentIndex(); //keep track of this for later
188   //Disable the background rotation option if only one background selected
189   if(ui->combo_desk_bg->count()<2){
190     ui->radio_desk_single->setChecked(true);
191     ui->radio_desk_multi->setEnabled(false);
192   }else{
193     ui->radio_desk_multi->setEnabled(true);
194   }
195   ui->spin_desk_min->setEnabled(allow_time_set);
196 
197   //Disable the bg remove button if no backgrounds loaded
198   ui->tool_desk_rmbg->setEnabled(ui->combo_desk_bg->count()>0);
199   ui->label_desk_bgview->setMinimumSize(10,10);
200 }
201 
desktimechanged()202 void page_wallpaper::desktimechanged(){
203   //ui->spin_desk_min->setEnabled(ui->radio_desk_multi->isChecked());
204   if(!loading){ emit HasPendingChanges(true); }
205 }
206 
deskbgremoved()207 void page_wallpaper::deskbgremoved(){
208   if(ui->combo_desk_bg->count()<1){ return; } //nothing to remove
209   ui->combo_desk_bg->removeItem( ui->combo_desk_bg->currentIndex() );
210   emit HasPendingChanges(true);
211 }
212 
deskbgadded()213 void page_wallpaper::deskbgadded(){
214   //Prompt the user to find an image file to use for a background
215   QString dir = LOS::LuminaShare().section("/lumina-desktop",0,0)+"/wallpapers";
216   qDebug() << "Looking for wallpaper dir:" << dir;
217   if( !QFile::exists(dir) ){ dir = QDir::homePath(); }
218   QStringList imgs = LUtils::imageExtensions();
219   for(int i=0; i<imgs.length(); i++){ imgs[i].prepend("*."); }
220   QStringList bgs = QFileDialog::getOpenFileNames(this, tr("Find Background Image(s)"), dir, "Images ("+imgs.join(" ")+");;All Files (*)");
221   if(bgs.isEmpty()){ return; }
222   for(int i=0; i<bgs.length(); i++){
223     ui->combo_desk_bg->addItem( QIcon(bgs[i]), bgs[i].section("/",-1), bgs[i]);
224   }
225   //Now move to the last item in the list (the new image(s));
226   ui->combo_desk_bg->setCurrentIndex( ui->combo_desk_bg->count()-1 );
227   //If multiple items selected, automatically enable the background rotation option
228   if(bgs.length() > 1 && !ui->radio_desk_multi->isChecked()){
229     ui->radio_desk_multi->setChecked(true);
230   }
231   emit HasPendingChanges(true);
232 }
233 
deskbgcoloradded()234 void page_wallpaper::deskbgcoloradded(){
235   //Prompt the user to select a color (no transparency allowed)
236   QString color = getColorStyle("",false); //no initial color
237   if(color.isEmpty()){ return; }
238   //Add it to the list
239   ui->combo_desk_bg->addItem( QString(tr("Solid Color: %1")).arg(color), color);
240   //Now move to the last item in the list (the new image(s));
241   ui->combo_desk_bg->setCurrentIndex( ui->combo_desk_bg->count()-1 );
242 
243   emit HasPendingChanges(true);
244 }
245 
deskbgdiradded()246 void page_wallpaper::deskbgdiradded(){
247   //Add the files from a single directory
248  QString dir = LOS::LuminaShare().section("/lumina-desktop",0,0)+"/wallpapers";
249   qDebug() << "Looking for wallpaper dir:" << dir;
250   if( !QFile::exists(dir) ){ dir = QDir::homePath(); }
251   dir = QFileDialog::getExistingDirectory(this, tr("Find Background Image Directory"), dir, QFileDialog::ReadOnly);
252   if(dir.isEmpty()){ return; }
253   //Got a directory - go ahead and find all the valid image files within it
254   ui->combo_desk_bg->addItem(dir.section("/",-1), dir);
255   //Now move to the last item in the list (the new image(s));
256   ui->combo_desk_bg->setCurrentIndex( ui->combo_desk_bg->count()-1 );
257   //If multiple items selected, automatically enable the background rotation option
258   /*if(bgs.length() > 1 && !ui->radio_desk_multi->isChecked()){
259     ui->radio_desk_multi->setChecked(true);
260   }*/
261   emit HasPendingChanges(true);
262 }
263 
deskbgdirradded()264 void page_wallpaper::deskbgdirradded(){
265   //Recursively add files from a directory
266  QString dir = LOS::LuminaShare().section("/lumina-desktop",0,0)+"/wallpapers";
267   qDebug() << "Looking for wallpaper dir:" << dir;
268   if( !QFile::exists(dir) ){ dir = QDir::homePath(); }
269   dir = QFileDialog::getExistingDirectory(this, tr("Find Background Image Directory"), dir, QFileDialog::ReadOnly);
270   if(dir.isEmpty()){ return; }
271   //Got a directory - go ahead and get all the valid image file formats
272   QStringList imgs = LUtils::imageExtensions();
273   for(int i=0; i<imgs.length(); i++){ imgs[i].prepend("*."); }
274   //Now load the directory and add all the valid files
275   QStringList dirs = LUtils::listSubDirectories(dir, true); //find/list all the dirs
276   dirs.prepend(dir); //make sure the main dir is also listed
277   for(int d=0; d<dirs.length(); d++){
278      ui->combo_desk_bg->addItem(dirs[d].section("/",-1), dirs[d]);
279   }
280   //Now move to the last item in the list (the new image(s));
281   ui->combo_desk_bg->setCurrentIndex( ui->combo_desk_bg->count()-1 );
282   //If multiple items selected, automatically enable the background rotation option
283   if(dirs.length() > 1 && !ui->radio_desk_multi->isChecked()){
284     ui->radio_desk_multi->setChecked(true);
285   }
286   emit HasPendingChanges(true);
287 }
288