예제 #1
0
/**
 * fm_folder_config_open
 * @path: path to get config
 *
 * Searches for settings in the cache that are specific to @path. Locks
 * the cache. Returned descriptor can be used for access to settings.
 *
 * Returns: (transfer full): new configuration descriptor.
 *
 * Since: 1.2.0
 */
FmFolderConfig *fm_folder_config_open(FmPath *path)
{
    FmFolderConfig *fc = g_slice_new(FmFolderConfig);
    FmPath *sub_path;

    fc->changed = FALSE;
    /* clear .directory file first */
    sub_path = fm_path_new_child(path, ".directory");
    fc->filepath = fm_path_to_str(sub_path);
    fm_path_unref(sub_path);
    if (g_file_test(fc->filepath, G_FILE_TEST_EXISTS))
    {
        fc->kf = g_key_file_new();
        if (g_key_file_load_from_file(fc->kf, fc->filepath,
                                      G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
                                      NULL) &&
            g_key_file_has_group(fc->kf, "File Manager"))
        {
            fc->group = "File Manager";
            return fc;
        }
        g_key_file_free(fc->kf);
    }
    g_free(fc->filepath);
    fc->filepath = NULL;
    fc->group = fm_path_to_str(path);
    G_LOCK(cache);
    fc->kf = fc_cache;
    return fc;
}
gint sort(FmFileInfo *fi1, FmFileInfo *fi2){
	char *filename1, *filename2;
	int year1 = 0, year2 = 0;
	TagLib_File *TL_file1, *TL_file2;
	
	filename1 = fm_path_to_str( fm_file_info_get_path(fi1) );
	filename2 = fm_path_to_str( fm_file_info_get_path(fi2) );
	TL_file1 = taglib_file_new( filename1 );
	TL_file2 = taglib_file_new( filename2 );
	free( filename1 );
	free( filename2 );
	
	if (TL_file1 != NULL) {
		if(taglib_file_is_valid(TL_file1)){
			TagLib_Tag *TL_tag = taglib_file_tag( TL_file1 );
			year1 = taglib_tag_year( TL_tag );
			
			taglib_tag_free_strings();
			taglib_file_free( TL_file1 );
		}
	}
	
	if (TL_file2 != NULL) {
		if(taglib_file_is_valid(TL_file2)){
			TagLib_Tag *TL_tag = taglib_file_tag( TL_file2 );
			year2 = taglib_tag_year( TL_tag );
			
			taglib_tag_free_strings();
			taglib_file_free( TL_file2 );
		}
	}
	
	return year1 - year2;
}
void get_value(FmFileInfo *fi, GValue *value){
	
	char* filename;
	int year;
	char year_string[10];
	TagLib_File *TL_file;
	TagLib_Tag *TL_tag;
	
	filename = fm_path_to_str( fm_file_info_get_path(fi) );
	TL_file = taglib_file_new( filename );
	free( filename );
	
	if (TL_file != NULL) {
		if(taglib_file_is_valid(TL_file)){
			TL_tag = taglib_file_tag( TL_file );
			year = taglib_tag_year( TL_tag );
			if( year !=0 ){
				sprintf( year_string, "%d", year );
				g_value_set_string( value, year_string );
			}
			
			taglib_tag_free_strings();
			taglib_file_free( TL_file );
		}
	}
};
예제 #4
0
static gboolean  fm_path_entry_match_selected(GtkEntryCompletion *widget,
                                              GtkTreeModel       *model,
                                              GtkTreeIter        *iter,
                                              gpointer user_data)
{
    GtkWidget *entry = gtk_entry_completion_get_entry(widget);
    gchar new_text[PATH_MAX];
    FmPathEntryPrivate *priv = FM_PATH_ENTRY_GET_PRIVATE( FM_PATH_ENTRY(entry) );
    gchar *model_file_name;
    gchar *new_path;
    gtk_tree_model_get(GTK_TREE_MODEL(model), iter,
                       COL_FILE_NAME, &model_file_name,
                       -1);
    /* FIXME: should we use UTF-8 encoded display name here? */
    new_path = fm_path_to_str(priv->completion_model->dir->dir_path);
    g_sprintf(new_text, "%s/%s",
              /* prevent leading double slash */
              g_str_equal(new_path, "/") ? "" : new_path,
              model_file_name);
    g_free(new_path);
    priv->completion_len = 0;
    gtk_entry_set_text(GTK_ENTRY(entry), new_text);
    /* move the cursor to the end of entry */
    gtk_editable_set_position(GTK_EDITABLE(entry), -1);
    return TRUE;
}
예제 #5
0
GFile* fm_path_to_gfile(FmPath* path)
{
	GFile* gf;
	char* str;
	str = fm_path_to_str(path);
	if(fm_path_is_native(path))
		gf = g_file_new_for_path(str);
	else
		gf = g_file_new_for_uri(str);
	g_free(str);
	return gf;
}
예제 #6
0
static void on_home_path_current_clicked(GtkButton *button, GtkEntry *home_path)
{
    FmMainWin *win = fm_main_win_get_last_active();
    FmPath *cwd;
    char *path;

    if (win == NULL || win->folder_view == NULL)
        return; /* FIXME: print warning? */
    cwd = fm_folder_view_get_cwd(win->folder_view);
    path = fm_path_to_str(cwd);
    gtk_entry_set_text(home_path, path);
    g_free(path);
}
예제 #7
0
static void _check_native_display_names(FmPath *path)
{
    char *path_str, *disp_name;

    if (path == NULL || _fm_path_get_display_name(path) != NULL)
        return; /* all done */
    path_str = fm_path_to_str(path);
    disp_name = g_filename_display_basename(path_str);
    g_free(path_str);
    _fm_path_set_display_name(path, disp_name);
    g_free(disp_name);
    _check_native_display_names(fm_path_get_parent(path)); /* recursion */
}
gint sort(FmFileInfo *fi1, FmFileInfo *fi2){
	int result;
	char *filename1, *filename2;
	char *genre1=NULL, *genre2=NULL;
	TagLib_File *TL_file1, *TL_file2;
	
	filename1 = fm_path_to_str( fm_file_info_get_path(fi1) );
	filename2 = fm_path_to_str( fm_file_info_get_path(fi2) );
	TL_file1 = taglib_file_new( filename1 );
	TL_file2 = taglib_file_new( filename2 );
	free( filename1 );
	free( filename2 );
	
	if (TL_file1 != NULL) {
		if(taglib_file_is_valid(TL_file1)){
			TagLib_Tag *TL_tag = taglib_file_tag( TL_file1 );
			genre1 = taglib_tag_genre( TL_tag );
			taglib_file_free( TL_file1 );
		}
	}
	
	if (TL_file2 != NULL) {
		if(taglib_file_is_valid(TL_file2)){
			TagLib_Tag *TL_tag = taglib_file_tag( TL_file2 );
			genre2 = taglib_tag_genre( TL_tag );
			taglib_file_free( TL_file2 );
		}
	}
	
	result = strcasecmp(genre1, genre2);
	
	if (TL_file1 != NULL || TL_file2 != NULL) {
		taglib_tag_free_strings();
	}
	
	return result;
}
예제 #9
0
static void on_browse_btn_clicked(GtkButton* btn, AppChooserData* data)
{
	FmPath* file;
	GtkFileFilter* filter = gtk_file_filter_new();
	gtk_file_filter_add_custom(filter,
		GTK_FILE_FILTER_FILENAME|GTK_FILE_FILTER_MIME_TYPE, exec_filter_func, NULL, NULL);
	/* gtk_file_filter_set_name(filter, _("Executable files")); */
	file = fm_select_file(GTK_WINDOW(data->dlg), NULL, "/usr/bin", TRUE, FALSE, filter, NULL);

	if(file)
	{
		char* binary = fm_path_to_str(file);
		gtk_entry_set_text(data->cmdline, binary);
		g_free(binary);
		fm_path_unref(file);
	}
}
예제 #10
0
char *fm_path_to_uri (FmPath *path)
{
    char *uri = NULL;
    char *str = fm_path_to_str (path);
    
    if (G_LIKELY (str))
    {
        if (str[0] == '/') // absolute path
            uri = g_filename_to_uri (str, NULL, NULL);
        else
        {
            uri = g_uri_escape_string (str, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, FALSE);
        }
        g_free (str);
    }
    return uri;
}
예제 #11
0
static void on_browse_btn_clicked(GtkButton* btn, AppChooserData* data)
{
    FmPath* file;
    GtkFileFilter* filter = gtk_file_filter_new();
    char* binary;
    gtk_file_filter_add_custom(filter,
        GTK_FILE_FILTER_FILENAME|GTK_FILE_FILTER_MIME_TYPE, exec_filter_func, NULL, NULL);
    /* gtk_file_filter_set_name(filter, _("Executable files")); */
    file = fm_select_file(GTK_WINDOW(data->dlg), NULL, "/usr/bin", TRUE, FALSE, filter, NULL);

    if (file == NULL)
        return;
    binary = fm_path_to_str(file);
    if (g_str_has_suffix(fm_path_get_basename(file), ".desktop"))
    {
        GKeyFile *kf = g_key_file_new();
        GDesktopAppInfo *info;
        if (g_key_file_load_from_file(kf, binary, 0, NULL) &&
            (info = g_desktop_app_info_new_from_keyfile(kf)) != NULL)
            /* it is a valid desktop entry */
        {
            /* FIXME: it will duplicate the file, how to avoid that? */
            gtk_entry_set_text(data->cmdline,
                               g_app_info_get_commandline(G_APP_INFO(info)));
            gtk_entry_set_text(data->app_name,
                               g_app_info_get_name(G_APP_INFO(info)));
            gtk_toggle_button_set_active(data->use_terminal,
                                         g_key_file_get_boolean(kf, G_KEY_FILE_DESKTOP_GROUP,
                                                                G_KEY_FILE_DESKTOP_KEY_TERMINAL,
                                                                NULL));
            gtk_toggle_button_set_active(data->keep_open,
                                         g_key_file_get_boolean(kf, G_KEY_FILE_DESKTOP_GROUP,
                                                                "X-KeepTerminal",
                                                                NULL));
            g_object_unref(info);
            g_key_file_free(kf);
            fm_path_unref(file);
            return;
        }
        g_key_file_free(kf);
    }
    gtk_entry_set_text(data->cmdline, binary);
    g_free(binary);
    fm_path_unref(file);
}
예제 #12
0
void DesktopWindow::loadItemPositions() {
  // load custom item positions
  customItemPos_.clear();
  Settings& settings = static_cast<Application*>(qApp)->settings();
  QString configFile = QString("%1/desktop-items-%2.conf").arg(settings.profileDir(settings.profileName())).arg(screenNum_);
  QSettings file(configFile, QSettings::IniFormat);
  QSize grid = listView_->gridSize();
  QRect workArea = qApp->desktop()->availableGeometry(screenNum_);
  workArea.adjust(12, 12, -12, -12);
  char* dektopPath = fm_path_to_str(fm_path_get_desktop());
  QString desktopDir = QString(dektopPath) + QString("/");
  g_free(dektopPath);
  Q_FOREACH(const QString& name, file.childGroups()) {
    if(!QFile::exists(desktopDir + name.toUtf8())) {
      // the file may have been removed from outside LXQT
      continue;
    }
    file.beginGroup(name);
    QVariant var = file.value("pos");
    if(var.isValid()) {
      QPoint customPos = var.toPoint();
      if (customPos.x() >= workArea.x() && customPos.y() >= workArea.y()
          && customPos.x() + listView_->gridSize().width() <= workArea.right() + 1
          && customPos.y() + listView_->gridSize().height() <= workArea.bottom() + 1)
      {
        // correct positions that are't aligned to the grid
        qreal w = qAbs((qreal)customPos.x() - (qreal)workArea.x())
                  / (qreal)(grid.width() + listView_->spacing());
        qreal h = qAbs(customPos.y() - (qreal)workArea.y())
                  / (qreal)(grid.height() + listView_->spacing());
        customPos.setX(workArea.x() + qRound(w) * (grid.width() + listView_->spacing()));
        customPos.setY(workArea.y() + qRound(h) * (grid.height() + listView_->spacing()));
        while(customItemPos_.values().contains(customPos)) {
          customPos.setY(customPos.y() + grid.height() + listView_->spacing());
          if(customPos.y() + grid.height() > workArea.bottom() + 1) {
            customPos.setX(customPos.x() + grid.width() + listView_->spacing());
            customPos.setY(workArea.top());
          }
        }
        customItemPos_[name.toUtf8()] = customPos;
      }
    }
    file.endGroup();
  }
}
예제 #13
0
void ProxyFilter::setVirtHidden(FmFolder* folder) {
  virtHiddenList_ = QStringList(); // reset the list
  if(!folder) return;
  if(FmPath* path = fm_folder_get_path(folder)) {
    char* pathStr = fm_path_to_str(path);
    if(pathStr) {
      QString dotHidden = QString(pathStr) + QString("/.hidden");
      g_free(pathStr);
      QFile file(dotHidden);
      if(file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QTextStream in(&file);
        while(!in.atEnd())
          virtHiddenList_.append(in.readLine());
        file.close();
      }
    }
  }
}
void get_value(FmFileInfo *fi, GValue *value){
	
	char* filename;
	char* genre;
	TagLib_File *TL_file;
	TagLib_Tag *TL_tag;
	
	filename = fm_path_to_str( fm_file_info_get_path(fi) );
	TL_file = taglib_file_new( filename );
	free( filename );
	
	if( TL_file != NULL ) {
		if(taglib_file_is_valid(TL_file)){
			TL_tag = taglib_file_tag( TL_file );
			genre = taglib_tag_genre( TL_tag );
			g_value_set_string( value, genre );
			
			taglib_tag_free_strings();
			taglib_file_free( TL_file );
		}
	}
};
예제 #15
0
void DesktopWindow::onRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) {
  Q_UNUSED(parent);
  Q_UNUSED(start);
  Q_UNUSED(end);
  if(!customItemPos_.isEmpty()) {
    // also delete stored custom item positions for the items currently being removed.
    // Here we can't rely on ProxyFolderModel::fileInfoFromIndex() because, although rows
    // aren't removed yet, files are already removed.
    QHash<QByteArray, QPoint> _customItemPos = customItemPos_;
    char* dektopPath = fm_path_to_str(fm_path_get_desktop());
    QString desktopDir = QString(dektopPath) + QString("/");
    g_free(dektopPath);
    QHash<QByteArray, QPoint>::iterator it;
    for(it = _customItemPos.begin(); it != _customItemPos.end(); ++it) {
      const QByteArray& name = it.key();
      if(!QFile::exists(desktopDir + QString::fromUtf8(name, name.length())))
        customItemPos_.remove(it.key());
    }
    if(customItemPos_ != _customItemPos)
      saveItemPositions();
  }
  queueRelayout();
}
예제 #16
0
GFile *fm_path_to_gfile (FmPath *path)
{
    GFile *gf;
    
    char *str = fm_path_to_str (path);
    
    if (fm_path_is_native (path))
    {
        gf = g_file_new_for_path (str);
    }
    else
    {
        // Escape the path so that it supports spaces and special characters like accentuated ones...
        char *tmp_str = g_uri_escape_string (str, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, TRUE);
        
        gf = g_file_new_for_uri (tmp_str);
        g_free (tmp_str);
    }
    
    g_free (str);
    
    return gf;
}
예제 #17
0
static gboolean fm_deep_count_job_run(FmJob* job)
{
    FmDeepCountJob* dc = (FmDeepCountJob*)job;
    GList* l;

    l = fm_path_list_peek_head_link(dc->paths);
    for(; !fm_job_is_cancelled(job) && l; l=l->next)
    {
        FmPath* path = FM_PATH(l->data);
        if(fm_path_is_native(path)) /* if it's a native file, use posix APIs */
        {
            char *path_str = fm_path_to_str(path);
            deep_count_posix( dc, path_str );
            g_free(path_str);
        }
        else
        {
            GFile* gf = fm_path_to_gfile(path);
            deep_count_gio( dc, NULL, gf );
            g_object_unref(gf);
        }
    }
    return TRUE;
}
예제 #18
0
static void get_data(GtkClipboard *clip, GtkSelectionData *sel, guint info, gpointer user_data)
{
	FmPathList* files = (FmPathList*)user_data;
	GString* uri_list;

    if(info == KDE_CUT_SEL)
    {
        /* set application/kde-cutselection data */
        if(is_cut)
            gtk_selection_data_set(sel, sel->target, 8, "1", 2);
        return;
    }

    uri_list = g_string_sized_new(4096);
	if(info == GNOME_COPIED_FILES)
		g_string_append(uri_list, is_cut ? "cut\n" : "copy\n");
	if(info == UTF8_STRING)
	{
		GList* l = fm_list_peek_head_link(files);
		while(l)
		{
			FmPath* path = (FmPath*)l->data;
			char* str = fm_path_to_str(path);
			g_string_append(uri_list, str);
			g_string_append_c(uri_list, '\n');
			g_free(str);
			l=l->next;
		}
	}
	else/* text/uri-list format */
	{
		fm_path_list_write_uri_list(files, uri_list);
	}
	gtk_selection_data_set(sel, sel->target, 8, uri_list->str, uri_list->len + 1);
	g_string_free(uri_list, TRUE);
}
예제 #19
0
// FIXME_pcm: maybe we can support different encoding for different mount points?
char *fm_path_display_name (FmPath *path, gboolean human_readable)
{
    char *disp;
    if (human_readable)
    {
        if (G_LIKELY (path->parent))
        {
            char *disp_parent = fm_path_display_name (path->parent, TRUE);
            char *disp_base = fm_path_display_basename (path);
            disp = g_build_filename (disp_parent, disp_base, NULL);
            g_free (disp_parent);
            g_free (disp_base);
        }
        else
            disp = fm_path_display_basename (path);
    }
    else
    {
        char *str = fm_path_to_str (path);
        disp = g_filename_display_name (str);
        g_free (str);
    }
    return disp;
}
예제 #20
0
static gboolean fm_dir_list_job_run_posix(FmDirListJob* job)
{
    FmJob* fmjob = FM_JOB(job);
    FmFileInfo* fi;
    GError *err = NULL;
    char* path_str;
    GDir* dir;

    path_str = fm_path_to_str(job->dir_path);

    fi = _new_info_for_native_file(job, job->dir_path, path_str, NULL);
    if(fi)
    {
        if(! fm_file_info_is_dir(fi))
        {
            err = g_error_new(G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY,
                              _("The specified directory '%s' is not valid"),
                              path_str);
            fm_file_info_unref(fi);
            fm_job_emit_error(fmjob, err, FM_JOB_ERROR_CRITICAL);
            g_error_free(err);
            g_free(path_str);
            return FALSE;
        }
        job->dir_fi = fi;
    }
    else
    {
        err = g_error_new(G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY,
                          _("The specified directory '%s' is not valid"),
                          path_str);
        fm_job_emit_error(fmjob, err, FM_JOB_ERROR_CRITICAL);
        g_error_free(err);
        g_free(path_str);
        return FALSE;
    }

    dir = g_dir_open(path_str, 0, &err);
    if( dir )
    {
        const char* name;
        GString* fpath = g_string_sized_new(4096);
        int dir_len = strlen(path_str);
        g_string_append_len(fpath, path_str, dir_len);
        if(fpath->str[dir_len-1] != '/')
        {
            g_string_append_c(fpath, '/');
            ++dir_len;
        }
        while( ! fm_job_is_cancelled(fmjob) && (name = g_dir_read_name(dir)) )
        {
            FmPath* new_path;
            g_string_truncate(fpath, dir_len);
            g_string_append(fpath, name);

            if(job->flags & FM_DIR_LIST_JOB_DIR_ONLY) /* if we only want directories */
            {
                struct stat st;
                /* FIXME: this results in an additional stat() call, which is inefficient */
                if(stat(fpath->str, &st) == -1 || !S_ISDIR(st.st_mode))
                    continue;
            }

            new_path = fm_path_new_child(job->dir_path, name);

        _retry:
            fi = _new_info_for_native_file(job, new_path, fpath->str, &err);
            if (fi == NULL) /* we got a damaged file */
            {
                FmJobErrorAction act = fm_job_emit_error(fmjob, err, FM_JOB_ERROR_MILD);
                GFile *gf;
                GFileInfo *inf;
                gchar *disp_basename;

                g_error_free(err);
                err = NULL;
                if(act == FM_JOB_RETRY)
                    goto _retry;
                /* bug #3615271: Damaged mountpoint isn't shown
                   let make a simple file info then */
                inf = g_file_info_new();
                gf = fm_path_to_gfile(new_path);
                g_file_info_set_file_type(inf, G_FILE_TYPE_UNKNOWN);
                g_file_info_set_name(inf, name);
                disp_basename = g_filename_display_basename(fpath->str);
                g_file_info_set_display_name(inf, disp_basename);
                g_free(disp_basename);
                g_file_info_set_content_type(inf, "inode/x-corrupted");
                fi = fm_file_info_new_from_g_file_data(gf, inf, new_path);
                g_object_unref(inf);
                g_object_unref(gf);
            }
            fm_dir_list_job_add_found_file(job, fi);
            fm_file_info_unref(fi);
            fm_path_unref(new_path);
        }
        g_string_free(fpath, TRUE);
        g_dir_close(dir);
    }
    else
    {
        fm_job_emit_error(fmjob, err, FM_JOB_ERROR_CRITICAL);
        g_error_free(err);
    }
    g_free(path_str);
    return TRUE;
}
예제 #21
0
/**
 * fm_launch_files
 * @ctx: (allow-none): a launch context
 * @file_infos: (element-type FmFileInfo): files to launch
 * @launcher: #FmFileLauncher with callbacks
 * @user_data: data supplied for callbacks
 *
 * Launches files using callbacks in @launcher.
 *
 * Returns: %TRUE in case of success.
 *
 * Since: 0.1.0
 */
