// =================== // ==== FOWorker Class ==== // =================== QStringList FOWorker::subfiles(QString dirpath, bool dirsfirst){ //NOTE: dirpath (input) is always the first/last item in the output as well! QStringList out; if(dirsfirst){ out << dirpath; } if( QFileInfo(dirpath).isDir() ){ QDir dir(dirpath); if(dirsfirst){ //Now recursively add any subdirectories and their contents QStringList subdirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden, QDir::NoSort); for(int i=0; i<subdirs.length(); i++){ out << subfiles(dir.absoluteFilePath(subdirs[i]), dirsfirst); } } //List the files QStringList files = dir.entryList(QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System, QDir::NoSort); for(int i=0; i<files.length(); i++){ out << dir.absoluteFilePath(files[i]); } if(!dirsfirst){ //Now recursively add any subdirectories and their contents QStringList subdirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden, QDir::NoSort); for(int i=0; i<subdirs.length(); i++){ out << subfiles(dir.absoluteFilePath(subdirs[i]), dirsfirst); } } } if(!dirsfirst){ out << dirpath; } return out; }
QStringList FOWorker::removeItem(QString path, bool recursive){ //qDebug() << "Remove Path:" << path; QStringList items; if(recursive){ items = subfiles(path,false); } else{ items << path; } //only the given path //qDebug() << " - Subfiles:" << items; QStringList err; for(int i=0; i<items.length(); i++){ if(QFileInfo(items[i]).isDir()){ if(items[i]==path){ //Current Directory Removal QDir dir; if( !dir.rmdir(items[i]) ){ err << items[i]; } }else{ //Recursive Directory Removal err << removeItem(items[i], recursive); } }else{ //Simple File Removal if( !QFile::remove(items[i]) ){ err << items[i]; } } } return err; }
// ==== PRIVATE SLOTS ==== void FOWorker::slotStartOperations(){ if(DEBUG){ qDebug() << "Start File operations" << isRM << isCP << isMV << ofiles << nfiles << overwrite; } //Now setup the UI /*ui->progressBar->setRange(0,ofiles.length()); ui->progressBar->setValue(0); ui->progressBar->setVisible(true); QApplication::processEvents();*/ /*if(!isRM && overwrite==-1){ //Check if the new files already exist, and prompt for action QStringList existing; for(int i=0; i<nfiles.length(); i++){ if(QFile::exists(nfiles[i])){ existing << nfiles[i].section("/",-1); } } if(!existing.isEmpty()){ //Prompt for whether to overwrite, not overwrite, or cancel QMessageBox::StandardButton ans = QMessageBox::question(this, tr("Overwrite Files?"), tr("Do you want to overwrite the existing files?")+"\n"+tr("Note: It will just add a number to the filename otherwise.")+"\n\n"+existing.join(", "), QMessageBox::YesToAll | QMessageBox::NoToAll | QMessageBox::Cancel, QMessageBox::NoToAll); if(ans==QMessageBox::NoToAll){ overwrite = 0; } //don't overwrite else if(ans==QMessageBox::YesToAll){ overwrite = 1; } //overwrite else{ emit finished(QStringList()); return; } //cancel operations } }*/ //Get the complete number of items to be operated on (better tracking) QStringList olist, nlist; //old/new list to actually be used (not inputs - modified/added as necessary) for(int i=0; i<ofiles.length() && !stopped; i++){ if(isRM){ //only old files olist << subfiles(ofiles[i], false); //dirs need to be last for removals }else if(isCP || isRESTORE){ if(QFile::exists(nfiles[i])){ if(overwrite!=1){ qDebug() << " - Get New Filename:" << nfiles[i]; nfiles[i] = newFileName(nfiles[i]); //prompt for new file name up front before anything starts qDebug() << " -- " << nfiles[i]; } } if(nfiles[i] == ofiles[i] && overwrite==1){ //Trying to copy a file/dir to itself - skip it continue; } QStringList subs = subfiles(ofiles[i], true); //dirs need to be first for additions for(int s=0; s<subs.length(); s++){ olist << subs[s]; QString newsub = subs[s].section(ofiles[i],0,100, QString::SectionSkipEmpty); newsub.prepend(nfiles[i]); nlist << newsub; } }else{ //Move/rename if( nfiles[i].startsWith(ofiles[i]+"/") ){ //This is trying to move a directory into itself (not possible) // Example: move "~/mydir" -> "~/mydir/mydir2" QStringList err; err << tr("Invalid Move") << QString(tr("It is not possible to move a directory into itself. Please make a copy of the directory instead.\n\nOld Location: %1\nNew Location: %2")).arg(ofiles[i], nfiles[i]); emit finished(err); return; }else{ //Check for existance of the new name if(QFile::exists(nfiles[i])){ if(overwrite!=1){ nfiles[i] = newFileName(nfiles[i]); //prompt for new file name up front before anything starts } } //no changes necessary olist << ofiles[i]; nlist << nfiles[i]; } } } //Now start iterating over the operations QStringList errlist; for(int i=0; i<olist.length() && !stopped; i++){ if(isRM){ /*ui->label->setText( QString(tr("Removing: %1")).arg(olist[i].section("/",-1)) ); QApplication::processEvents();*/ emit startingItem(i+1,olist.length(), olist[i], ""); errlist << removeItem(olist[i]); }else if(isCP || isRESTORE){ /*ui->label->setText( QString(tr("Copying: %1 to %2")).arg(olist[i].section("/",-1), nlist[i].section("/",-1)) ); QApplication::processEvents();*/ emit startingItem(i+1,olist.length(), olist[i],nlist[i]); if(QFile::exists(nlist[i])){ if(overwrite==1){ errlist << removeItem(nlist[i], true); //recursively remove the file/dir since we are supposed to overwrite it } } //If a parent directory fails to copy, skip all the children as well (they will also fail) //QApplication::processEvents(); if( !errlist.contains(olist[i].section("/",0,-1)) ){ errlist << copyItem(olist[i], nlist[i]); } }else if(isMV){ /*ui->label->setText( QString(tr("Moving: %1 to %2")).arg(ofiles[i].section("/",-1), nfiles[i].section("/",-1)) ); QApplication::processEvents();*/ emit startingItem(i+1,olist.length(), olist[i], nlist[i]); //Clean up any overwritten files/dirs if(QFile::exists(nlist[i])){ if(overwrite==1){ errlist << removeItem(nlist[i], true); //recursively remove the file/dir since we are supposed to overwrite it } } //Perform the move if no error yet (including skipping all children) if( !errlist.contains(olist[i].section("/",0,-1)) ){ if( !QFile::rename(ofiles[i], nfiles[i]) ){ errlist << ofiles[i]; } } } //ui->progressBar->setValue(i+1); //QApplication::processEvents(); } //All finished, emit the signal errlist.removeAll(""); //make sure to clear any empty items emit finished(errlist); qDebug() << "Done with File Operations"; }
/* Main code */ int main(int argc, char* argv[]) { gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), "Suse Control Center"); gtk_window_set_default_size (GTK_WINDOW (window), 650, 400); g_signal_connect(G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL); bool is_root = getuid () == 0; View view; { // adding groups GKeyFile *file = g_key_file_new(); std::set <std::string> groups = subfiles (YAST_GROUPS); for (std::set <std::string>::iterator it = groups.begin(); it != groups.end(); it++) { if (!g_key_file_load_from_file (file, (YAST_GROUPS + (*it)).c_str(), G_KEY_FILE_NONE, NULL)) continue; gchar* name = g_key_file_get_locale_string (file, "Desktop Entry", "Name", 0, NULL); gchar *nick = g_key_file_get_string (file, "Desktop Entry", "X-SuSE-YaST-Group", NULL); gchar *icon = g_key_file_get_string (file, "Desktop Entry", "Icon", NULL); gchar *sort_key = g_key_file_get_string (file, "Desktop Entry", "X-SuSE-YaST-SortKey", NULL); if (name && nick) view.addGroup (name, icon, nick, sort_key); if (name) g_free (name); if (nick) g_free (nick); if (icon) g_free (icon); if (sort_key) g_free (sort_key); } g_key_file_free (file); } { // adding entries GKeyFile *file = g_key_file_new(); std::set <std::string> entries = subfiles (YAST_ENTRIES); for (std::set <std::string>::iterator it = entries.begin(); it != entries.end(); it++) { if (!g_key_file_load_from_file (file, (YAST_ENTRIES + (*it)).c_str(), G_KEY_FILE_NONE, NULL)) continue; gchar *group = g_key_file_get_string (file, "Desktop Entry", "X-SuSE-YaST-Group", NULL); gchar* name = g_key_file_get_locale_string (file, "Desktop Entry", "Name", 0, NULL); gchar *icon = g_key_file_get_string (file, "Desktop Entry", "Icon", NULL); gchar *command = g_key_file_get_string (file, "Desktop Entry", "Exec", NULL); gboolean needs_root = g_key_file_get_boolean (file, "Desktop Entry", "X-SuSE-YaST-RootOnly", NULL); if (group && name && command && (!needs_root || is_root)) view.addEntry (group, name, icon, command); if (group) g_free (group); if (name) g_free (name); if (icon) g_free (icon); if (command) g_free (command); } g_key_file_free (file); } gtk_container_add (GTK_CONTAINER (window), view.getWidget()); gtk_widget_show_all (window); if (!is_root) { GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (window), GtkDialogFlags (0), GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "You are executing the control center as an ordinary user.\n" "Only a few modules will be available."); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); } gtk_main(); return 0; }