DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (5b81998bb7ab)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <stdio.h>
#include <gtk/gtk.h>
#include <unistd.h>
#include "progressui.h"
#include "readstrings.h"
#include "errors.h"

#define TIMER_INTERVAL 100

static float    sProgressVal;  // between 0 and 100
static gboolean sQuit = FALSE;
static gboolean sEnableUI;
static guint    sTimerID;

static GtkWidget *sWin;
static GtkWidget *sLabel;
static GtkWidget *sProgressBar;

static const char *sProgramPath;

static gboolean
UpdateDialog(gpointer data)
{
  if (sQuit)
  {
    gtk_widget_hide(sWin);
    gtk_main_quit();
  }

  float progress = sProgressVal;

  gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(sProgressBar),
                                progress / 100.0);

  return TRUE;
}

static gboolean
OnDeleteEvent(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
  return TRUE;
}

int
InitProgressUI(int *pargc, char ***pargv)
{
  sProgramPath = (*pargv)[0];

  sEnableUI = gtk_init_check(pargc, pargv);
  return 0;
}

int
ShowProgressUI()
{
  if (!sEnableUI)
    return -1;

  // Only show the Progress UI if the process is taking a significant amount of
  // time where a significant amount of time is defined as .5 seconds after
  // ShowProgressUI is called sProgress is less than 70.
  usleep(500000);

  if (sQuit || sProgressVal > 70.0f)
    return 0;

  char ini_path[PATH_MAX];
  snprintf(ini_path, sizeof(ini_path), "%s.ini", sProgramPath);

  StringTable strings;
  if (ReadStrings(ini_path, &strings) != OK)
    return -1;

  sWin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  if (!sWin)
    return -1;

  static GdkPixbuf *pixbuf;
  char icon_path[PATH_MAX];
  snprintf(icon_path, sizeof(icon_path), "%s.png", sProgramPath);

  g_signal_connect(G_OBJECT(sWin), "delete_event",
                   G_CALLBACK(OnDeleteEvent), NULL);

  gtk_window_set_title(GTK_WINDOW(sWin), strings.title);
  gtk_window_set_type_hint(GTK_WINDOW(sWin), GDK_WINDOW_TYPE_HINT_DIALOG);
  gtk_window_set_position(GTK_WINDOW(sWin), GTK_WIN_POS_CENTER_ALWAYS);
  gtk_window_set_resizable(GTK_WINDOW(sWin), FALSE);
  gtk_window_set_decorated(GTK_WINDOW(sWin), TRUE);
  gtk_window_set_deletable(GTK_WINDOW(sWin),FALSE);
  pixbuf = gdk_pixbuf_new_from_file (icon_path, NULL);
  gtk_window_set_icon(GTK_WINDOW(sWin), pixbuf);
  g_object_unref(pixbuf);

  GtkWidget *vbox = gtk_vbox_new(TRUE, 6);
  sLabel = gtk_label_new(strings.info);
  gtk_misc_set_alignment(GTK_MISC(sLabel), 0.0f, 0.0f);
  sProgressBar = gtk_progress_bar_new();

  gtk_box_pack_start(GTK_BOX(vbox), sLabel, FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(vbox), sProgressBar, TRUE, TRUE, 0);

  sTimerID = g_timeout_add(TIMER_INTERVAL, UpdateDialog, NULL);

  gtk_container_set_border_width(GTK_CONTAINER(sWin), 10);
  gtk_container_add(GTK_CONTAINER(sWin), vbox);
  gtk_widget_show_all(sWin);

  gtk_main();
  return 0;
}

// Called on a background thread
void
QuitProgressUI()
{
  sQuit = TRUE;
}

// Called on a background thread
void
UpdateProgressUI(float progress)
{
  sProgressVal = progress;  // 32-bit writes are atomic
}