gboolean fm_launch_files(GAppLaunchContext* ctx, GList* file_infos, FmFileLauncher* launcher, gpointer user_data)
{
    GList* l;
    GHashTable* hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
    GList *folders = NULL;
    FmFileInfo* fi;
    GList *targets = NULL;
    GError* err = NULL;
    GAppInfo* app;
    const char* type;

    for(l = file_infos; l; l=l->next)
    {
        GList* fis;
        char *filename, *scheme;
        const char *target = NULL;

        fi = (FmFileInfo*)l->data;
        /* special handling for shortcuts */
        if (!fm_file_info_is_symlink(fi))
            /* symlinks also has fi->target, but we only handle shortcuts here. */
            target = fm_file_info_get_target(fi);
        if (launcher->open_folder && fm_file_info_is_dir(fi))
        {
            /* special handling for shortcuts */
            if(target)
            {
                fi = _fetch_file_info_for_shortcut(fm_file_info_get_target(fi),
                                                   ctx, launcher, user_data);
                if (fi == NULL)
                    /* error was shown by job already */
                    continue;
                targets = g_list_prepend(targets, fi);
            }
            folders = g_list_prepend(folders, fi);
        }
        else if (fm_file_info_is_desktop_entry(fi))
        {
_launch_desktop_entry:
            if (!target)
                filename = fm_path_to_str(fm_file_info_get_path(fi));
            fm_launch_desktop_entry(ctx, target ? target : filename, NULL,
                                    launcher, user_data);
            if (!target)
                g_free(filename);
            continue;
        }
        else
        {
            FmPath* path = fm_file_info_get_path(fi);
            FmMimeType* mime_type = NULL;
            if(fm_path_is_native(path))
            {
                /* special handling for shortcuts */
                if (target)
                {
                    if (fm_file_info_get_mime_type(fi) == _fm_mime_type_get_inode_x_shortcut())
                    /* if we already know MIME type then use it instead */
                    {
                      scheme = g_uri_parse_scheme(target);
                      if (scheme)
                      {
                        /* FIXME: this is rough! */
                        if (strcmp(scheme, "file") != 0 &&
                            strcmp(scheme, "trash") != 0 &&
                            strcmp(scheme, "network") != 0 &&
                            strcmp(scheme, "computer") != 0 &&
                            strcmp(scheme, "menu") != 0)
                        {
                            /* we don't support this URI internally, try GIO */
                            app = g_app_info_get_default_for_uri_scheme(scheme);
                            if (app)
                            {
                                fis = g_list_prepend(NULL, (char *)target);
                                fm_app_info_launch_uris(app, fis, ctx, &err);
                                g_list_free(fis);
                                g_object_unref(app);
                            }
                            else if (launcher->error)
                                g_set_error(&err, G_IO_ERROR, G_IO_ERROR_FAILED,
                                            _("No default application is set to launch URIs %s://"),
                                            scheme);
                            if (err)
                            {
                                launcher->error(ctx, err, NULL, user_data);
                                g_clear_error(&err);
                            }
                            g_free(scheme);
                            continue;
                        }
                        g_free(scheme);
                      }
                    }
                    else
                        mime_type = fm_file_info_get_mime_type(fi);
                    /* retrieve file info for target otherwise and handle it */
                    fi = _fetch_file_info_for_shortcut(target, ctx, launcher, user_data);
                    if (fi == NULL)
                        /* error was shown by job already */
                        continue;
                    targets = g_list_prepend(targets, fi);
                    path = fm_file_info_get_path(fi);
                    /* special handling for desktop entries */
                    if (fm_file_info_is_desktop_entry(fi))
                        goto _launch_desktop_entry;
                }
                if(fm_file_info_is_executable_type(fi))
                {
                    /* if it's an executable file, directly execute it. */
                    filename = fm_path_to_str(path);

                    /* FIXME: we need to use eaccess/euidaccess here. */
                    if(g_file_test(filename, G_FILE_TEST_IS_EXECUTABLE))
                    {
                        if(launcher->exec_file)
                        {
                            FmFileLauncherExecAction act = launcher->exec_file(fi, user_data);
                            GAppInfoCreateFlags flags = 0;
                            switch(act)
                            {
                            case FM_FILE_LAUNCHER_EXEC_IN_TERMINAL:
                                flags |= G_APP_INFO_CREATE_NEEDS_TERMINAL;
                                /* NOTE: no break here */
                            case FM_FILE_LAUNCHER_EXEC:
                            {
                                /* filename may contain spaces. Fix #3143296 */
                                char* quoted = g_shell_quote(filename);
                                app = fm_app_info_create_from_commandline(quoted, NULL, flags, NULL);
                                g_free(quoted);
                                if(app)
                                {
                                    char* run_path = g_path_get_dirname(filename);
                                    char* cwd = NULL;
                                    /* bug #3589641: scripts are ran from $HOME.
                                       since GIO launcher is kinda ugly - it has
                                       no means to set running directory so we
                                       do workaround - change directory to it */
                                    if(run_path && strcmp(run_path, "."))
                                    {
                                        cwd = g_get_current_dir();
                                        if(chdir(run_path) != 0)
                                        {
                                            g_free(cwd);
                                            cwd = NULL;
                                            if (launcher->error)
                                            {
                                                g_set_error(&err, G_IO_ERROR,
                                                            g_io_error_from_errno(errno),
                                                            _("Cannot set working directory to '%s': %s"),
                                                            run_path, g_strerror(errno));
                                                launcher->error(ctx, err, NULL, user_data);
                                                g_clear_error(&err);
                                            }
                                        }
                                    }
                                    g_free(run_path);
                                    if(!fm_app_info_launch(app, NULL, ctx, &err))
                                    {
                                        if(launcher->error)
                                            launcher->error(ctx, err, NULL, user_data);
                                        g_error_free(err);
                                        err = NULL;
                                    }
                                    if(cwd) /* return back */
                                    {
                                        if(chdir(cwd) != 0)
                                            g_warning("fm_launch_files(): chdir() failed");
                                        g_free(cwd);
                                    }
                                    g_object_unref(app);
                                    continue;
                                }
                                break;
                            }
                            case FM_FILE_LAUNCHER_EXEC_OPEN:
                                break;
                            case FM_FILE_LAUNCHER_EXEC_CANCEL:
                                continue;
                            }
                        }
                    }
                    g_free(filename);
                }
            }
            if (mime_type == NULL)
                mime_type = fm_file_info_get_mime_type(fi);
            if(mime_type && (type = fm_mime_type_get_type(mime_type)))
            {
                fis = g_hash_table_lookup(hash, type);
                fis = g_list_prepend(fis, fi);
                g_hash_table_insert(hash, (gpointer)type, fis);
            }
            else if (launcher->error)
            {
                g_set_error(&err, G_IO_ERROR, G_IO_ERROR_FAILED,
                            _("Could not determine content type of file '%s' to launch it"),
                            fm_file_info_get_disp_name(fi));
                launcher->error(ctx, err, NULL, user_data);
                g_clear_error(&err);
            }
        }
    }

    if(g_hash_table_size(hash) > 0)
    {
        GHashTableIter it;
        GList* fis;
        g_hash_table_iter_init(&it, hash);
        while(g_hash_table_iter_next(&it, (void**)&type, (void**)&fis))
        {
            GAppInfo* app = g_app_info_get_default_for_type(type, FALSE);
            if(!app)
            {
                if(launcher->get_app)
                {
                    FmMimeType* mime_type = fm_file_info_get_mime_type((FmFileInfo*)fis->data);
                    app = launcher->get_app(fis, mime_type, user_data, NULL);
                }
            }
            if(app)
            {
                for(l=fis; l; l=l->next)
                {
                    char* uri;
                    fi = (FmFileInfo*)l->data;
                    /* special handling for shortcuts */
                    if (fm_file_info_is_shortcut(fi))
                        uri = g_strdup(fm_file_info_get_target(fi));
                    else
                        uri = fm_path_to_uri(fm_file_info_get_path(fi));
                    l->data = uri;
                }
                fis = g_list_reverse(fis);
                fm_app_info_launch_uris(app, fis, ctx, &err);
                /* free URI strings */
                g_list_foreach(fis, (GFunc)g_free, NULL);
                g_object_unref(app);
            }
            else if (launcher->error)
                g_set_error(&err, G_IO_ERROR, G_IO_ERROR_FAILED,
                            _("No default application is set for MIME type %s"),
                            type);
            if (err)
            {
                launcher->error(ctx, err, NULL, user_data);
                g_clear_error(&err);
            }
            g_list_free(fis);
        }
    }
    g_hash_table_destroy(hash);

    if(folders)
    {
        folders = g_list_reverse(folders);
        if(launcher->open_folder)
        {
            launcher->open_folder(ctx, folders, user_data, &err);
            if(err)
            {
                if(launcher->error)
                    launcher->error(ctx, err, NULL, user_data);
                g_error_free(err);
                err = NULL;
            }
        }
        g_list_free(folders);
    }
    g_list_free_full(targets, (GDestroyNotify)fm_file_info_unref);
    return TRUE;
}
예제 #22
0
/* translate gvfs trash:///path to real path of the trashed file on disk.
 * this only works when path is a trashed file and gvfs is active.
 */
