Пример #1
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();
  }
}
Пример #2
0
/*****************************************************************************************
 *  Create Direct Root Items...
 * 
 * 
 ****************************************************************************************/
void fm_dir_tree_model_load (FmDirTreeModel *dir_tree_model)
{
    FmPath *path;
    FmFileInfo *file_info;
    FmDirTreeItem *dir_tree_item;
    
    
    // Desktop...
    path = fm_path_get_desktop ();
    file_info = fm_file_info_new_for_path (path);
    fm_file_info_query (file_info, NULL, NULL);
    fm_dir_tree_model_add_root (dir_tree_model, file_info, NULL, TRUE);


    /* Root FileSystem...
    path = fm_path_get_root ();
    file_info = fm_file_info_new_for_path (path);
    fm_file_info_query (file_info, NULL, NULL);
    fm_dir_tree_model_add_root (dir_tree_model, file_info, NULL, TRUE);
    */
    
    // Settings...
    path = fm_path_new_for_uri ("menu://Applications/DesktopSettings");
    file_info = fm_file_info_new_for_path (path);
    fm_file_info_query (file_info, NULL, NULL);
    fm_dir_tree_model_add_root (dir_tree_model, file_info, NULL, FALSE);
    fm_path_unref (path);
    
    // System...
    path = fm_path_new_for_uri ("menu://Applications/System");
    file_info = fm_file_info_new_for_path (path);
    fm_file_info_query (file_info, NULL, NULL);
    fm_dir_tree_model_add_root (dir_tree_model, file_info, NULL, FALSE);
    fm_path_unref (path);
    
    // What's the purpose of weak pointers ??? :-P
    g_object_add_weak_pointer (dir_tree_model, &dir_tree_model);
    return;
}
Пример #3
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();
}
Пример #4
0
static void init_model()
{
    if(G_UNLIKELY(!model))
    {
        GtkTreeIter it;
        PlaceItem* item;
        GList *vols, *l;
        GIcon* gicon;
        FmIcon* icon;
        GFile* gf;
        GdkPixbuf* pix;

        theme_change_handler = g_signal_connect(gtk_icon_theme_get_default(), "changed",
                                                G_CALLBACK(update_icons), NULL);

        use_trash_change_handler = g_signal_connect(fm_config, "changed::use_trash",
                                                 G_CALLBACK(on_use_trash_changed), NULL);

        pane_icon_size_change_handler = g_signal_connect(fm_config, "changed::pane_icon_size",
                                                 G_CALLBACK(on_pane_icon_size_changed), NULL);

        model = gtk_list_store_new(N_COLS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER);
        g_object_weak_ref(G_OBJECT(model), on_model_destroy, NULL);

        item = g_slice_new0(PlaceItem);
        item->type = PLACE_PATH;
        item->path = fm_path_ref(fm_path_get_home());
        item->icon = fm_icon_from_name("user-home");
        gtk_list_store_append(model, &it);
        pix = fm_icon_get_pixbuf(item->icon, fm_config->pane_icon_size);
        gtk_list_store_set(model, &it, COL_ICON, pix, COL_LABEL, item->path->name, COL_INFO, item, -1);
        g_object_unref(pix);

        /* Only show desktop in side pane when the user has a desktop dir. */
        if(g_file_test(g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP), G_FILE_TEST_IS_DIR))
        {
            item = g_slice_new0(PlaceItem);
            item->type = PLACE_PATH;
            item->path = fm_path_ref(fm_path_get_desktop());
            item->icon = fm_icon_from_name("user-desktop");
            gtk_list_store_append(model, &it);
            pix = fm_icon_get_pixbuf(item->icon, fm_config->pane_icon_size);
            gtk_list_store_set(model, &it, COL_ICON, pix, COL_LABEL, _("Desktop"), COL_INFO, item, -1);
            g_object_unref(pix);
        }

        if(fm_config->use_trash)
            create_trash();

        item = g_slice_new0(PlaceItem);
        item->type = PLACE_PATH;
        item->path = fm_path_ref(fm_path_get_apps_menu());
        item->icon = fm_icon_from_name("system-software-install");
        gtk_list_store_append(model, &it);
        pix = fm_icon_get_pixbuf(item->icon, fm_config->pane_icon_size);
        gtk_list_store_set(model, &it, COL_ICON, pix, COL_LABEL, _("Applications"), COL_INFO, item, -1);
        g_object_unref(pix);

        /* volumes */
        vol_mon = g_volume_monitor_get();
        g_signal_connect(vol_mon, "volume-added", G_CALLBACK(on_vol_added), NULL);
        g_signal_connect(vol_mon, "volume-removed", G_CALLBACK(on_vol_removed), NULL);
        g_signal_connect(vol_mon, "volume-changed", G_CALLBACK(on_vol_changed), NULL);

        /* separator */
        gtk_list_store_append(model, &sep_it);

        vols = g_volume_monitor_get_volumes(vol_mon);
        for(l=vols;l;l=l->next)
        {
            GVolume* vol = G_VOLUME(l->data);
            add_vol(vol);
            g_object_unref(vol);
        }
        g_list_free(vols);

        bookmarks = fm_bookmarks_get(); /* bookmarks */
        g_signal_connect(bookmarks, "changed", G_CALLBACK(on_bookmarks_changed), NULL);
        add_bookmarks();
    }
    else
        g_object_ref(model);
}
Пример #5
0
static void fm_places_model_init(FmPlacesModel *self)
{
    GType types[] = {GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER};
    GtkTreeIter it;
    GtkTreePath* tp;
    FmPlaceItem* item;
    GList *vols, *l;
    GIcon* gicon;
    FmIcon* icon;
    GFile* gf;
    GdkPixbuf* pix;
    FmFileInfoJob* job = fm_file_info_job_new(NULL, FM_FILE_INFO_JOB_FOLLOW_SYMLINK);
    GtkListStore* model = GTK_LIST_STORE(self);

    gtk_list_store_set_column_types(GTK_LIST_STORE(self), FM_PLACES_MODEL_N_COLS, types);

    self->theme_change_handler = g_signal_connect_swapped(gtk_icon_theme_get_default(), "changed",
                                            G_CALLBACK(update_icons), self);

    self->use_trash_change_handler = g_signal_connect(fm_config, "changed::use_trash",
                                             G_CALLBACK(on_use_trash_changed), self);

    self->pane_icon_size_change_handler = g_signal_connect(fm_config, "changed::pane_icon_size",
                                             G_CALLBACK(on_pane_icon_size_changed), self);
    icon = fm_icon_from_name("media-eject");
    pix = fm_icon_get_pixbuf(icon, fm_config->pane_icon_size);
    fm_icon_unref(icon);
    self->eject_icon = pix;

    item = g_slice_new0(FmPlaceItem);
    item->type = FM_PLACES_ITEM_PATH;
    item->fi = fm_file_info_new();
    item->fi->path = fm_path_ref(fm_path_get_home());
    item->fi->icon = fm_icon_from_name("user-home");
    gtk_list_store_append(model, &it);
    pix = fm_icon_get_pixbuf(item->fi->icon, fm_config->pane_icon_size);
    gtk_list_store_set(model, &it, FM_PLACES_MODEL_COL_ICON, pix, FM_PLACES_MODEL_COL_LABEL, item->fi->path->name, FM_PLACES_MODEL_COL_INFO, item, -1);
    g_object_unref(pix);
    fm_file_info_job_add(job, item->fi->path);

    /* Only show desktop in side pane when the user has a desktop dir. */
    if(g_file_test(g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP), G_FILE_TEST_IS_DIR))
    {
        item = g_slice_new0(FmPlaceItem);
        item->type = FM_PLACES_ITEM_PATH;
        item->fi = fm_file_info_new();
        item->fi->path = fm_path_ref(fm_path_get_desktop());
        item->fi->icon = fm_icon_from_name("user-desktop");
        gtk_list_store_append(model, &it);
        pix = fm_icon_get_pixbuf(item->fi->icon, fm_config->pane_icon_size);
        gtk_list_store_set(model, &it, FM_PLACES_MODEL_COL_ICON, pix, FM_PLACES_MODEL_COL_LABEL, _("Desktop"), FM_PLACES_MODEL_COL_INFO, item, -1);
        g_object_unref(pix);
        fm_file_info_job_add(job, item->fi->path);
    }

    if(fm_config->use_trash)
        create_trash_item(self); /* FIXME: how to handle trash can? */

    item = g_slice_new0(FmPlaceItem);
    item->type = FM_PLACES_ITEM_PATH;
    item->fi = fm_file_info_new();
    item->fi->path = fm_path_ref(fm_path_get_apps_menu());
    item->fi->icon = fm_icon_from_name("system-software-install");
    gtk_list_store_append(model, &it);
    pix = fm_icon_get_pixbuf(item->fi->icon, fm_config->pane_icon_size);
    gtk_list_store_set(model, &it, FM_PLACES_MODEL_COL_ICON, pix, FM_PLACES_MODEL_COL_LABEL, _("Applications"), FM_PLACES_MODEL_COL_INFO, item, -1);
    g_object_unref(pix);
    /* fm_file_info_job_add(job, item->fi->path); */

    /* volumes */
    self->vol_mon = g_volume_monitor_get();
    g_signal_connect(self->vol_mon, "volume-added", G_CALLBACK(on_vol_added), self);
    g_signal_connect(self->vol_mon, "volume-removed", G_CALLBACK(on_vol_removed), self);
    g_signal_connect(self->vol_mon, "volume-changed", G_CALLBACK(on_vol_changed), self);
    g_signal_connect(self->vol_mon, "mount-added", G_CALLBACK(on_mount_added), self);

    /* separator */
    gtk_list_store_append(model, &self->sep_it);

    /* add volumes to side-pane */
    vols = g_volume_monitor_get_volumes(self->vol_mon);
    for(l=vols;l;l=l->next)
    {
        GVolume* vol = G_VOLUME(l->data);
        add_vol(self, vol, job);
        g_object_unref(vol);
    }
    g_list_free(vols);

    /* get the path of separator */
    self->sep_tp = gtk_tree_model_get_path(GTK_TREE_MODEL(self), &self->sep_it);

    self->bookmarks = fm_bookmarks_get(); /* bookmarks */
    g_signal_connect(self->bookmarks, "changed", G_CALLBACK(on_bookmarks_changed), self);

    /* add bookmarks to side pane */
    add_bookmarks(self, job);

    g_signal_connect(job, "finished", G_CALLBACK(on_file_info_job_finished), self);
    self->jobs = g_slist_prepend(self->jobs, job);
    fm_job_run_async(FM_JOB(job));
}
Пример #6
0
DesktopWindow::DesktopWindow(int screenNum):
  View(Fm::FolderView::IconMode),
  proxyModel_(NULL),
  model_(NULL),
  folder_(NULL),
  wallpaperMode_(WallpaperNone),
  fileLauncher_(NULL),
  showWmMenu_(false),
  screenNum_(screenNum),
  relayoutTimer_(NULL) {

  QDesktopWidget* desktopWidget = QApplication::desktop();
  setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
  setAttribute(Qt::WA_X11NetWmWindowTypeDesktop);
  setAttribute(Qt::WA_DeleteOnClose);

  // set our custom file launcher
  View::setFileLauncher(&fileLauncher_);

  listView_ = static_cast<Fm::FolderViewListView*>(childView());
  listView_->setMovement(QListView::Snap);
  listView_->setResizeMode(QListView::Adjust);
  listView_->setFlow(QListView::TopToBottom);

  // NOTE: When XRnadR is in use, the all screens are actually combined to form a
  // large virtual desktop and only one DesktopWindow needs to be created and screenNum is -1.
  // In some older multihead setups, such as xinerama, every physical screen
  // is treated as a separate desktop so many instances of DesktopWindow may be created.
  // In this case we only want to show desktop icons on the primary screen.
  if(desktopWidget->isVirtualDesktop() || screenNum_ == desktopWidget->primaryScreen()) {
    loadItemPositions();
    Settings& settings = static_cast<Application* >(qApp)->settings();

    model_ = Fm::CachedFolderModel::modelFromPath(fm_path_get_desktop());
    folder_ = reinterpret_cast<FmFolder*>(g_object_ref(model_->folder()));

    proxyModel_ = new Fm::ProxyFolderModel();
    proxyModel_->setSourceModel(model_);
    proxyModel_->setShowThumbnails(settings.showThumbnails());
    proxyModel_->sort(settings.desktopSortColumn(), settings.desktopSortOrder());
    proxyModel_->setFolderFirst(settings.desktopSortFolderFirst());
    setModel(proxyModel_);

    connect(proxyModel_, &Fm::ProxyFolderModel::rowsInserted, this, &DesktopWindow::onRowsInserted);
    connect(proxyModel_, &Fm::ProxyFolderModel::rowsAboutToBeRemoved, this, &DesktopWindow::onRowsAboutToBeRemoved);
    connect(proxyModel_, &Fm::ProxyFolderModel::layoutChanged, this, &DesktopWindow::onLayoutChanged);
    connect(proxyModel_, &Fm::ProxyFolderModel::sortFilterChanged, this, &DesktopWindow::onModelSortFilterChanged);
    connect(listView_, &QListView::indexesMoved, this, &DesktopWindow::onIndexesMoved);
  }

  // set our own delegate
  delegate_ = new DesktopItemDelegate(listView_);
  listView_->setItemDelegateForColumn(Fm::FolderModel::ColumnFileName, delegate_);

  // remove frame
  listView_->setFrameShape(QFrame::NoFrame);
  // inhibit scrollbars FIXME: this should be optional in the future
  listView_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  listView_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

  connect(this, &DesktopWindow::openDirRequested, this, &DesktopWindow::onOpenDirRequested);

  listView_->installEventFilter(this);

  // setup shortcuts
  QShortcut* shortcut;
  shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_X), this); // cut
  connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onCutActivated);

  shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_C), this); // copy
  connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onCopyActivated);

  shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_V), this); // paste
  connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onPasteActivated);

  shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_A), this); // select all
  connect(shortcut, &QShortcut::activated, listView_, &QListView::selectAll);

  shortcut = new QShortcut(QKeySequence(Qt::Key_Delete), this); // delete
  connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onDeleteActivated);

  shortcut = new QShortcut(QKeySequence(Qt::Key_F2), this); // rename
  connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onRenameActivated);

  shortcut = new QShortcut(QKeySequence(Qt::ALT + Qt::Key_Return), this); // rename
  connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onFilePropertiesActivated);

  shortcut = new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Delete), this); // force delete
  connect(shortcut, &QShortcut::activated, this, &DesktopWindow::onDeleteActivated);
}