/** * @file gnome-cmd-dir-indicator.cc * @copyright (C) 2001-2006 Marcus Bjurman\n * @copyright (C) 2007-2012 Piotr Eljasiak\n * @copyright (C) 2013-2023 Uwe Scholz\n * * @copyright This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * @copyright This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * @copyright You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "gnome-cmd-includes.h" #include "gnome-cmd-dir-indicator.h" #include "gnome-cmd-style.h" #include "gnome-cmd-file-selector.h" #include "gnome-cmd-main-win.h" #include "gnome-cmd-data.h" #include "gnome-cmd-user-actions.h" #include "dialogs/gnome-cmd-manage-bookmarks-dialog.h" #include "imageloader.h" #include "utils.h" using namespace std; struct GnomeCmdDirIndicatorPrivate { GtkWidget *event_box; GtkWidget *label; GtkWidget *history_button; GtkWidget *bookmark_button; GtkWidget *dir_history_popup; GtkWidget *bookmark_popup; gboolean history_is_popped; gboolean bookmark_is_popped; GnomeCmdFileSelector *fs; int *slashCharPosition; int *slashPixelPosition; int numPositions; }; static GtkFrameClass *parent_class = nullptr; /******************************* * Gtk class implementation *******************************/ static void destroy (GtkObject *object) { GnomeCmdDirIndicator *dir_indicator = GNOME_CMD_DIR_INDICATOR (object); g_free (dir_indicator->priv->slashCharPosition); g_free (dir_indicator->priv->slashPixelPosition); g_free (dir_indicator->priv); if (GTK_OBJECT_CLASS (parent_class)->destroy) (*GTK_OBJECT_CLASS (parent_class)->destroy) (object); } static void class_init (GnomeCmdDirIndicatorClass *klass) { GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass); parent_class = (GtkFrameClass *) gtk_type_class (gtk_frame_get_type ()); object_class->destroy = destroy; } static void set_clipboard_from_indicator(GnomeCmdDirIndicator *indicator, const gchar *labelText, GdkEventButton *event) { gchar *chTo = g_strdup (labelText); gint x = (gint) event->x; for (gint i=0; i < indicator->priv->numPositions; ++i) { if (x < indicator->priv->slashPixelPosition[i]) { chTo[indicator->priv->slashCharPosition[i]] = 0; gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), chTo, indicator->priv->slashCharPosition[i]); break; } } g_free (chTo); } static void change_dir_from_clicked_indicator(GdkEventButton *event, const gchar* chToDir, GnomeCmdFileSelector *fs) { main_win->switch_fs(fs); if (event->button==2 || event->state & GDK_CONTROL_MASK || fs->file_list()->locked) { GnomeCmdCon *con = fs->get_connection(); GnomeCmdDir *dir = gnome_cmd_dir_new (con, gnome_cmd_con_create_path (con, chToDir)); fs->new_tab(dir); } else { fs->goto_directory(chToDir); } } static gboolean handle_remote_indicator_clicked (GnomeCmdDirIndicator *indicator, GdkEventButton *event, GnomeCmdFileSelector *fs) { auto labelText = gtk_label_get_text (GTK_LABEL (indicator->priv->label)); auto colonPtr = strchr(labelText, ':'); auto colonIndex = (int)(colonPtr - labelText) + 1; // + 1 as we want to ignore "host:" until the colon if (event->button==1 || event->button==2) { // left click - work out the path auto chTo = g_strdup (colonPtr+1); auto x = (gint) event->x; for (gint slashIdx=0; slashIdx < indicator->priv->numPositions; ++slashIdx) { if (x < indicator->priv->slashPixelPosition[slashIdx]) { chTo[indicator->priv->slashCharPosition[slashIdx] - colonIndex] = 0; change_dir_from_clicked_indicator(event, chTo, fs); break; } } // pointer is after directory name - just return g_free (chTo); return TRUE; } else if (event->button==3) { set_clipboard_from_indicator(indicator, labelText, event); return TRUE; } return FALSE; } static gboolean handle_local_indicator_clicked (GnomeCmdDirIndicator *indicator, GdkEventButton *event, GnomeCmdFileSelector *fs) { auto labelText = gtk_label_get_text (GTK_LABEL (indicator->priv->label)); if (event->button==1 || event->button==2) { // left click - work out the path auto chTo = g_strdup (labelText); auto x = (gint) event->x; for (gint slashIdx = 0; slashIdx < indicator->priv->numPositions; ++slashIdx) { if (x < indicator->priv->slashPixelPosition[slashIdx]) { chTo[indicator->priv->slashCharPosition[slashIdx]] = 0; change_dir_from_clicked_indicator(event, chTo, fs); break; } } // pointer is after directory name - just return g_free (chTo); return TRUE; } else if (event->button==3) { set_clipboard_from_indicator(indicator, labelText, event); return TRUE; } return FALSE; } /******************************* * Event handlers *******************************/ static gboolean on_dir_indicator_clicked (GnomeCmdDirIndicator *indicator, GdkEventButton *event, GnomeCmdFileSelector *fs) { g_return_val_if_fail (GNOME_CMD_IS_DIR_INDICATOR (indicator), FALSE); if (event->type!=GDK_BUTTON_PRESS) return FALSE; const gchar *labelText = gtk_label_get_text (GTK_LABEL (indicator->priv->label)); if(strchr(labelText, ':')) { return handle_remote_indicator_clicked(indicator, event, fs); } else { return handle_local_indicator_clicked(indicator, event, fs); } } static gchar* update_markup_for_remote(GnomeCmdDirIndicator *indicator, gint slashIdx) { auto tmpLabelText = g_strdup (gtk_label_get_text (GTK_LABEL (indicator->priv->label))); auto colonPtr = strchr(tmpLabelText, ':'); if (!colonPtr) { g_free(tmpLabelText); return nullptr; } if (slashIdx == 0) { auto monoText = get_mono_text (tmpLabelText); g_free(tmpLabelText); return monoText; } auto colonIndex = (int)(colonPtr - tmpLabelText) + 1; // +1 as we want to ignore "host:" after the colon auto startText = g_strndup(tmpLabelText, colonIndex); auto startMonoText = get_mono_text (startText); auto middleText = slashIdx > 0 ? g_strndup(&tmpLabelText[colonIndex], indicator->priv->slashCharPosition[slashIdx] - colonIndex) : g_strdup(""); gchar *middleBoldText = get_bold_mono_text (middleText); gchar *restText = slashIdx > 0 ? g_strdup (&tmpLabelText[indicator->priv->slashCharPosition[slashIdx]]) : &tmpLabelText[colonIndex]; gchar *restMonoText = get_mono_text (restText); auto markupText = g_strconcat (startMonoText, middleBoldText, restMonoText, nullptr); g_free (startText); g_free (startMonoText); g_free (middleText); g_free (middleBoldText); g_free (restText); g_free (restMonoText); g_free (tmpLabelText); return markupText; } static gchar* update_markup_for_local(GnomeCmdDirIndicator *indicator, gint i) { auto tmpLabelText = g_strdup (gtk_label_get_text (GTK_LABEL (indicator->priv->label))); gchar *restText = g_strdup (&tmpLabelText[indicator->priv->slashCharPosition[i]]); tmpLabelText[indicator->priv->slashCharPosition[i]] = '\0'; gchar *boldMonoText = get_bold_mono_text (tmpLabelText); gchar *monoText = get_mono_text (restText); auto markupText = g_strconcat (boldMonoText, monoText, nullptr); g_free (restText); g_free (monoText); g_free (boldMonoText); g_free (tmpLabelText); return markupText; } static void update_markup (GnomeCmdDirIndicator *indicator, gint i) { if (!indicator->priv->slashCharPosition) return; gchar *tmpLabelText, *markupText; tmpLabelText = g_strdup (gtk_label_get_text (GTK_LABEL (indicator->priv->label))); if (i >= 0) { // If we are on a remote connection, there is a colon in the label auto colonPosition = strstr(tmpLabelText, ":"); if (colonPosition) { markupText = update_markup_for_remote(indicator, i); } else { markupText = update_markup_for_local(indicator, i); } } else markupText = get_mono_text (tmpLabelText); gtk_label_set_markup (GTK_LABEL (indicator->priv->label), markupText); g_free (tmpLabelText); g_free (markupText); } static gint on_dir_indicator_motion (GnomeCmdDirIndicator *indicator, GdkEventMotion *event, gpointer user_data) { g_return_val_if_fail (GNOME_CMD_IS_DIR_INDICATOR (indicator), FALSE); if (indicator->priv->slashCharPosition == nullptr) return FALSE; if (indicator->priv->slashPixelPosition == nullptr) return FALSE; // find out where in the label the pointer is at gint iX = (gint) event->x; for (gint i=0; i < indicator->priv->numPositions; i++) { if (iX < indicator->priv->slashPixelPosition[i]) { // underline the part that is selected GdkCursor *cursor = gdk_cursor_new (GDK_HAND2); gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (indicator)), cursor); gdk_cursor_unref (cursor); update_markup (indicator, i); return TRUE; } // clear underline, cursor=pointer update_markup (indicator, -1); gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (indicator)), nullptr); } return TRUE; } static gint on_dir_indicator_leave (GnomeCmdDirIndicator *indicator, GdkEventMotion *event, gpointer user_data) { g_return_val_if_fail (GNOME_CMD_IS_DIR_INDICATOR (indicator), FALSE); // clear underline, cursor=pointer update_markup (indicator, -1); gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (indicator)), nullptr); return TRUE; } static gboolean on_bookmark_button_clicked (GtkWidget *button, GnomeCmdDirIndicator *indicator) { if (indicator->priv->bookmark_is_popped) { gtk_widget_hide (indicator->priv->bookmark_popup); indicator->priv->bookmark_is_popped = FALSE; } else { gnome_cmd_dir_indicator_show_bookmarks (indicator); indicator->priv->bookmark_is_popped = TRUE; } return TRUE; } static gboolean on_history_button_clicked (GtkWidget *button, GnomeCmdDirIndicator *indicator) { if (indicator->priv->history_is_popped) { gtk_widget_hide (indicator->priv->dir_history_popup); indicator->priv->history_is_popped = FALSE; } else { gnome_cmd_dir_indicator_show_history (indicator); indicator->priv->history_is_popped = TRUE; } return TRUE; } static void on_dir_history_popup_hide (GtkMenu *menu, GnomeCmdDirIndicator *indicator) { indicator->priv->dir_history_popup = nullptr; indicator->priv->history_is_popped = FALSE; } static void on_bookmark_popup_hide (GtkMenu *menu, GnomeCmdDirIndicator *indicator) { indicator->priv->bookmark_popup = nullptr; indicator->priv->bookmark_is_popped = FALSE; } static void on_dir_history_item_selected (GtkMenuItem *item, const gchar *path) { g_return_if_fail (path != nullptr); GdkModifierType mask; gdk_window_get_pointer (nullptr, nullptr, nullptr, &mask); auto indicator = static_cast (g_object_get_data (G_OBJECT (item), "indicator")); g_return_if_fail (GNOME_CMD_IS_DIR_INDICATOR (indicator)); main_win->switch_fs(indicator->priv->fs); if (mask&GDK_CONTROL_MASK || indicator->priv->fs->file_list()->locked) { GnomeCmdCon *con = indicator->priv->fs->get_connection(); GnomeCmdDir *dir = gnome_cmd_dir_new (con, gnome_cmd_con_create_path (con, path)); indicator->priv->fs->new_tab(dir); } else indicator->priv->fs->goto_directory(path); } static void on_bookmark_item_selected (GtkMenuItem *item, GnomeCmdBookmark *bm) { g_return_if_fail (bm != nullptr); GdkModifierType mask; gdk_window_get_pointer (nullptr, nullptr, nullptr, &mask); auto indicator = static_cast (g_object_get_data (G_OBJECT (item), "indicator")); g_return_if_fail (GNOME_CMD_IS_DIR_INDICATOR (indicator)); main_win->switch_fs(indicator->priv->fs); if (mask&GDK_CONTROL_MASK || indicator->priv->fs->file_list()->locked) { GnomeCmdCon *con = indicator->priv->fs->get_connection(); GnomeCmdDir *dir = gnome_cmd_dir_new (con, gnome_cmd_con_create_path (con, bm->path)); indicator->priv->fs->new_tab(dir); } else indicator->priv->fs->goto_directory(bm->path); } static void get_popup_pos (GtkMenu *menu, gint *x, gint *y, gboolean push_in, GnomeCmdDirIndicator *indicator) { g_return_if_fail (GNOME_CMD_IS_DIR_INDICATOR (indicator)); GtkWidget *w = GTK_WIDGET (indicator->priv->fs->file_list()); gdk_window_get_origin (gtk_widget_get_window (w), x, y); } static void add_menu_item (GnomeCmdDirIndicator *indicator, GtkMenuShell *shell, const gchar *text, GtkSignalFunc func, gpointer data) { GtkWidget *item = text ? gtk_menu_item_new_with_label (text) : gtk_menu_item_new (); g_object_ref (item); g_object_set_data (G_OBJECT (item), "indicator", indicator); g_object_set_data_full (G_OBJECT (shell), "menu_item", item, g_object_unref); if (func) g_signal_connect (item, "activate", G_CALLBACK (func), data); gtk_widget_show (item); if (!text) gtk_widget_set_sensitive (item, FALSE); gtk_menu_shell_append (shell, item); } void gnome_cmd_dir_indicator_show_history (GnomeCmdDirIndicator *indicator) { if (indicator->priv->dir_history_popup) return; indicator->priv->dir_history_popup = gtk_menu_new (); g_object_ref (indicator->priv->dir_history_popup); g_object_set_data_full (G_OBJECT (indicator), "dir_history_popup", indicator->priv->dir_history_popup, g_object_unref); g_signal_connect (indicator->priv->dir_history_popup, "hide", G_CALLBACK (on_dir_history_popup_hide), indicator); GnomeCmdCon *con = indicator->priv->fs->get_connection(); History *history = gnome_cmd_con_get_dir_history (con); for (GList *l=history->ents; l; l=l->next) { gchar *path = (gchar *) l->data; add_menu_item (indicator, GTK_MENU_SHELL (indicator->priv->dir_history_popup), path, GTK_SIGNAL_FUNC (on_dir_history_item_selected), path); } gtk_menu_popup (GTK_MENU (indicator->priv->dir_history_popup), nullptr, nullptr, (GtkMenuPositionFunc) get_popup_pos, indicator, 0, gtk_get_current_event_time()); gint w = -1; GtkAllocation indicator_allocation; gtk_widget_get_allocation (GTK_WIDGET (indicator), &indicator_allocation); if (indicator_allocation.width > 100) w = indicator_allocation.width; gtk_widget_set_size_request (indicator->priv->dir_history_popup, w, -1); } static void on_bookmarks_add_current (GtkMenuItem *item, GnomeCmdDirIndicator *indicator) { gnome_cmd_bookmark_add_current (indicator->priv->fs->get_directory()); } static void on_bookmarks_manage (GtkMenuItem *item, GnomeCmdDirIndicator *indicator) { bookmarks_edit (nullptr, nullptr); } void gnome_cmd_dir_indicator_show_bookmarks (GnomeCmdDirIndicator *indicator) { if (indicator->priv->bookmark_popup) return; indicator->priv->bookmark_popup = gtk_menu_new (); g_object_ref (indicator->priv->bookmark_popup); g_object_set_data_full (G_OBJECT (indicator), "bookmark_popup", indicator->priv->bookmark_popup, g_object_unref); g_signal_connect (indicator->priv->bookmark_popup, "hide", G_CALLBACK (on_bookmark_popup_hide), indicator); GnomeCmdCon *con = indicator->priv->fs->get_connection(); GnomeCmdBookmarkGroup *group = gnome_cmd_con_get_bookmarks (con); for (GList *l = group->bookmarks; l; l = l->next) { auto bm = static_cast (l->data); add_menu_item (indicator, GTK_MENU_SHELL (indicator->priv->bookmark_popup), bm->name, GTK_SIGNAL_FUNC (on_bookmark_item_selected), bm); } add_menu_item (indicator, GTK_MENU_SHELL (indicator->priv->bookmark_popup), nullptr, nullptr, indicator); add_menu_item (indicator, GTK_MENU_SHELL (indicator->priv->bookmark_popup), _("Add current dir"), GTK_SIGNAL_FUNC (on_bookmarks_add_current), indicator); add_menu_item (indicator, GTK_MENU_SHELL (indicator->priv->bookmark_popup), _("Manage bookmarks…"), GTK_SIGNAL_FUNC (on_bookmarks_manage), indicator); gtk_menu_popup (GTK_MENU (indicator->priv->bookmark_popup), nullptr, nullptr, (GtkMenuPositionFunc) get_popup_pos, indicator, 0, gtk_get_current_event_time()); gint w = -1; GtkAllocation indicator_allocation; gtk_widget_get_allocation (GTK_WIDGET (indicator), &indicator_allocation); if (indicator_allocation.width > 100) w = indicator_allocation.width; gtk_widget_set_size_request (indicator->priv->bookmark_popup, w, -1); } static void init (GnomeCmdDirIndicator *indicator) { GtkWidget *hbox, *arrow, *bbox; indicator->priv = g_new0 (GnomeCmdDirIndicatorPrivate, 1); // below assignments are not necessary any longer due to above g_new0() // indicator->priv->dir_history_popup = nullptr; // indicator->priv->bookmark_popup = nullptr; // indicator->priv->history_is_popped = FALSE; // indicator->priv->slashCharPosition = nullptr; // indicator->priv->slashPixelPosition = nullptr; // indicator->priv->numPositions = 0; // create the directory label and its event box indicator->priv->event_box = gtk_event_box_new (); g_object_ref (indicator->priv->event_box); g_signal_connect_swapped (indicator->priv->event_box, "motion-notify-event", G_CALLBACK (on_dir_indicator_motion), indicator); g_signal_connect_swapped (indicator->priv->event_box, "leave-notify-event", G_CALLBACK (on_dir_indicator_leave), indicator); gtk_widget_set_events (indicator->priv->event_box, GDK_POINTER_MOTION_MASK); gtk_widget_show (indicator->priv->event_box); indicator->priv->label = create_label (GTK_WIDGET (indicator), "not initialized"); gtk_container_add (GTK_CONTAINER (indicator->priv->event_box), indicator->priv->label); // create the history popup button indicator->priv->history_button = gtk_button_new (); gtk_widget_set_can_focus (indicator->priv->history_button, FALSE); g_object_ref (indicator->priv->history_button); gtk_button_set_relief (GTK_BUTTON (indicator->priv->history_button), GTK_RELIEF_NONE); g_object_set_data_full (G_OBJECT (indicator), "button", indicator->priv->history_button, g_object_unref); gtk_widget_show (indicator->priv->history_button); arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT); g_object_ref (arrow); g_object_set_data_full (G_OBJECT (indicator), "arrow", arrow, g_object_unref); gtk_widget_show (arrow); gtk_container_add (GTK_CONTAINER (indicator->priv->history_button), arrow); // create the bookmark popup button indicator->priv->bookmark_button = create_styled_pixmap_button (nullptr, IMAGE_get_gnome_cmd_pixmap (PIXMAP_BOOKMARK)); gtk_widget_set_can_focus (indicator->priv->bookmark_button, FALSE); gtk_button_set_relief (GTK_BUTTON (indicator->priv->bookmark_button), GTK_RELIEF_NONE); g_object_set_data_full (G_OBJECT (indicator), "button", indicator->priv->bookmark_button, g_object_unref); gtk_widget_show (indicator->priv->bookmark_button); // pack hbox = create_hbox (GTK_WIDGET (indicator), FALSE, 10); gtk_container_add (GTK_CONTAINER (indicator), hbox); gtk_box_pack_start (GTK_BOX (hbox), indicator->priv->event_box, TRUE, TRUE, 0); bbox = create_hbox (GTK_WIDGET (indicator), FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), bbox, FALSE, TRUE, 0); gtk_box_pack_start (GTK_BOX (bbox), indicator->priv->bookmark_button, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (bbox), indicator->priv->history_button, FALSE, FALSE, 0); g_signal_connect (indicator->priv->history_button, "clicked", G_CALLBACK (on_history_button_clicked), indicator); g_signal_connect (indicator->priv->bookmark_button, "clicked", G_CALLBACK (on_bookmark_button_clicked), indicator); } /*********************************** * Public functions ***********************************/ GtkType gnome_cmd_dir_indicator_get_type () { static GtkType type = 0; if (type == 0) { GtkTypeInfo info = { (gchar*) "GnomeCmdDirIndicator", sizeof(GnomeCmdDirIndicator), sizeof(GnomeCmdDirIndicatorClass), (GtkClassInitFunc) class_init, (GtkObjectInitFunc) init, /* reserved_1 */ nullptr, /* reserved_2 */ nullptr, (GtkClassInitFunc) nullptr }; type = gtk_type_unique (gtk_frame_get_type (), &info); } return type; } GtkWidget *gnome_cmd_dir_indicator_new (GnomeCmdFileSelector *fs) { auto dir_indicator = static_cast (g_object_new (GNOME_CMD_TYPE_DIR_INDICATOR, nullptr)); g_signal_connect (dir_indicator, "button-press-event", G_CALLBACK (on_dir_indicator_clicked), fs); dir_indicator->priv->fs = fs; return GTK_WIDGET (dir_indicator); } static void update_slash_positions(GnomeCmdDirIndicator *indicator, const gchar* path) { g_free (indicator->priv->slashCharPosition); g_free (indicator->priv->slashPixelPosition); indicator->priv->numPositions = 0; indicator->priv->slashCharPosition = nullptr; indicator->priv->slashPixelPosition = nullptr; if (!path) return; gboolean isUNC = g_str_has_prefix (path, "\\\\"); if (!isUNC && (*path!=G_DIR_SEPARATOR && !strstr(path, ":"))) return; const gchar sep = isUNC ? '\\' : G_DIR_SEPARATOR; GArray *sepPositions = g_array_sized_new (FALSE, FALSE, sizeof(gint), 16); gchar *tmpPath = get_utf8 (path); for (tmpPath = isUNC ? (gchar*) path+2 : (gchar*) path+1; *tmpPath; ++tmpPath) { if (*tmpPath == sep) { gint i = tmpPath - path; g_array_append_val (sepPositions, i); } } gint path_len = tmpPath - path; // allocate memory for storing (back)slashes positions // (both char positions within the string and their pixel positions in the display) // now there will be pos->len entries for UNC: // [0..pos->len-2] is '\\host\share\dir' etc. // last entry [pos->len-1] will be the whole UNC // pos->len+1 (1) entries for '/' (root): // last entry [pos->len] will be the whole path ('/') // and pos->len+2 entries otherwise: // first entry [0] is just '/' (root) // [1..pos->len] is '/dir/dir' etc. // last entry [pos->len+1] will be the whole path indicator->priv->numPositions = isUNC ? sepPositions->len : path_len==1 ? sepPositions->len+1 : sepPositions->len+2; indicator->priv->slashCharPosition = g_new (gint, indicator->priv->numPositions); indicator->priv->slashPixelPosition = g_new (gint, indicator->priv->numPositions); gint pos_idx = 0; if (!isUNC && path_len>1) { indicator->priv->slashCharPosition[pos_idx] = 1; //auto colonPtr = strchr(path, ':'); //colonPtr = colonPtr ? colonPtr : path; //auto startLength = (int)(colonPtr - path) + 1; // +1 as we want to ignore "host:" //indicator->priv->slashPixelPosition[pos_idx++] = get_string_pixel_size (path, startLength); indicator->priv->slashPixelPosition[pos_idx++] = get_string_pixel_size (path, 1); } for (guint ii = isUNC ? 1 : 0; ii < sepPositions->len; ii++) { indicator->priv->slashCharPosition[pos_idx] = g_array_index (sepPositions, gint, ii); indicator->priv->slashPixelPosition[pos_idx++] = get_string_pixel_size (path, g_array_index (sepPositions, gint, ii)+1); } if (indicator->priv->numPositions>0) { indicator->priv->slashCharPosition[pos_idx] = path_len; indicator->priv->slashPixelPosition[pos_idx] = get_string_pixel_size (path, path_len); } g_array_free (sepPositions, TRUE); } void gnome_cmd_dir_indicator_set_dir (GnomeCmdDirIndicator *indicator, GnomeCmdDir *dir) { gchar *path = gnome_cmd_dir_get_display_path (dir); g_return_if_fail (path != nullptr); gchar* host = nullptr; // show host in dir indicator if we are not on a local connection if (!gnome_cmd_dir_is_local(dir)) { GError *error = nullptr; auto dirUri = g_file_get_uri(GNOME_CMD_FILE(dir)->gFile); auto gUri = g_uri_parse(dirUri, G_URI_FLAGS_NONE, &error); if (error) { g_warning("g_uri_parse error %s: %s", dirUri, error->message); g_error_free(error); } else { host = g_strdup(g_uri_get_host(gUri)); } g_free(dirUri); } gchar *tmpPath = get_utf8 (path); gchar *indicatorString = host ? g_strdup_printf("%s:%s", host, tmpPath) : g_strdup_printf("%s", tmpPath); g_free (tmpPath); gchar *monoIndicatorString = get_mono_text (indicatorString); gtk_label_set_markup (GTK_LABEL (indicator->priv->label), monoIndicatorString); g_free (monoIndicatorString); update_markup (indicator, -1); update_slash_positions(indicator, indicatorString); g_free(indicatorString); g_free(path); } void gnome_cmd_dir_indicator_set_active (GnomeCmdDirIndicator *indicator, gboolean active) { switch (active) { case true: { auto tmpLabelText = g_strdup (gtk_label_get_text (GTK_LABEL (indicator->priv->label))); gchar *result = g_strdup_printf("%s", tmpLabelText); gtk_label_set_markup (GTK_LABEL (indicator->priv->label), result); g_free (tmpLabelText); break; } case false: { auto tmpLabelText = g_strdup (gtk_label_get_text (GTK_LABEL (indicator->priv->label))); gchar *result = g_strdup_printf("%s", tmpLabelText); gtk_label_set_markup (GTK_LABEL (indicator->priv->label), result); g_free (tmpLabelText); break; } } }