char* fm_path_get_trash_real_path(FmPath* path)
{
    char* path_str, *p;
    GString* result;
    /* The filenames listed in trash:/// by gvfs are carefully encoded 
     * to carry important information.
     * Handling of trashed file name can be found in gvfs source code:
     * gvfs/daemon/trashlib/trashitem.c: trash_item_escape_name().
     * The filename listed under trash:/// are encoded according to the 
     * real path on disk. */
    
    if(!fm_path_is_trash(path)) /* this only works for files in trash:/// */
        return NULL;

	/* converting it to string first for ease of handling */
    path_str = fm_path_to_str(path);
    p = path_str + 9; /* skip "trash:///" */
    result = g_string_sized_new(1024);
    if(*p == '\\') /* files not in home trash */
    {
		/* the basename is an encoded full path */
		for(; *p; ++p)
		{
			if(*p == '\\') /* translate all \ to / */
				g_string_append_c(result, '/');
			else if(*p == '`') /* special handling for ` */
			{
				++p;
				if(*p == '\\') /* translate `\ to \ */
					g_string_append_c(result, '\\');
				else if(*p == '`') /* translate `` to ` */
					g_string_append_c(result, '`');
				else
				{
					g_string_append_c(result, '`');
					g_string_append_c(result, *p);
				}
			}
			else
				g_string_append_c(result, *p);			
		}
	}
	else /* files in home trash */
	{
		g_string_append(result, g_get_user_data_dir());
		g_string_append_c(result, '/');
		g_string_append(result, "Trash/files/");
		if(*p == '`') /* special handling of the first character */
		{
			++p;
			if(*p == '`') /* translate `` to ` */
			{
				g_string_append_c(result, '`');
				++p;
			}
			else if(*p == '\\') /* translate `\ to \ */
			{
				g_string_append_c(result, '\\');
				++p;
			}
			else
				g_string_append_c(result, '`'); /* don't translate anything */
		}
		g_string_append(result, p); /* append the remaining part */
	}
    return g_string_free(result, FALSE);
}
예제 #23
0
/* NOTE: Sticking to natural behavior of returning a list with the unchanged input_string, incase nothing can be substituted, however, this is expensive. A better way would be to return NULL incase of no changes, and let the caller handle the NULL case, which implies that there is no change in the input_string */
GPtrArray* substitute_parameters(gchar *input_string, FmFileInfoList *file_info_list)
{
	//printf("Input string is %s\n", input_string);
	GPtrArray *out_string_array = g_ptr_array_new();
	if(strchr(input_string, '%') == NULL){
		//printf("Found nothing to expand. Returning input_string.\n");
		g_ptr_array_add(out_string_array, g_string_new(input_string));
		return out_string_array;
	}

	gsize i, j;
	gsize len_file_list = fm_list_get_length(file_info_list);
	GString *out_string = g_string_new(NULL);
	gsize first_pos = strcspn(input_string, "%");
	gchar *pos = input_string + first_pos;
	g_string_append_len(out_string, input_string, first_pos);
	GString *g_string_i = NULL;
	gchar *base_name = NULL, *base_dir = NULL, *file_name = NULL, *host_name = NULL, *user_name = NULL, *port = NULL, *scheme = NULL, *uri = NULL, *file_name_wo_ext = NULL, *ext_pos = NULL;
	gboolean array_is_init = FALSE;
	FmFileInfo *file_info_i = NULL, *file_info_j = NULL;
	char temp[256];
	gboolean curr_dir_flag;

	while((pos = strchr(pos, '%')) != NULL){
		switch(pos[1]){
			case 'b':
				/* Works */
				if(array_is_init == FALSE){
					for(i=0; i<len_file_list; ++i){
						g_string_i = g_string_new(out_string->str);
						file_info_i = fm_list_peek_nth(file_info_list, i);
						base_name = (gchar *)fm_file_info_get_disp_name(file_info_i);
						g_string_append(g_string_i, base_name);
						g_string_append_c(g_string_i, ' ');

						g_ptr_array_add(out_string_array, g_string_new(g_string_i->str));
						g_string_free(g_string_i, TRUE);
					}
					break;
				}

				file_info_i = fm_list_peek_head(file_info_list);
				base_name = (gchar *)fm_file_info_get_disp_name(file_info_i);
				for(i=0; i<out_string_array->len; ++i){
					g_string_i = (GString *)g_ptr_array_index(out_string_array, i);
					g_string_append(g_string_i, base_name);
					g_string_append_c(g_string_i, ' ');
				}

				break;
			case 'B':
				/* Works */
				if(array_is_init == FALSE)
					g_ptr_array_add(out_string_array, g_string_new(out_string->str));

				for(i=0; i<out_string_array->len; ++i){
					g_string_i = (GString *)g_ptr_array_index(out_string_array, i);
					for(j=0; j<len_file_list; ++j){
						file_info_j= fm_list_peek_nth(file_info_list, j);
						base_name = (gchar *)fm_file_info_get_disp_name(file_info_j);
						g_string_append(g_string_i, base_name);
						g_string_append_c(g_string_i, ' ');
					}
				}

				break;
			case 'c':
				/* Works */
				memset(temp, 256, 0);
				if(array_is_init == FALSE)
					g_ptr_array_add(out_string_array, g_string_new(out_string->str));

				for(i=0; i<out_string_array->len; ++i){
					g_string_i = (GString *)g_ptr_array_index(out_string_array, i);
					sprintf(temp, "%u", len_file_list);
					g_string_append(g_string_i, temp);
					g_string_append_c(g_string_i, ' ');
				}

				break;
			case 'd':
				/* Works */
				curr_dir_flag = FALSE;
				if(array_is_init == FALSE){
					for(i=0; i<len_file_list; ++i){
						g_string_i = g_string_new(out_string->str);
						file_info_i = fm_list_peek_nth(file_info_list, i);
						if(fm_file_info_is_dir(file_info_i) == TRUE){
							base_dir = fm_path_to_str(fm_file_info_get_path(file_info_i));
						} else {
							if(curr_dir_flag == FALSE){
								base_dir = g_get_current_dir();
								curr_dir_flag = TRUE;
							} else {
								continue;
							}
						}
						g_string_append(g_string_i, base_dir);
						g_string_append_c(g_string_i, ' ');

						g_ptr_array_add(out_string_array, g_string_new(g_string_i->str));

						g_free(base_dir);
						g_string_free(g_string_i, TRUE);
					}
					break;
				}

				file_info_i = fm_list_peek_head(file_info_list);
				if(fm_file_info_is_dir(file_info_i) == TRUE){
					base_dir = fm_path_to_str(fm_file_info_get_path(file_info_i));
				} else {
					if(curr_dir_flag == FALSE){
						base_dir = g_get_current_dir();
						curr_dir_flag = TRUE;
					} else {
						continue;
					}
				}
				for(i=0; i<out_string_array->len; ++i){
					g_string_i = (GString *)g_ptr_array_index(out_string_array, i);
					g_string_append(g_string_i, base_dir);
					g_string_append_c(g_string_i, ' ');
				}

				g_free(base_dir);
				break;
			case 'D':
				/* Works */
				if(array_is_init == FALSE)
					g_ptr_array_add(out_string_array, g_string_new(out_string->str));

				for(i=0; i<out_string_array->len; ++i){
					curr_dir_flag = FALSE;
					g_string_i = (GString *)g_ptr_array_index(out_string_array, i);
					for(j=0; j<len_file_list; ++j){
						file_info_j= fm_list_peek_nth(file_info_list, j);
						if(fm_file_info_is_dir(file_info_j) == TRUE){
							base_dir = fm_path_to_str(fm_file_info_get_path(file_info_j));
						} else {
							if(curr_dir_flag == FALSE){
								base_dir = g_get_current_dir();
								curr_dir_flag = TRUE;
							} else {
								continue;
							}
						}
						g_string_append(g_string_i, base_dir);
						g_string_append_c(g_string_i, ' ');

						g_free(base_dir);
					}
				}

				break;
			case 'f':
				/* Works */
				if(array_is_init == FALSE){
					for(i=0; i<len_file_list; ++i){
						g_string_i = g_string_new(out_string->str);
						file_info_i = fm_list_peek_nth(file_info_list, i);
						file_name = (gchar *)fm_path_to_str(fm_file_info_get_path(file_info_i));
						g_string_append(g_string_i, file_name);
						g_string_append_c(g_string_i, ' ');

						g_ptr_array_add(out_string_array, g_string_new(g_string_i->str));

						g_free(file_name);
						g_string_free(g_string_i, TRUE);
					}
					break;
				}

				file_info_i = fm_list_peek_head(file_info_list);
				file_name = (gchar *)fm_path_to_str(fm_file_info_get_path(file_info_i));
				for(i=0; i<out_string_array->len; ++i){
					g_string_i = (GString *)g_ptr_array_index(out_string_array, i);
					g_string_append(g_string_i, file_name);
					g_string_append_c(g_string_i, ' ');
				}

				g_free(file_name);
				break;
			case 'F':
				/* Works */
				if(array_is_init == FALSE)
					g_ptr_array_add(out_string_array, g_string_new(out_string->str));

				for(i=0; i<out_string_array->len; ++i){
					g_string_i = (GString *)g_ptr_array_index(out_string_array, i);
					for(j=0; j<len_file_list; ++j){
						file_info_j= fm_list_peek_nth(file_info_list, j);
						file_name = (gchar *)fm_path_to_str(fm_file_info_get_path(file_info_j));
						g_string_append(g_string_i, file_name);
						g_string_append_c(g_string_i, ' ');

						g_free(file_name);
					}
				}

				break;
			case 'h':
				if(array_is_init == FALSE)
					g_ptr_array_add(out_string_array, g_string_new(out_string->str));

				for(i=0; i<out_string_array->len; ++i){
					g_string_i = (GString *)g_ptr_array_index(out_string_array, i);
					file_info_i = fm_list_peek_nth(file_info_list, i);
					host_name = get_host_name(file_info_i);
					g_string_append(g_string_i, host_name);
					g_string_append_c(g_string_i, ' ');
				}
				break;
			case 'n':
				if(array_is_init == FALSE)
					g_ptr_array_add(out_string_array, g_string_new(out_string->str));

				for(i=0; i<out_string_array->len; ++i){
					g_string_i = (GString *)g_ptr_array_index(out_string_array, i);
					file_info_i = fm_list_peek_nth(file_info_list, i);
					user_name = get_user_name(file_info_i);
					g_string_append(g_string_i, user_name);
					g_string_append_c(g_string_i, ' ');
				}
				break;
			case 'p':
				if(array_is_init == FALSE)
					g_ptr_array_add(out_string_array, g_string_new(out_string->str));

				for(i=0; i<out_string_array->len; ++i){
					g_string_i = (GString *)g_ptr_array_index(out_string_array, i);
					file_info_i = fm_list_peek_nth(file_info_list, i);
					port = get_port(file_info_i);
					g_string_append(g_string_i, port);
					g_string_append_c(g_string_i, ' ');
				}
				break;
			case 's':
				if(array_is_init == FALSE)
					g_ptr_array_add(out_string_array, g_string_new(out_string->str));

				for(i=0; i<out_string_array->len; ++i){
					g_string_i = (GString *)g_ptr_array_index(out_string_array, i);
					file_info_i = fm_list_peek_nth(file_info_list, i);
					scheme = get_scheme(file_info_i);
					g_string_append(g_string_i, scheme);
					g_string_append_c(g_string_i, ' ');
				}

				break;
			case 'u':
				/* Works */
				if(array_is_init == FALSE){
					for(i=0; i<len_file_list; ++i){
						g_string_i = g_string_new(out_string->str);
						file_info_i = fm_list_peek_nth(file_info_list, i);
						uri = fm_path_to_uri(fm_file_info_get_path(file_info_i));
						g_string_append(g_string_i, uri);
						g_string_append_c(g_string_i, ' ');

						g_ptr_array_add(out_string_array, g_string_new(g_string_i->str));
						g_string_free(g_string_i, TRUE);
					}
					break;
				}

				file_info_i = fm_list_peek_head(file_info_list);
				uri = fm_path_to_uri(fm_file_info_get_path(file_info_i));
				for(i=0; i<out_string_array->len; ++i){
					g_string_i = (GString *)g_ptr_array_index(out_string_array, i);
					g_string_append(g_string_i, uri);
					g_string_append_c(g_string_i, ' ');
				}

				break;
			case 'U':
				/* Works */
				if(array_is_init == FALSE)
					g_ptr_array_add(out_string_array, g_string_new(out_string->str));

				for(i=0; i<out_string_array->len; ++i){
					g_string_i = (GString *)g_ptr_array_index(out_string_array, i);
					for(j=0; j<len_file_list; ++j){
						file_info_j= fm_list_peek_nth(file_info_list, j);
						uri = fm_path_to_uri(fm_file_info_get_path(file_info_j));
						g_string_append(g_string_i, uri);
						g_string_append_c(g_string_i, ' ');
					}
				}

				break;
			case 'w':
				/* Works */
				if(array_is_init == FALSE){
					for(i=0; i<len_file_list; ++i){
						g_string_i = g_string_new(out_string->str);
						file_info_i = fm_list_peek_nth(file_info_list, i);
						file_name = (gchar *)fm_file_info_get_disp_name(file_info_i);
						//printf("%s\n", file_name);

						ext_pos = g_strrstr(fm_file_info_get_disp_name(fm_list_peek_nth(file_info_list, i)), ".");
						if(ext_pos != NULL)
							file_name_wo_ext = g_strndup(file_name, strlen(file_name) - strlen(ext_pos));
						else
							file_name_wo_ext = g_strdup(file_name);

						g_string_append(g_string_i, file_name_wo_ext);
						g_string_append_c(g_string_i, ' ');
						g_ptr_array_add(out_string_array, g_string_new(g_string_i->str));

						g_free(file_name_wo_ext);
						g_string_free(g_string_i, TRUE);
					}
					break;
				}

				file_info_i = fm_list_peek_head(file_info_list);
				file_name = (gchar *)fm_file_info_get_disp_name(file_info_i);
				ext_pos = g_strrstr(file_name, ".");
				if(ext_pos != NULL)
					file_name_wo_ext = g_strndup(file_name, strlen(file_name) - strlen(ext_pos));
				else
					file_name_wo_ext = g_strdup(file_name);

				for(i=0; i<out_string_array->len; ++i){
					g_string_i = (GString *)g_ptr_array_index(out_string_array, i);
					g_string_append(g_string_i, file_name_wo_ext);
					g_string_append_c(g_string_i, ' ');
				}
				g_free(file_name_wo_ext);
				break;
			case 'W':
				/* Works */
				if(array_is_init == FALSE)
					g_ptr_array_add(out_string_array, g_string_new(out_string->str));

				for(i=0; i<out_string_array->len; ++i){
					g_string_i = (GString *)g_ptr_array_index(out_string_array, i);
					for(j=0; j<len_file_list; ++j){
						file_info_j= fm_list_peek_nth(file_info_list, j);
						file_name = (gchar *)fm_file_info_get_disp_name(file_info_j);
						ext_pos = g_strrstr(file_name, ".");
						if(ext_pos != NULL)
							file_name_wo_ext = g_strndup(file_name, strlen(file_name) - strlen(ext_pos));
						else
							file_name_wo_ext = g_strdup(file_name);
						g_string_append(g_string_i, file_name_wo_ext);
						g_string_append_c(g_string_i, ' ');
						g_free(file_name_wo_ext);
					}
				}
				break;
			case 'x':
				/* Works */
				if(array_is_init == FALSE){
					for(i=0; i<len_file_list; ++i){
						file_info_i = fm_list_peek_nth(file_info_list, i);
						file_name = (gchar *)fm_file_info_get_disp_name(file_info_i);
						ext_pos = g_strrstr(file_name, ".");
						if(ext_pos != NULL){
							g_string_i = g_string_new(out_string->str);
							g_string_append(g_string_i, ext_pos);
							g_string_append_c(g_string_i, ' ');
							g_ptr_array_add(out_string_array, g_string_new(g_string_i->str));

							g_free(file_name_wo_ext);
							g_string_free(g_string_i, TRUE);
						}
					}
					break;
				}

				file_info_i = fm_list_peek_head(file_info_list);
				file_name = (gchar *)fm_file_info_get_disp_name(file_info_i);
				ext_pos = g_strrstr(file_name, ".");
				if(ext_pos == NULL)
					break;

				for(i=0; i<out_string_array->len;++i){
					g_string_i = (GString *)g_ptr_array_index(out_string_array, i);
					g_string_append(g_string_i, ext_pos);
					g_string_append_c(g_string_i, ' ');
				}

				break;
			case 'X':
				/* Works */
				if(array_is_init == FALSE)
					g_ptr_array_add(out_string_array, g_string_new(out_string->str));

				for(i=0; i<out_string_array->len; ++i){
					g_string_i = (GString *)g_ptr_array_index(out_string_array, i);
					for(j=0; j<len_file_list; ++j){
						file_info_j= fm_list_peek_nth(file_info_list, j);
						file_name = (gchar *)fm_file_info_get_disp_name(file_info_j);
						ext_pos = g_strrstr(file_name, ".");
						if(ext_pos != NULL){
							g_string_append(g_string_i, ext_pos);
							g_string_append_c(g_string_i, ' ');
						}
					}
				}

				break;
			case '%':
				/* Works */
				if(array_is_init == FALSE)
					g_ptr_array_add(out_string_array, g_string_new(out_string->str));

				for(i=0; i<out_string_array->len; ++i){
					g_string_i = (GString *)g_ptr_array_index(out_string_array, i);
					g_string_append(g_string_i, "% ");
				}

				break;
			default:
				return NULL;
		}

		pos += 2;
		(array_is_init == FALSE)?array_is_init = TRUE:0;
	}

	return out_string_array;
}
예제 #24
0
파일: fm-dnd-dest.c 프로젝트: engla/libfm
/* return 0 for match */
static gint _compare_path(gconstpointer p1, gconstpointer pth) {
    FmPath *fmp1 = p1;
    FmPath *fmp2 = pth;
    g_debug("Comparing '%s' to '%s'", fm_path_to_str(fmp1), fm_path_to_str(fmp2));
    return !fm_path_equal(fmp1, fmp2);
}
예제 #25
0
gboolean deep_count_posix(FmDeepCountJob* job, FmPath* fm_path)
{
    FmJob* fmjob = (FmJob*)job;
    char* path = fm_path_to_str(fm_path);
    struct stat st;
    int ret;

_retry_stat:
    if( G_UNLIKELY(job->flags & FM_DC_JOB_FOLLOW_LINKS) )
        ret = stat(path, &st);
    else
        ret = lstat(path, &st);

    if( ret == 0 )
    {
        ++job->count;
        job->total_size += (goffset)st.st_size;
        job->total_block_size += (st.st_blocks * st.st_blksize);

        /* NOTE: if job->dest_dev is 0, that means our destination
         * folder is not on native UNIX filesystem. Hence it's not
         * on the same device. Our st.st_dev will always be non-zero
         * since our file is on a native UNIX filesystem. */

        /* only descends into files on the same filesystem */
        if( job->flags & FM_DC_JOB_SAME_FS )
        {
            if( st.st_dev != job->dest_dev )
                return TRUE;
        }
        /* only descends into files on the different filesystem */
        else if( job->flags & FM_DC_JOB_PREPARE_MOVE )
        {
            if( st.st_dev == job->dest_dev )
                return TRUE;
        }
    }
    else
    {
        GError* err = g_error_new(G_IO_ERROR, g_io_error_from_errno(errno), "%s", g_strerror(errno));
        FmJobErrorAction act = fm_job_emit_error(FM_JOB(job), err, FM_JOB_ERROR_MILD);
        g_error_free(err);
        err = NULL;
        if(act == FM_JOB_RETRY)
            goto _retry_stat;
        return FALSE;
    }
    if(fm_job_is_cancelled(fmjob))
        return FALSE;

    if( S_ISDIR(st.st_mode) ) /* if it's a dir */
    {
        GDir* dir_ent = g_dir_open(path, 0, NULL);
        if(dir_ent)
        {
            const char* basename;
            while( !fm_job_is_cancelled(fmjob)
                    && (basename = g_dir_read_name(dir_ent)) )
            {
                FmPath* sub = fm_path_new_child(fm_path, basename);
                if(!fm_job_is_cancelled(fmjob))
                {
                    if(deep_count_posix(job, sub))
                    {
                        /* for moving across different devices, an additional 'delete'
                         * for source file is needed. so let's +1 for the delete.*/
                        if(job->flags & FM_DC_JOB_PREPARE_MOVE)
                        {
                            ++job->total_size;
                            ++job->total_block_size;
                            ++job->count;
                        }
                    }
                }
                fm_path_unref(sub);
            }
            g_dir_close(dir_ent);
        }
    }
    g_free(path);
    return TRUE;
}
예제 #26
0
static gboolean fm_file_info_job_run(FmJob* fmjob)
{
    GList* l;
    FmFileInfoJob* job = (FmFileInfoJob*)fmjob;
    GError* err = NULL;

    if(job->file_infos == NULL)
        return FALSE;

    for(l = fm_file_info_list_peek_head_link(job->file_infos); !fm_job_is_cancelled(fmjob) && l;)
    {
        FmFileInfo* fi = (FmFileInfo*)l->data;
        GList* next = l->next;
        FmPath* path = fm_file_info_get_path(fi);

        if(job->current)
            fm_path_unref(job->current);
        job->current = fm_path_ref(path);

        if(fm_path_is_native(path))
        {
            char* path_str = fm_path_to_str(path);
            if(!_fm_file_info_job_get_info_for_native_file(fmjob, fi, path_str, &err))
            {
                FmJobErrorAction act = fm_job_emit_error(fmjob, err, FM_JOB_ERROR_MILD);
                g_error_free(err);
                err = NULL;
                if(act == FM_JOB_RETRY)
                {
                    g_free(path_str);
                    continue; /* retry */
                }

                fm_file_info_list_delete_link(job->file_infos, l); /* also calls unref */
            }
            else if(G_UNLIKELY(job->flags & FM_FILE_INFO_JOB_EMIT_FOR_EACH_FILE))
                fm_job_call_main_thread(fmjob, _emit_current_file, fi);
            g_free(path_str);
            /* recursively set display names for path parents */
            _check_native_display_names(fm_path_get_parent(path));
        }
        else
        {
            GFile* gf;

            gf = fm_path_to_gfile(path);
            if(!_fm_file_info_job_get_info_for_gfile(fmjob, fi, gf, &err))
            {
              if(err->domain == G_IO_ERROR && err->code == G_IO_ERROR_NOT_MOUNTED)
              {
                GFileInfo *inf;
                /* location by link isn't mounted; unfortunately we cannot
                   launch a target if we don't know what kind of target we
                   have; lets make a simplest directory-kind GFIleInfo */
                /* FIXME: this may be dirty a bit */
                g_error_free(err);
                err = NULL;
                inf = g_file_info_new();
                g_file_info_set_file_type(inf, G_FILE_TYPE_DIRECTORY);
                g_file_info_set_name(inf, fm_path_get_basename(path));
                g_file_info_set_display_name(inf, fm_path_get_basename(path));
                fm_file_info_set_from_g_file_data(fi, gf, inf);
                g_object_unref(inf);
              }
              else
              {
                FmJobErrorAction act = fm_job_emit_error(fmjob, err, FM_JOB_ERROR_MILD);
                g_error_free(err);
                err = NULL;
                if(act == FM_JOB_RETRY)
                {
                    g_object_unref(gf);
                    continue; /* retry */
                }

                fm_file_info_list_delete_link(job->file_infos, l); /* also calls unref */
                goto _next;
              }
            }
            else if(G_UNLIKELY(job->flags & FM_FILE_INFO_JOB_EMIT_FOR_EACH_FILE))
                    fm_job_call_main_thread(fmjob, _emit_current_file, fi);
            /* recursively set display names for path parents */
            _check_gfile_display_names(fm_path_get_parent(path), gf);
_next:
            g_object_unref(gf);
        }
        l = next;
    }
    return TRUE;
}
예제 #27
0
/*********************************************************************
 * ...
 * 
 * 
 ********************************************************************/
gboolean fm_file_info_job_run (FmJob *fmjob)
{
	FmFileInfoJob *job = (FmFileInfoJob*) fmjob;
    GError *err = NULL;

	GList *l;
	for (l = fm_list_peek_head_link (job->file_infos); !fm_job_is_cancelled (fmjob) && l; )
	{
		FmFileInfo *file_info = (FmFileInfo*) l->data;
        GList *next = l->next;

        job->current = file_info->path;

		if (fm_path_is_native (file_info->path))
		{
			char *path_str = fm_path_to_str (file_info->path);
			
            
            // FileInfo rework: new function for testing...
            // this one is not cancellable and doesn't handle errors...
            // if (!fm_file_info_job_get_info_for_native_file (FM_JOB (job), file_info, path_str, &err))
            if (!fm_file_info_set_for_native_file (file_info, path_str))
            {
                //~ FmJobErrorAction act = fm_job_emit_error (FM_JOB(job), err, FM_JOB_ERROR_MILD);
                //~ 
                //~ g_error_free (err);
                //~ err = NULL;
                //~ 
                //~ if (act == FM_JOB_RETRY)
                    //~ continue;

                DEBUG ("fm_file_info_set_for_native_file: error reading %s\n", path_str);
                
                next = l->next;
                fm_list_delete_link (job->file_infos, l); // Also calls unref...
            }
			
            g_free (path_str);
		}
		else
		{
            GFile *gf;
            
            if (fm_path_is_virtual (file_info->path))
            {
                // This is a xdg menu
                if (fm_path_is_xdg_menu (file_info->path))
                {
                    MenuCache *mc;
                    MenuCacheDir *dir;
                    
                    char *path_str = fm_path_to_str (file_info->path);
                    char *menu_name = path_str + 5, ch;
                    char *dir_name;
                    
                    while (*menu_name == '/')
                        ++menu_name;
                    
                    dir_name = menu_name;
                    
                    while (*dir_name && *dir_name != '/')
                        ++dir_name;
                    
                    ch = *dir_name;
                    *dir_name = '\0';
                    
                    menu_name = g_strconcat (menu_name, ".menu", NULL);
                    mc = menu_cache_lookup_sync (menu_name);
                    g_free (menu_name);

                    if (*dir_name && !(*dir_name == '/' && dir_name[1] == '\0'))
                    {
                        char *tmp = g_strconcat ("/",
                                                 menu_cache_item_get_id (MENU_CACHE_ITEM(menu_cache_get_root_dir (mc))),
                                                 dir_name, NULL);
                        
                        dir = menu_cache_get_dir_from_path (mc, tmp);
                        
                        g_free (tmp);
                    }
                    else
                    {
                        dir = menu_cache_get_root_dir (mc);
                    }
                    
                    if (dir)
                    {
                        fm_file_info_set_from_menu_cache_item (file_info, (MenuCacheItem*) dir);
                    }
                    else
                    {
                        next = l->next;
                        fm_list_delete_link (job->file_infos, l); // Also calls unref...
                    }
                    
                    g_free (path_str);
                    menu_cache_unref (mc);
                    
                    l = l->next;
                    continue;
                }
            }

			gf = fm_path_to_gfile (file_info->path);
			
            if (!fm_file_info_job_get_info_for_gfile (FM_JOB (job), file_info, gf, &err))
            {
                FmJobErrorAction act = fm_job_emit_error (FM_JOB (job), err, FM_JOB_ERROR_MILD);
                
                g_error_free (err);
                err = NULL;
                
                if (act == FM_JOB_RETRY)
                    continue;

                next = l->next;
                
                fm_list_delete_link (job->file_infos, l);   // Also calls unref...
            }
			
            g_object_unref (gf);
		}
        
        l = next;
	}
	
    return TRUE;
}
예제 #28
0
gboolean fm_launch_files(GAppLaunchContext* ctx, GList* file_infos, FmFileLauncher* launcher, gpointer user_data)
{
    GList* l;
    GHashTable* hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
    GList* folders = NULL;
    FmFileInfo* fi;
    GError* err = NULL;
    GAppInfo* app;

    for(l = file_infos; l; l=l->next)
    {
        GList* fis;
        fi = (FmFileInfo*)l->data;
        if(fm_file_info_is_dir(fi))
            folders = g_list_prepend(folders, fi);
        else
        {
            /* FIXME: handle shortcuts, such as the items in menu:// */
            if(fm_path_is_native(fi->path))
            {
                char* filename;
                if(fm_file_info_is_desktop_entry(fi))
                {
                    /* if it's a desktop entry file, directly launch it. */
                    filename = fm_path_to_str(fi->path);
                    if(!fm_launch_desktop_entry(ctx, filename, NULL, &err))
                    {
                        if(launcher->error)
                            launcher->error(ctx, err, user_data);
                        g_error_free(err);
                        err = NULL;
                    }
                    continue;
                }
                else if(fm_file_info_is_executable_type(fi))
                {
                    /* if it's an executable file, directly execute it. */
                    filename = fm_path_to_str(fi->path);
                    /* FIXME: we need to use eaccess/euidaccess here. */
                    if(g_file_test(filename, G_FILE_TEST_IS_EXECUTABLE))
                    {
                        app = g_app_info_create_from_commandline(filename, NULL, 0, NULL);
                        if(app)
                        {
                            if(!g_app_info_launch(app, NULL, ctx, &err))
                            {
                                if(launcher->error)
                                    launcher->error(ctx, err, user_data);
                                g_error_free(err);
                                err = NULL;
                            }
                            g_object_unref(app);
                            continue;
                        }
                    }
                    g_free(filename);
                }
            }
            else /* not a native path */
            {
                if(fm_file_info_is_shortcut(fi) && !fm_file_info_is_dir(fi))
                {
                    /* FIXME: special handling for shortcuts */
                    if(fm_path_is_xdg_menu(fi->path) && fi->target)
                    {
                        if(!fm_launch_desktop_entry(ctx, fi->target, NULL, &err))
                        {
                            if(launcher->error)
                                launcher->error(ctx, err, user_data);
                            g_error_free(err);
                            err = NULL;
                        }
                        continue;
                    }
                }
            }
            if(fi->type && fi->type->type)
            {
                fis = g_hash_table_lookup(hash, fi->type->type);
                fis = g_list_prepend(fis, fi);
                g_hash_table_insert(hash, fi->type->type, fis);
            }
        }
    }

    if(g_hash_table_size(hash) > 0)
    {
        GHashTableIter it;
        const char* type;
        GList* fis;
        g_hash_table_iter_init(&it, hash);
        while(g_hash_table_iter_next(&it, &type, &fis))
        {
            GAppInfo* app = g_app_info_get_default_for_type(type, FALSE);
            if(!app)
            {
                if(launcher->get_app)
                {
                    FmMimeType* mime_type = ((FmFileInfo*)fis->data)->type;
                    app = launcher->get_app(fis, mime_type, user_data, NULL);
                }
            }
            if(app)
            {
                for(l=fis; l; l=l->next)
                {
                    char* uri;
                    fi = (FmFileInfo*)l->data;
                    uri = fm_path_to_uri(fi->path);
                    l->data = uri;
                }
                fis = g_list_reverse(fis);
                g_app_info_launch_uris(app, fis, ctx, err);
                /* free URI strings */
                g_list_foreach(fis, (GFunc)g_free, NULL);
                g_object_unref(app);
            }
            g_list_free(fis);
        }
    }
    g_hash_table_destroy(hash);

    if(folders)
    {
        folders = g_list_reverse(folders);
        if(launcher->open_folder)
        {
            launcher->open_folder(ctx, folders, user_data, &err);
            if(err)
            {
                if(launcher->error)
                    launcher->error(ctx, err, user_data);
                g_error_free(err);
                err = NULL;
            }
        }
        g_list_free(folders);
    }
    return TRUE;
}
예제 #29
0
static gboolean fm_dir_list_job_run_gio(FmDirListJob* job)
{
    GFileEnumerator *enu;
    GFileInfo *inf;
    FmFileInfo* fi;
    GError *err = NULL;
    FmJob* fmjob = FM_JOB(job);
    GFile* gf;
    const char* query;

    gf = fm_path_to_gfile(job->dir_path);
_retry:
    inf = g_file_query_info(gf, gfile_info_query_attribs, 0, fm_job_get_cancellable(fmjob), &err);
    if(!inf )
    {
        FmJobErrorAction act = fm_job_emit_error(fmjob, err, FM_JOB_ERROR_MODERATE);
        g_error_free(err);
        if( act == FM_JOB_RETRY )
        {
            err = NULL;
            goto _retry;
        }
        else
        {
            g_object_unref(gf);
            return FALSE;
        }
    }

    if( g_file_info_get_file_type(inf) != G_FILE_TYPE_DIRECTORY)
    {
        char *path_str = fm_path_to_str(job->dir_path);
        err = g_error_new(G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY,
                          _("The specified directory '%s' is not valid"),
                          path_str);
        fm_job_emit_error(fmjob, err, FM_JOB_ERROR_CRITICAL);
        g_free(path_str);
        g_error_free(err);
        g_object_unref(gf);
        g_object_unref(inf);
        return FALSE;
    }

    /* check if FS is R/O and set attr. into inf */
    _fm_file_info_job_update_fs_readonly(gf, inf, NULL, NULL);

    job->dir_fi = fm_file_info_new_from_g_file_data(gf, inf, job->dir_path);
    g_object_unref(inf);

    if(G_UNLIKELY(job->flags & FM_DIR_LIST_JOB_DIR_ONLY))
    {
        query = G_FILE_ATTRIBUTE_STANDARD_TYPE","G_FILE_ATTRIBUTE_STANDARD_NAME","
                G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN","G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP","
                G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK","G_FILE_ATTRIBUTE_STANDARD_IS_VIRTUAL","
                G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME","
                G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME","G_FILE_ATTRIBUTE_STANDARD_ICON","
                G_FILE_ATTRIBUTE_STANDARD_SIZE","G_FILE_ATTRIBUTE_STANDARD_TARGET_URI","
                "unix::*,time::*,access::*,id::filesystem";
    }
    else
        query = gfile_info_query_attribs;

    enu = g_file_enumerate_children (gf, query, 0, fm_job_get_cancellable(fmjob), &err);
    g_object_unref(gf);
    if(enu)
    {
        while( ! fm_job_is_cancelled(fmjob) )
        {
            inf = g_file_enumerator_next_file(enu, fm_job_get_cancellable(fmjob), &err);
            if(inf)
            {
                FmPath *dir, *sub;
                GFile *child;
                if(G_UNLIKELY(job->flags & FM_DIR_LIST_JOB_DIR_ONLY))
                {
                    /* FIXME: handle symlinks */
                    if(g_file_info_get_file_type(inf) != G_FILE_TYPE_DIRECTORY)
                    {
                        g_object_unref(inf);
                        continue;
                    }
                }

                /* virtual folders may return children not within them */
                dir = fm_path_new_for_gfile(g_file_enumerator_get_container(enu));
                if (fm_path_equal(job->dir_path, dir))
                    sub = fm_path_new_child(job->dir_path, g_file_info_get_name(inf));
                else
                    sub = fm_path_new_child(dir, g_file_info_get_name(inf));
                child = g_file_get_child(g_file_enumerator_get_container(enu),
                                         g_file_info_get_name(inf));
                if (g_file_info_get_file_type(inf) == G_FILE_TYPE_DIRECTORY)
                    /* for dir: check if its FS is R/O and set attr. into inf */
                    _fm_file_info_job_update_fs_readonly(child, inf, NULL, NULL);
                fi = fm_file_info_new_from_g_file_data(child, inf, sub);
                fm_path_unref(sub);
                fm_path_unref(dir);
                g_object_unref(child);
                fm_dir_list_job_add_found_file(job, fi);
                fm_file_info_unref(fi);
            }
            else
            {
                if(err)
                {
                    FmJobErrorAction act = fm_job_emit_error(fmjob, err, FM_JOB_ERROR_MILD);
                    g_error_free(err);
                    /* FM_JOB_RETRY is not supported. */
                    if(act == FM_JOB_ABORT)
                        fm_job_cancel(fmjob);
                }
                /* otherwise it's EOL */
                break;
            }
            g_object_unref(inf);
        }
        g_file_enumerator_close(enu, NULL, &err);
        g_object_unref(enu);
    }
    else
    {
        fm_job_emit_error(fmjob, err, FM_JOB_ERROR_CRITICAL);
        g_error_free(err);
        return FALSE;
    }
    return TRUE;
}