ClipIt-v1.3.2-22112010001
+ Fixed: Fixed most of the markup and indentation (replaced double spaces with tabs). + Fixed: Removed clipboard restoring from history, as this seems to cause more problems than it solves.
This commit is contained in:
parent
cba465c964
commit
85d1ec0416
@ -1,3 +1,9 @@
|
||||
ClipIt-v1.3.2-22112010001 - 22 Nov. 2010
|
||||
+ Fixed: Fixed most of the markup and indentation (replaced double spaces
|
||||
with tabs).
|
||||
+ Fixed: Removed clipboard restoring from history, as this seems to cause
|
||||
more problems than it solves.
|
||||
|
||||
ClipIt-v1.3.1-17112010001 - 17 Nov. 2010
|
||||
+ Added: Added autostart support for LXDE.
|
||||
+ Fixed: Fixed problem with "Edit" window not appearing.
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Autoconf/automake.
|
||||
# -------------------------------------------------------------------------------
|
||||
AC_PREREQ([2.5])
|
||||
AC_INIT([clipit], [1.3.1], [oss@web-tm.com])
|
||||
AC_INIT([clipit], [1.3.2], [oss@web-tm.com])
|
||||
AM_INIT_AUTOMAKE([AC_PACKAGE_TARNAME()], [AC_PACKAGE_VERSION()])
|
||||
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
133
src/daemon.c
133
src/daemon.c
@ -12,11 +12,11 @@
|
||||
*
|
||||
* ClipIt 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
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
@ -25,92 +25,89 @@
|
||||
|
||||
|
||||
static gint timeout_id;
|
||||
static gchar* primary_text;
|
||||
static gchar* clipboard_text;
|
||||
static GtkClipboard* primary;
|
||||
static GtkClipboard* clipboard;
|
||||
static gchar *primary_text;
|
||||
static gchar *clipboard_text;
|
||||
static GtkClipboard *primary;
|
||||
static GtkClipboard *clipboard;
|
||||
|
||||
|
||||
/* Called during the daemon loop to protect primary/clipboard contents */
|
||||
static void
|
||||
daemon_check()
|
||||
static void daemon_check()
|
||||
{
|
||||
/* Get current primary/clipboard contents */
|
||||
gchar* primary_temp = gtk_clipboard_wait_for_text(primary);
|
||||
gchar* clipboard_temp = gtk_clipboard_wait_for_text(clipboard);
|
||||
/* Check if primary contents were lost */
|
||||
if ((primary_temp == NULL) && (primary_text != NULL))
|
||||
{
|
||||
/* Check contents */
|
||||
gint count;
|
||||
/* Get current primary/clipboard contents */
|
||||
gchar *primary_temp = gtk_clipboard_wait_for_text(primary);
|
||||
gchar *clipboard_temp = gtk_clipboard_wait_for_text(clipboard);
|
||||
/* Check if primary contents were lost */
|
||||
if ((primary_temp == NULL) && (primary_text != NULL))
|
||||
{
|
||||
/* Check contents */
|
||||
gint count;
|
||||
GdkAtom *targets;
|
||||
gboolean contents = gtk_clipboard_wait_for_targets(primary, &targets, &count);
|
||||
g_free(targets);
|
||||
/* Only recover lost contents if there isn't any other type of content in the clipboard */
|
||||
if (!contents)
|
||||
gtk_clipboard_set_text(primary, primary_text, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get the button state to check if the mouse button is being held */
|
||||
GdkModifierType button_state;
|
||||
gdk_window_get_pointer(NULL, NULL, NULL, &button_state);
|
||||
if ((primary_temp != NULL) && !(button_state & GDK_BUTTON1_MASK))
|
||||
{
|
||||
g_free(primary_text);
|
||||
primary_text = g_strdup(primary_temp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if clipboard contents were lost */
|
||||
if ((clipboard_temp == NULL) && (clipboard_text != NULL))
|
||||
{
|
||||
/* Check contents */
|
||||
gint count;
|
||||
gtk_clipboard_set_text(primary, primary_text, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get the button state to check if the mouse button is being held */
|
||||
GdkModifierType button_state;
|
||||
gdk_window_get_pointer(NULL, NULL, NULL, &button_state);
|
||||
if ((primary_temp != NULL) && !(button_state & GDK_BUTTON1_MASK))
|
||||
{
|
||||
g_free(primary_text);
|
||||
primary_text = g_strdup(primary_temp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if clipboard contents were lost */
|
||||
if ((clipboard_temp == NULL) && (clipboard_text != NULL))
|
||||
{
|
||||
/* Check contents */
|
||||
gint count;
|
||||
GdkAtom *targets;
|
||||
gboolean contents = gtk_clipboard_wait_for_targets(primary, &targets, &count);
|
||||
g_free(targets);
|
||||
/* Only recover lost contents if there isn't any other type of content in the clipboard */
|
||||
if (!contents)
|
||||
gtk_clipboard_set_text(clipboard, clipboard_text, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free(clipboard_text);
|
||||
clipboard_text = g_strdup(clipboard_temp);
|
||||
}
|
||||
g_free(primary_temp);
|
||||
g_free(clipboard_temp);
|
||||
gtk_clipboard_set_text(clipboard, clipboard_text, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free(clipboard_text);
|
||||
clipboard_text = g_strdup(clipboard_temp);
|
||||
}
|
||||
g_free(primary_temp);
|
||||
g_free(clipboard_temp);
|
||||
}
|
||||
|
||||
/* Called if timeout was destroyed */
|
||||
static void
|
||||
reset_daemon(gpointer data)
|
||||
static void reset_daemon(gpointer data)
|
||||
{
|
||||
if (timeout_id != 0)
|
||||
g_source_remove(timeout_id);
|
||||
/* Add the daemon loop */
|
||||
timeout_id = g_timeout_add_full(G_PRIORITY_LOW,
|
||||
DAEMON_INTERVAL,
|
||||
(GSourceFunc)daemon_check,
|
||||
NULL,
|
||||
(GDestroyNotify)reset_daemon);
|
||||
if (timeout_id != 0)
|
||||
g_source_remove(timeout_id);
|
||||
/* Add the daemon loop */
|
||||
timeout_id = g_timeout_add_full(G_PRIORITY_LOW,
|
||||
DAEMON_INTERVAL,
|
||||
(GSourceFunc)daemon_check,
|
||||
NULL,
|
||||
(GDestroyNotify)reset_daemon);
|
||||
}
|
||||
|
||||
/* Initializes daemon mode */
|
||||
void
|
||||
init_daemon_mode()
|
||||
void init_daemon_mode()
|
||||
{
|
||||
/* Create clipboard and primary and connect signals */
|
||||
primary = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
|
||||
clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
|
||||
/* Add the daemon loop */
|
||||
timeout_id = g_timeout_add_full(G_PRIORITY_LOW,
|
||||
DAEMON_INTERVAL,
|
||||
(GSourceFunc)daemon_check,
|
||||
NULL,
|
||||
(GDestroyNotify)reset_daemon);
|
||||
|
||||
/* Start daemon loop */
|
||||
gtk_main();
|
||||
/* Create clipboard and primary and connect signals */
|
||||
primary = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
|
||||
clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
|
||||
/* Add the daemon loop */
|
||||
timeout_id = g_timeout_add_full(G_PRIORITY_LOW,
|
||||
DAEMON_INTERVAL,
|
||||
(GSourceFunc)daemon_check,
|
||||
NULL,
|
||||
(GDestroyNotify)reset_daemon);
|
||||
|
||||
/* Start daemon loop */
|
||||
gtk_main();
|
||||
}
|
||||
|
@ -12,11 +12,11 @@
|
||||
*
|
||||
* ClipIt 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
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DAEMON_H
|
||||
@ -26,8 +26,7 @@ G_BEGIN_DECLS
|
||||
|
||||
#define DAEMON_INTERVAL 500
|
||||
|
||||
void
|
||||
init_daemon_mode();
|
||||
void init_daemon_mode();
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
*
|
||||
* This library 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
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
|
294
src/history.c
294
src/history.c
@ -12,11 +12,11 @@
|
||||
*
|
||||
* ClipIt 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
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
@ -26,178 +26,174 @@
|
||||
#include "utils.h"
|
||||
#include "history.h"
|
||||
|
||||
GSList* history;
|
||||
GSList *history;
|
||||
|
||||
/* Reads history from ~/.local/share/clipit/history */
|
||||
void
|
||||
read_history ()
|
||||
void read_history ()
|
||||
{
|
||||
/* Build file path */
|
||||
gchar* history_path = g_build_filename(g_get_home_dir(),
|
||||
HISTORY_FILE,
|
||||
NULL);
|
||||
|
||||
/* Open the file for reading */
|
||||
FILE* history_file = fopen(history_path, "rb");
|
||||
g_free(history_path);
|
||||
/* Check that it opened and begin read */
|
||||
if (history_file)
|
||||
{
|
||||
/* Read the size of the first item */
|
||||
gint size;
|
||||
if (fread(&size, 4, 1, history_file) != 1)
|
||||
size = 0;
|
||||
/* Continue reading until size is 0 */
|
||||
while (size)
|
||||
{
|
||||
/* Malloc according to the size of the item */
|
||||
gchar* item = (gchar*)g_malloc(size + 1);
|
||||
/* Read item and add ending character */
|
||||
size_t fread_return;
|
||||
fread_return = fread(item, size, 1, history_file);
|
||||
item[size] = '\0';
|
||||
/* Prepend item and read next size */
|
||||
history = g_slist_prepend(history, item);
|
||||
if (fread(&size, 4, 1, history_file) != 1)
|
||||
size = 0;
|
||||
}
|
||||
/* Close file and reverse the history to normal */
|
||||
fclose(history_file);
|
||||
history = g_slist_reverse(history);
|
||||
}
|
||||
/* Build file path */
|
||||
gchar *history_path = g_build_filename(g_get_home_dir(),
|
||||
HISTORY_FILE,
|
||||
NULL);
|
||||
|
||||
/* Open the file for reading */
|
||||
FILE *history_file = fopen(history_path, "rb");
|
||||
g_free(history_path);
|
||||
/* Check that it opened and begin read */
|
||||
if (history_file)
|
||||
{
|
||||
/* Read the size of the first item */
|
||||
gint size;
|
||||
if (fread(&size, 4, 1, history_file) != 1)
|
||||
size = 0;
|
||||
/* Continue reading until size is 0 */
|
||||
while (size)
|
||||
{
|
||||
/* Malloc according to the size of the item */
|
||||
gchar *item = (gchar*)g_malloc(size + 1);
|
||||
/* Read item and add ending character */
|
||||
size_t fread_return;
|
||||
fread_return = fread(item, size, 1, history_file);
|
||||
item[size] = '\0';
|
||||
/* Prepend item and read next size */
|
||||
history = g_slist_prepend(history, item);
|
||||
if (fread(&size, 4, 1, history_file) != 1)
|
||||
size = 0;
|
||||
}
|
||||
/* Close file and reverse the history to normal */
|
||||
fclose(history_file);
|
||||
history = g_slist_reverse(history);
|
||||
}
|
||||
}
|
||||
|
||||
/* Saves history to ~/.local/share/clipit/history */
|
||||
void
|
||||
save_history()
|
||||
void save_history()
|
||||
{
|
||||
/* Check that the directory is available */
|
||||
check_dirs();
|
||||
/* Build file path */
|
||||
gchar* history_path = g_build_filename(g_get_home_dir(),
|
||||
HISTORY_FILE,
|
||||
NULL);
|
||||
/* Open the file for writing */
|
||||
FILE* history_file = fopen(history_path, "wb");
|
||||
g_free(history_path);
|
||||
/* Check that it opened and begin write */
|
||||
if (history_file)
|
||||
{
|
||||
GSList* element;
|
||||
/* Write each element to a binary file */
|
||||
for (element = history; element != NULL; element = element->next)
|
||||
{
|
||||
/* Create new GString from element data, write its length (size)
|
||||
* to file followed by the element data itself
|
||||
*/
|
||||
GString* item = g_string_new((gchar*)element->data);
|
||||
fwrite(&(item->len), 4, 1, history_file);
|
||||
fputs(item->str, history_file);
|
||||
g_string_free(item, TRUE);
|
||||
}
|
||||
/* Write 0 to indicate end of file */
|
||||
gint end = 0;
|
||||
fwrite(&end, 4, 1, history_file);
|
||||
fclose(history_file);
|
||||
}
|
||||
/* Check that the directory is available */
|
||||
check_dirs();
|
||||
/* Build file path */
|
||||
gchar *history_path = g_build_filename(g_get_home_dir(),
|
||||
HISTORY_FILE,
|
||||
NULL);
|
||||
/* Open the file for writing */
|
||||
FILE *history_file = fopen(history_path, "wb");
|
||||
g_free(history_path);
|
||||
/* Check that it opened and begin write */
|
||||
if (history_file)
|
||||
{
|
||||
GSList *element;
|
||||
/* Write each element to a binary file */
|
||||
for (element = history; element != NULL; element = element->next)
|
||||
{
|
||||
/* Create new GString from element data, write its
|
||||
* length (size) to file followed by the element
|
||||
* data itself
|
||||
*/
|
||||
GString *item = g_string_new((gchar*)element->data);
|
||||
fwrite(&(item->len), 4, 1, history_file);
|
||||
fputs(item->str, history_file);
|
||||
g_string_free(item, TRUE);
|
||||
}
|
||||
/* Write 0 to indicate end of file */
|
||||
gint end = 0;
|
||||
fwrite(&end, 4, 1, history_file);
|
||||
fclose(history_file);
|
||||
}
|
||||
}
|
||||
|
||||
/* Checks if item should be included in history and calls append */
|
||||
void
|
||||
check_and_append(gchar* item)
|
||||
void check_and_append(gchar *item)
|
||||
{
|
||||
if (item)
|
||||
{
|
||||
/* if item is too big, we don't include it in the history */
|
||||
if(strlen(item) > ENTRY_MAX_SIZE)
|
||||
return;
|
||||
GtkClipboard* clip = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
|
||||
/* Prepend new item */
|
||||
/* Check if we have URIs */
|
||||
gchar **arr = gtk_clipboard_wait_for_uris(clip);
|
||||
if(arr != NULL) {
|
||||
/* We have URIs */
|
||||
if(!prefs.save_uris)
|
||||
return;
|
||||
}
|
||||
g_strfreev(arr);
|
||||
if(!is_excluded(item))
|
||||
{
|
||||
append_item(item);
|
||||
}
|
||||
}
|
||||
if (item)
|
||||
{
|
||||
/* if item is too big, we don't include it in the history */
|
||||
if(strlen(item) > ENTRY_MAX_SIZE)
|
||||
return;
|
||||
GtkClipboard *clip = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
|
||||
/* Prepend new item */
|
||||
/* Check if we have URIs */
|
||||
gchar **arr = gtk_clipboard_wait_for_uris(clip);
|
||||
if(arr != NULL) {
|
||||
/* We have URIs */
|
||||
if(!prefs.save_uris)
|
||||
return;
|
||||
}
|
||||
g_strfreev(arr);
|
||||
if(!is_excluded(item))
|
||||
{
|
||||
append_item(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Adds item to the end of history */
|
||||
void
|
||||
append_item(gchar* item)
|
||||
void append_item(gchar *item)
|
||||
{
|
||||
history = g_slist_prepend(history, g_strdup(item));
|
||||
/* Shorten history if necessary */
|
||||
GSList* last_possible_element = g_slist_nth(history, prefs.history_limit - 1);
|
||||
if (last_possible_element)
|
||||
{
|
||||
/* Free last posible element and subsequent elements */
|
||||
g_slist_free(last_possible_element->next);
|
||||
last_possible_element->next = NULL;
|
||||
}
|
||||
/* Save changes */
|
||||
if (prefs.save_history)
|
||||
save_history();
|
||||
history = g_slist_prepend(history, g_strdup(item));
|
||||
/* Shorten history if necessary */
|
||||
GSList *last_possible_element = g_slist_nth(history,
|
||||
prefs.history_limit - 1);
|
||||
if (last_possible_element)
|
||||
{
|
||||
/* Free last posible element and subsequent elements */
|
||||
g_slist_free(last_possible_element->next);
|
||||
last_possible_element->next = NULL;
|
||||
}
|
||||
/* Save changes */
|
||||
if (prefs.save_history)
|
||||
save_history();
|
||||
}
|
||||
|
||||
/* Truncates history to history_limit items */
|
||||
void
|
||||
truncate_history()
|
||||
void truncate_history()
|
||||
{
|
||||
if (history)
|
||||
{
|
||||
/* Shorten history if necessary */
|
||||
GSList* last_possible_element = g_slist_nth(history, prefs.history_limit - 1);
|
||||
if (last_possible_element)
|
||||
{
|
||||
/* Free last posible element and subsequent elements */
|
||||
g_slist_free(last_possible_element->next);
|
||||
last_possible_element->next = NULL;
|
||||
}
|
||||
/* Save changes */
|
||||
if (prefs.save_history)
|
||||
save_history();
|
||||
}
|
||||
if (history)
|
||||
{
|
||||
/* Shorten history if necessary */
|
||||
GSList *last_possible_element = g_slist_nth(history,
|
||||
prefs.history_limit - 1);
|
||||
if (last_possible_element)
|
||||
{
|
||||
/* Free last posible element and subsequent elements */
|
||||
g_slist_free(last_possible_element->next);
|
||||
last_possible_element->next = NULL;
|
||||
}
|
||||
/* Save changes */
|
||||
if (prefs.save_history)
|
||||
save_history();
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns pointer to last item in history */
|
||||
gpointer
|
||||
get_last_item()
|
||||
gpointer get_last_item()
|
||||
{
|
||||
if (history)
|
||||
{
|
||||
if (history->data)
|
||||
{
|
||||
/* Return the last element */
|
||||
gpointer last_item = history->data;
|
||||
return last_item;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
if (history)
|
||||
{
|
||||
if (history->data)
|
||||
{
|
||||
/* Return the last element */
|
||||
gpointer last_item = history->data;
|
||||
return last_item;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Deletes duplicate item in history */
|
||||
void
|
||||
delete_duplicate(gchar* item)
|
||||
void delete_duplicate(gchar *item)
|
||||
{
|
||||
GSList* element;
|
||||
/* Go through each element compare each */
|
||||
for (element = history; element != NULL; element = element->next)
|
||||
{
|
||||
if (g_strcmp0((gchar*)element->data, item) == 0)
|
||||
{
|
||||
g_free(element->data);
|
||||
history = g_slist_delete_link(history, element);
|
||||
break;
|
||||
}
|
||||
}
|
||||
GSList *element;
|
||||
/* Go through each element compare each */
|
||||
for (element = history; element != NULL; element = element->next)
|
||||
{
|
||||
if (g_strcmp0((gchar*)element->data, item) == 0)
|
||||
{
|
||||
g_free(element->data);
|
||||
history = g_slist_delete_link(history, element);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,11 +12,11 @@
|
||||
*
|
||||
* ClipIt 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
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef HISTORY_H
|
||||
@ -25,6 +25,7 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define HISTORY_FILE ".local/share/clipit/history"
|
||||
|
||||
/* Set maximum size of one clipboard entry to 1024KB (1MB)
|
||||
* 1024 pages × 2000 characters per page - should be more than enough.
|
||||
* WARNING: if you use all 1000 history items, clipit could use up to
|
||||
@ -33,26 +34,19 @@ G_BEGIN_DECLS
|
||||
|
||||
extern GSList* history;
|
||||
|
||||
void
|
||||
read_history();
|
||||
void read_history();
|
||||
|
||||
void
|
||||
save_history();
|
||||
void save_history();
|
||||
|
||||
void
|
||||
check_and_append(gchar* item);
|
||||
void check_and_append(gchar* item);
|
||||
|
||||
void
|
||||
append_item(gchar* item);
|
||||
void append_item(gchar* item);
|
||||
|
||||
void
|
||||
truncate_history();
|
||||
void truncate_history();
|
||||
|
||||
gpointer
|
||||
get_last_item();
|
||||
gpointer get_last_item();
|
||||
|
||||
void
|
||||
delete_duplicate(gchar* item);
|
||||
void delete_duplicate(gchar* item);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
137
src/main.c
137
src/main.c
@ -12,11 +12,11 @@
|
||||
*
|
||||
* ClipIt 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
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -55,8 +55,7 @@ prefs_t prefs = {DEF_USE_COPY, DEF_USE_PRIMARY, DEF_SYNCHRONIZE,
|
||||
INIT_MENU_KEY, INIT_SEARCH_KEY, DEF_NO_ICON};
|
||||
|
||||
/* Called every CHECK_INTERVAL seconds to check for new items */
|
||||
static gboolean
|
||||
item_check(gpointer data)
|
||||
static gboolean item_check(gpointer data)
|
||||
{
|
||||
/* Grab the current primary and clipboard text */
|
||||
gchar* primary_temp = gtk_clipboard_wait_for_text(primary);
|
||||
@ -80,12 +79,13 @@ item_check(gpointer data)
|
||||
/* if use_primary is enabled, we restore from primary */
|
||||
gtk_clipboard_set_text(primary, primary_text, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* else, we restore from history */
|
||||
GSList* element = g_slist_nth(history, 0);
|
||||
gtk_clipboard_set_text(primary, (gchar*)element->data, -1);
|
||||
}
|
||||
/* else
|
||||
* {
|
||||
* /* else, we restore from history
|
||||
* GSList* element = g_slist_nth(history, 0);
|
||||
* gtk_clipboard_set_text(primary, (gchar*)element->data, -1);
|
||||
* }
|
||||
*/
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -186,8 +186,7 @@ item_check(gpointer data)
|
||||
}
|
||||
|
||||
/* Thread function called for each action performed */
|
||||
static void *
|
||||
execute_action(void *command)
|
||||
static void *execute_action(void *command)
|
||||
{
|
||||
/* Execute action */
|
||||
int sys_return;
|
||||
@ -210,8 +209,7 @@ execute_action(void *command)
|
||||
}
|
||||
|
||||
/* Called when execution action exits */
|
||||
static void
|
||||
action_exit(GPid pid, gint status, gpointer data)
|
||||
static void action_exit(GPid pid, gint status, gpointer data)
|
||||
{
|
||||
g_spawn_close_pid(pid);
|
||||
if (!prefs.no_icon)
|
||||
@ -223,8 +221,7 @@ action_exit(GPid pid, gint status, gpointer data)
|
||||
}
|
||||
|
||||
/* Called when an action is selected from actions menu */
|
||||
static void
|
||||
action_selected(GtkButton *button, gpointer user_data)
|
||||
static void action_selected(GtkButton *button, gpointer user_data)
|
||||
{
|
||||
/* Change icon and enable lock */
|
||||
actions_lock = TRUE;
|
||||
@ -255,8 +252,7 @@ action_selected(GtkButton *button, gpointer user_data)
|
||||
}
|
||||
|
||||
/* Called when Edit Actions is selected from actions menu */
|
||||
static void
|
||||
edit_actions_selected(GtkButton *button, gpointer user_data)
|
||||
static void edit_actions_selected(GtkButton *button, gpointer user_data)
|
||||
{
|
||||
/* This helps prevent multiple instances */
|
||||
if (!gtk_grab_get_current())
|
||||
@ -275,8 +271,7 @@ item_selected(GtkMenuItem *menu_item, gpointer user_data)
|
||||
}
|
||||
|
||||
/* Called when Clear is selected from history menu */
|
||||
static void
|
||||
clear_selected(GtkMenuItem *menu_item, gpointer user_data)
|
||||
static void clear_selected(GtkMenuItem *menu_item, gpointer user_data)
|
||||
{
|
||||
/* Check for confirm clear option */
|
||||
if (prefs.confirm_clear)
|
||||
@ -323,8 +318,7 @@ clear_selected(GtkMenuItem *menu_item, gpointer user_data)
|
||||
}
|
||||
|
||||
/* Called when About is selected from right-click menu */
|
||||
static void
|
||||
show_about_dialog(GtkMenuItem *menu_item, gpointer user_data)
|
||||
static void show_about_dialog(GtkMenuItem *menu_item, gpointer user_data)
|
||||
{
|
||||
/* This helps prevent multiple instances */
|
||||
if (!gtk_grab_get_current())
|
||||
@ -391,8 +385,7 @@ show_about_dialog(GtkMenuItem *menu_item, gpointer user_data)
|
||||
}
|
||||
|
||||
/* Called when Preferences is selected from right-click menu */
|
||||
static void
|
||||
preferences_selected(GtkMenuItem *menu_item, gpointer user_data)
|
||||
static void preferences_selected(GtkMenuItem *menu_item, gpointer user_data)
|
||||
{
|
||||
/* This helps prevent multiple instances */
|
||||
if (!gtk_grab_get_current())
|
||||
@ -401,8 +394,7 @@ preferences_selected(GtkMenuItem *menu_item, gpointer user_data)
|
||||
}
|
||||
|
||||
/* Called when Quit is selected from right-click menu */
|
||||
static void
|
||||
quit_selected(GtkMenuItem *menu_item, gpointer user_data)
|
||||
static void quit_selected(GtkMenuItem *menu_item, gpointer user_data)
|
||||
{
|
||||
/* Prevent quit with dialogs open */
|
||||
if (!gtk_grab_get_current())
|
||||
@ -411,8 +403,7 @@ quit_selected(GtkMenuItem *menu_item, gpointer user_data)
|
||||
}
|
||||
|
||||
/* Called when status icon is control-clicked */
|
||||
static gboolean
|
||||
show_actions_menu(gpointer data)
|
||||
static gboolean show_actions_menu(gpointer data)
|
||||
{
|
||||
/* Declare some variables */
|
||||
GtkWidget *menu, *menu_item,
|
||||
@ -521,8 +512,7 @@ show_actions_menu(gpointer data)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
show_history_menu_full(gpointer data)
|
||||
static gboolean show_history_menu_full(gpointer data)
|
||||
{
|
||||
/* Declare some variables */
|
||||
GtkWidget *menu, *menu_item,
|
||||
@ -550,32 +540,9 @@ show_history_menu_full(gpointer data)
|
||||
{
|
||||
GString* string = g_string_new((gchar*)element->data);
|
||||
/* Ellipsize text */
|
||||
if (string->len > prefs.item_length)
|
||||
{
|
||||
switch (prefs.ellipsize)
|
||||
{
|
||||
case PANGO_ELLIPSIZE_START:
|
||||
string = g_string_erase(string, 0, string->len-(prefs.item_length));
|
||||
string = g_string_prepend(string, "...");
|
||||
break;
|
||||
case PANGO_ELLIPSIZE_MIDDLE:
|
||||
string = g_string_erase(string, (prefs.item_length/2), string->len-(prefs.item_length));
|
||||
string = g_string_insert(string, (string->len/2), "...");
|
||||
break;
|
||||
case PANGO_ELLIPSIZE_END:
|
||||
string = g_string_truncate(string, prefs.item_length);
|
||||
string = g_string_append(string, "...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
string = ellipsize_string(string);
|
||||
/* Remove control characters */
|
||||
int i = 0;
|
||||
while (i < string->len)
|
||||
{
|
||||
if (string->str[i] == '\n')
|
||||
g_string_overwrite(string, i, " ");
|
||||
i++;
|
||||
}
|
||||
string = remove_newlines_string(string);
|
||||
/* Make new item with ellipsized text */
|
||||
gchar* list_item;
|
||||
if (prefs.show_indexes)
|
||||
@ -642,8 +609,7 @@ show_history_menu_full(gpointer data)
|
||||
}
|
||||
|
||||
/* Generates the small history menu */
|
||||
static gboolean
|
||||
show_history_menu_small(gpointer data)
|
||||
static gboolean show_history_menu_small(gpointer data)
|
||||
{
|
||||
/* Declare some variables */
|
||||
GtkWidget *menu, *menu_item,
|
||||
@ -672,32 +638,9 @@ show_history_menu_small(gpointer data)
|
||||
{
|
||||
GString* string = g_string_new((gchar*)element->data);
|
||||
/* Ellipsize text */
|
||||
if (string->len > prefs.item_length)
|
||||
{
|
||||
switch (prefs.ellipsize)
|
||||
{
|
||||
case PANGO_ELLIPSIZE_START:
|
||||
string = g_string_erase(string, 0, string->len-(prefs.item_length));
|
||||
string = g_string_prepend(string, "...");
|
||||
break;
|
||||
case PANGO_ELLIPSIZE_MIDDLE:
|
||||
string = g_string_erase(string, (prefs.item_length/2), string->len-(prefs.item_length));
|
||||
string = g_string_insert(string, (string->len/2), "...");
|
||||
break;
|
||||
case PANGO_ELLIPSIZE_END:
|
||||
string = g_string_truncate(string, prefs.item_length);
|
||||
string = g_string_append(string, "...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
string = ellipsize_string(string);
|
||||
/* Remove control characters */
|
||||
int i = 0;
|
||||
while (i < string->len)
|
||||
{
|
||||
if (string->str[i] == '\n')
|
||||
g_string_overwrite(string, i, " ");
|
||||
i++;
|
||||
}
|
||||
string = remove_newlines_string(string);
|
||||
/* Make new item with ellipsized text */
|
||||
gchar* list_item;
|
||||
if (prefs.show_indexes)
|
||||
@ -771,8 +714,7 @@ show_history_menu_small(gpointer data)
|
||||
}
|
||||
|
||||
/* Called when status icon is left-clicked */
|
||||
static gboolean
|
||||
show_history_menu()
|
||||
static gboolean show_history_menu()
|
||||
{
|
||||
if (prefs.small_history)
|
||||
g_timeout_add(POPUP_DELAY, show_history_menu_small, NULL);
|
||||
@ -783,8 +725,7 @@ show_history_menu()
|
||||
}
|
||||
|
||||
/* Called when status icon is right-clicked */
|
||||
static void
|
||||
show_clipit_menu(GtkStatusIcon *status_icon, guint button, guint activate_time)
|
||||
static void show_clipit_menu(GtkStatusIcon *status_icon, guint button, guint activate_time)
|
||||
{
|
||||
/* Declare some variables */
|
||||
GtkWidget *menu, *menu_item,
|
||||
@ -827,8 +768,7 @@ show_clipit_menu(GtkStatusIcon *status_icon, guint button, guint activate_time)
|
||||
|
||||
/* Called when status icon is clicked */
|
||||
/* (checks type of click and calls correct function */
|
||||
static void
|
||||
status_icon_clicked(GtkStatusIcon *status_icon, GdkEventButton *event )
|
||||
static void status_icon_clicked(GtkStatusIcon *status_icon, GdkEventButton *event )
|
||||
{
|
||||
/* Check what type of click was recieved */
|
||||
GdkModifierType state;
|
||||
@ -841,11 +781,12 @@ status_icon_clicked(GtkStatusIcon *status_icon, GdkEventButton *event )
|
||||
g_timeout_add(POPUP_DELAY, show_actions_menu, NULL);
|
||||
}
|
||||
}
|
||||
/* Normal click */
|
||||
/* Left click */
|
||||
else if (event->button == 1)
|
||||
{
|
||||
show_history_menu();
|
||||
}
|
||||
/* Right click */
|
||||
else
|
||||
{
|
||||
show_clipit_menu(status_icon, event->button, gtk_get_current_event_time());
|
||||
@ -853,36 +794,31 @@ status_icon_clicked(GtkStatusIcon *status_icon, GdkEventButton *event )
|
||||
}
|
||||
|
||||
/* Called when history global hotkey is pressed */
|
||||
void
|
||||
history_hotkey(char *keystring, gpointer user_data)
|
||||
void history_hotkey(char *keystring, gpointer user_data)
|
||||
{
|
||||
g_timeout_add(POPUP_DELAY, show_history_menu, NULL);
|
||||
}
|
||||
|
||||
/* Called when actions global hotkey is pressed */
|
||||
void
|
||||
actions_hotkey(char *keystring, gpointer user_data)
|
||||
void actions_hotkey(char *keystring, gpointer user_data)
|
||||
{
|
||||
g_timeout_add(POPUP_DELAY, show_actions_menu, NULL);
|
||||
}
|
||||
|
||||
/* Called when actions global hotkey is pressed */
|
||||
void
|
||||
menu_hotkey(char *keystring, gpointer user_data)
|
||||
void menu_hotkey(char *keystring, gpointer user_data)
|
||||
{
|
||||
show_clipit_menu(status_icon, 0, 0);
|
||||
}
|
||||
|
||||
/* Called when search global hotkey is pressed */
|
||||
void
|
||||
search_hotkey(char *keystring, gpointer user_data)
|
||||
void search_hotkey(char *keystring, gpointer user_data)
|
||||
{
|
||||
g_timeout_add(POPUP_DELAY, show_search, NULL);
|
||||
}
|
||||
|
||||
/* Startup calls and initializations */
|
||||
static void
|
||||
clipit_init()
|
||||
static void clipit_init()
|
||||
{
|
||||
/* Create clipboard */
|
||||
primary = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
|
||||
@ -913,8 +849,7 @@ clipit_init()
|
||||
}
|
||||
|
||||
/* This is Sparta! */
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
bindtextdomain(GETTEXT_PACKAGE, CLIPITLOCALEDIR);
|
||||
bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
|
||||
|
12
src/main.h
12
src/main.h
@ -65,17 +65,13 @@ prefs_t;
|
||||
|
||||
extern prefs_t prefs;
|
||||
|
||||
void
|
||||
history_hotkey(char *keystring, gpointer user_data);
|
||||
void history_hotkey(char *keystring, gpointer user_data);
|
||||
|
||||
void
|
||||
actions_hotkey(char *keystring, gpointer user_data);
|
||||
void actions_hotkey(char *keystring, gpointer user_data);
|
||||
|
||||
void
|
||||
menu_hotkey(char *keystring, gpointer user_data);
|
||||
void menu_hotkey(char *keystring, gpointer user_data);
|
||||
|
||||
void
|
||||
search_hotkey(char *keystring, gpointer user_data);
|
||||
void search_hotkey(char *keystring, gpointer user_data);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
92
src/manage.c
92
src/manage.c
@ -12,11 +12,11 @@
|
||||
*
|
||||
* ClipIt 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
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
@ -34,8 +34,7 @@ GtkWidget *search_entry;
|
||||
GtkWidget* treeview_search;
|
||||
|
||||
/* Search through the history */
|
||||
static void
|
||||
search_history()
|
||||
static void search_history()
|
||||
{
|
||||
guint16 search_len = gtk_entry_get_text_length((GtkEntry*)search_entry);
|
||||
/* Test if there is text in the search box */
|
||||
@ -62,31 +61,8 @@ search_history()
|
||||
{
|
||||
GtkTreeIter row_iter;
|
||||
gtk_list_store_append(search_list, &row_iter);
|
||||
if (string->len > prefs.item_length)
|
||||
{
|
||||
switch (prefs.ellipsize)
|
||||
{
|
||||
case PANGO_ELLIPSIZE_START:
|
||||
string = g_string_erase(string, 0, string->len-(prefs.item_length));
|
||||
string = g_string_prepend(string, "...");
|
||||
break;
|
||||
case PANGO_ELLIPSIZE_MIDDLE:
|
||||
string = g_string_erase(string, (prefs.item_length/2), string->len-(prefs.item_length));
|
||||
string = g_string_insert(string, (string->len/2), "...");
|
||||
break;
|
||||
case PANGO_ELLIPSIZE_END:
|
||||
string = g_string_truncate(string, prefs.item_length);
|
||||
string = g_string_append(string, "...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
int i = 0;
|
||||
while (i < string->len)
|
||||
{
|
||||
if (string->str[i] == '\n')
|
||||
g_string_overwrite(string, i, " ");
|
||||
i++;
|
||||
}
|
||||
string = ellipsize_string(string);
|
||||
string = remove_newlines_string(string);
|
||||
int row_num = g_slist_position(history, element);
|
||||
gtk_list_store_set(search_list, &row_iter, 0, row_num, 1, string->str, -1);
|
||||
}
|
||||
@ -107,38 +83,15 @@ search_history()
|
||||
gtk_list_store_remove(search_list, &search_iter);
|
||||
|
||||
/* Declare some variables */
|
||||
GSList* element;
|
||||
GSList *element;
|
||||
/* Go through each element and adding each */
|
||||
for (element = history; element != NULL; element = element->next)
|
||||
{
|
||||
GString* string = g_string_new((gchar*)element->data);
|
||||
GString *string = g_string_new((gchar*)element->data);
|
||||
GtkTreeIter row_iter;
|
||||
gtk_list_store_append(search_list, &row_iter);
|
||||
if (string->len > prefs.item_length)
|
||||
{
|
||||
switch (prefs.ellipsize)
|
||||
{
|
||||
case PANGO_ELLIPSIZE_START:
|
||||
string = g_string_erase(string, 0, string->len-(prefs.item_length));
|
||||
string = g_string_prepend(string, "...");
|
||||
break;
|
||||
case PANGO_ELLIPSIZE_MIDDLE:
|
||||
string = g_string_erase(string, (prefs.item_length/2), string->len-(prefs.item_length));
|
||||
string = g_string_insert(string, (string->len/2), "...");
|
||||
break;
|
||||
case PANGO_ELLIPSIZE_END:
|
||||
string = g_string_truncate(string, prefs.item_length);
|
||||
string = g_string_append(string, "...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
int i = 0;
|
||||
while (i < string->len)
|
||||
{
|
||||
if (string->str[i] == '\n')
|
||||
g_string_overwrite(string, i, " ");
|
||||
i++;
|
||||
}
|
||||
string = ellipsize_string(string);
|
||||
string = remove_newlines_string(string);
|
||||
int row_num = g_slist_position(history, element);
|
||||
gtk_list_store_set(search_list, &row_iter, 0, row_num, 1, string->str, -1);
|
||||
|
||||
@ -150,8 +103,7 @@ search_history()
|
||||
}
|
||||
|
||||
/* Called when Edit is selected from Manage dialog */
|
||||
static void
|
||||
edit_selected()
|
||||
static void edit_selected()
|
||||
{
|
||||
GtkTreeIter sel_iter;
|
||||
GtkTreeSelection* search_selection = gtk_tree_view_get_selection((GtkTreeView*)treeview_search);
|
||||
@ -201,8 +153,7 @@ edit_selected()
|
||||
|
||||
/* Insert new element before the old one */
|
||||
history = g_slist_insert_before(history, element->next,
|
||||
g_strdup(gtk_text_buffer_get_text(clipboard_buffer, &start, &end, TRUE))
|
||||
);
|
||||
g_strdup(gtk_text_buffer_get_text(clipboard_buffer, &start, &end, TRUE)));
|
||||
|
||||
/* Remove old entry */
|
||||
history = g_slist_remove(history, element->data);
|
||||
@ -213,8 +164,7 @@ edit_selected()
|
||||
clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
|
||||
gtk_clipboard_set_text(clipboard,
|
||||
gtk_text_buffer_get_text(clipboard_buffer, &start, &end, TRUE),
|
||||
-1
|
||||
);
|
||||
-1);
|
||||
}
|
||||
}
|
||||
gtk_widget_destroy(dialog);
|
||||
@ -224,8 +174,7 @@ edit_selected()
|
||||
}
|
||||
|
||||
/* Called when Remove is selected from Manage dialog */
|
||||
static void
|
||||
remove_selected()
|
||||
static void remove_selected()
|
||||
{
|
||||
GtkTreeIter sel_iter;
|
||||
GtkTreeSelection* search_selection = gtk_tree_view_get_selection((GtkTreeView*)treeview_search);
|
||||
@ -242,8 +191,7 @@ remove_selected()
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
search_doubleclick()
|
||||
static void search_doubleclick()
|
||||
{
|
||||
GtkTreeIter sel_iter;
|
||||
GtkTreeSelection* search_selection = gtk_tree_view_get_selection((GtkTreeView*)treeview_search);
|
||||
@ -260,8 +208,7 @@ search_doubleclick()
|
||||
}
|
||||
}
|
||||
|
||||
gint
|
||||
search_click(GtkWidget *widget, GdkEventButton *event, GtkWidget *search_window)
|
||||
gint search_click(GtkWidget *widget, GdkEventButton *event, GtkWidget *search_window)
|
||||
{
|
||||
if(event->type==GDK_2BUTTON_PRESS || event->type==GDK_3BUTTON_PRESS)
|
||||
{
|
||||
@ -271,8 +218,7 @@ search_click(GtkWidget *widget, GdkEventButton *event, GtkWidget *search_window)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gint
|
||||
search_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
|
||||
static gint search_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
|
||||
{
|
||||
/* Check if [Return] key was pressed */
|
||||
if ((event->keyval == 0xff0d) || (event->keyval == 0xff8d))
|
||||
@ -280,8 +226,7 @@ search_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
search_window_response(GtkDialog *dialog, gint response_id, gpointer user_data)
|
||||
void search_window_response(GtkDialog *dialog, gint response_id, gpointer user_data)
|
||||
{
|
||||
if(response_id < 0)
|
||||
{
|
||||
@ -291,8 +236,7 @@ search_window_response(GtkDialog *dialog, gint response_id, gpointer user_data)
|
||||
}
|
||||
|
||||
/* Shows the search dialog */
|
||||
gboolean
|
||||
show_search()
|
||||
gboolean show_search()
|
||||
{
|
||||
/* Prevent multiple instances */
|
||||
if(gtk_grab_get_current())
|
||||
|
@ -12,11 +12,11 @@
|
||||
*
|
||||
* ClipIt 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
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MANAGE_H
|
||||
@ -24,8 +24,7 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gboolean
|
||||
show_search();
|
||||
gboolean show_search();
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -56,8 +56,7 @@ GtkListStore* exclude_list;
|
||||
GtkTreeSelection* exclude_selection;
|
||||
|
||||
/* Apply the new preferences */
|
||||
static void
|
||||
apply_preferences()
|
||||
static void apply_preferences()
|
||||
{
|
||||
/* Unbind the keys before binding new ones */
|
||||
keybinder_unbind(prefs.history_key, history_hotkey);
|
||||
@ -104,8 +103,7 @@ apply_preferences()
|
||||
}
|
||||
|
||||
/* Save preferences to ~/.config/clipit/clipitrc */
|
||||
static void
|
||||
save_preferences()
|
||||
static void save_preferences()
|
||||
{
|
||||
/* Create key */
|
||||
GKeyFile* rc_key = g_key_file_new();
|
||||
@ -142,8 +140,7 @@ save_preferences()
|
||||
}
|
||||
|
||||
/* Read ~/.config/clipit/clipitrc */
|
||||
void
|
||||
read_preferences()
|
||||
void read_preferences()
|
||||
{
|
||||
gchar* rc_file = g_build_filename(g_get_home_dir(), PREFERENCES_FILE, NULL);
|
||||
/* Create key */
|
||||
@ -203,8 +200,7 @@ read_preferences()
|
||||
}
|
||||
|
||||
/* Read ~/.clipit/actions into the treeview */
|
||||
static void
|
||||
read_actions()
|
||||
static void read_actions()
|
||||
{
|
||||
/* Open the file for reading */
|
||||
gchar* path = g_build_filename(g_get_home_dir(), ACTIONS_FILE, NULL);
|
||||
@ -243,8 +239,7 @@ read_actions()
|
||||
}
|
||||
|
||||
/* Save the actions treeview to ~/.local/share/clipit/actions */
|
||||
static void
|
||||
save_actions()
|
||||
static void save_actions()
|
||||
{
|
||||
/* Check config and data directories */
|
||||
check_dirs();
|
||||
@ -298,8 +293,7 @@ save_actions()
|
||||
}
|
||||
|
||||
/* Called when clipboard checks are pressed */
|
||||
static void
|
||||
check_toggled(GtkToggleButton *togglebutton, gpointer user_data)
|
||||
static void check_toggled(GtkToggleButton *togglebutton, gpointer user_data)
|
||||
{
|
||||
if (gtk_toggle_button_get_active((GtkToggleButton*)copy_check) &&
|
||||
gtk_toggle_button_get_active((GtkToggleButton*)primary_check))
|
||||
@ -317,8 +311,7 @@ check_toggled(GtkToggleButton *togglebutton, gpointer user_data)
|
||||
}
|
||||
|
||||
/* Called when Add... button is clicked */
|
||||
static void
|
||||
add_action(GtkButton *button, gpointer user_data)
|
||||
static void add_action(GtkButton *button, gpointer user_data)
|
||||
{
|
||||
/* Append new item */
|
||||
GtkTreeIter row_iter;
|
||||
@ -334,8 +327,7 @@ add_action(GtkButton *button, gpointer user_data)
|
||||
}
|
||||
|
||||
/* Called when Remove button is clicked */
|
||||
static void
|
||||
remove_action(GtkButton *button, gpointer user_data)
|
||||
static void remove_action(GtkButton *button, gpointer user_data)
|
||||
{
|
||||
GtkTreeIter sel_iter;
|
||||
/* Check if selected */
|
||||
@ -356,8 +348,7 @@ remove_action(GtkButton *button, gpointer user_data)
|
||||
}
|
||||
|
||||
/* Called when Up button is clicked */
|
||||
static void
|
||||
move_action_up(GtkButton *button, gpointer user_data)
|
||||
static void move_action_up(GtkButton *button, gpointer user_data)
|
||||
{
|
||||
GtkTreeIter sel_iter;
|
||||
/* Check if selected */
|
||||
@ -378,8 +369,7 @@ move_action_up(GtkButton *button, gpointer user_data)
|
||||
}
|
||||
|
||||
/* Called when Down button is clicked */
|
||||
static void
|
||||
move_action_down(GtkButton *button, gpointer user_data)
|
||||
static void move_action_down(GtkButton *button, gpointer user_data)
|
||||
{
|
||||
GtkTreeIter sel_iter;
|
||||
/* Check if selected */
|
||||
@ -395,8 +385,7 @@ move_action_down(GtkButton *button, gpointer user_data)
|
||||
}
|
||||
|
||||
/* Called when delete key is pressed */
|
||||
static void
|
||||
delete_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
|
||||
static void delete_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
|
||||
{
|
||||
/* Check if DEL key was pressed (keyval: 65535) */
|
||||
if (event->keyval == 65535)
|
||||
@ -404,8 +393,7 @@ delete_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
|
||||
}
|
||||
|
||||
/* Called when a cell is edited */
|
||||
static void
|
||||
edit_action(GtkCellRendererText *renderer, gchar *path,
|
||||
static void edit_action(GtkCellRendererText *renderer, gchar *path,
|
||||
gchar *new_text, gpointer cell)
|
||||
{
|
||||
GtkTreeIter sel_iter;
|
||||
@ -420,8 +408,7 @@ edit_action(GtkCellRendererText *renderer, gchar *path,
|
||||
/* exclude Functions */
|
||||
|
||||
/* Read ~/.clipit/excludes into the treeview */
|
||||
static void
|
||||
read_excludes()
|
||||
static void read_excludes()
|
||||
{
|
||||
/* Open the file for reading */
|
||||
gchar* path = g_build_filename(g_get_home_dir(), EXCLUDES_FILE, NULL);
|
||||
@ -454,8 +441,7 @@ read_excludes()
|
||||
}
|
||||
|
||||
/* Save the actions treeview to ~/.local/share/clipit/excludes */
|
||||
static void
|
||||
save_excludes()
|
||||
static void save_excludes()
|
||||
{
|
||||
/* Check config and data directories */
|
||||
check_dirs();
|
||||
@ -503,8 +489,7 @@ save_excludes()
|
||||
}
|
||||
|
||||
/* Called when Add... button is clicked */
|
||||
static void
|
||||
add_exclude(GtkButton *button, gpointer user_data)
|
||||
static void add_exclude(GtkButton *button, gpointer user_data)
|
||||
{
|
||||
/* Append new item */
|
||||
GtkTreeIter row_iter;
|
||||
@ -520,8 +505,7 @@ add_exclude(GtkButton *button, gpointer user_data)
|
||||
}
|
||||
|
||||
/* Called when Remove button is clicked */
|
||||
static void
|
||||
remove_exclude(GtkButton *button, gpointer user_data)
|
||||
static void remove_exclude(GtkButton *button, gpointer user_data)
|
||||
{
|
||||
GtkTreeIter sel_iter;
|
||||
/* Check if selected */
|
||||
@ -542,8 +526,7 @@ remove_exclude(GtkButton *button, gpointer user_data)
|
||||
}
|
||||
|
||||
/* Called when a cell is edited */
|
||||
static void
|
||||
edit_exclude(GtkCellRendererText *renderer, gchar *path,
|
||||
static void edit_exclude(GtkCellRendererText *renderer, gchar *path,
|
||||
gchar *new_text, gpointer cell)
|
||||
{
|
||||
GtkTreeIter sel_iter;
|
||||
@ -556,8 +539,7 @@ edit_exclude(GtkCellRendererText *renderer, gchar *path,
|
||||
}
|
||||
|
||||
/* Shows the preferences dialog on the given tab */
|
||||
void
|
||||
show_preferences(gint tab)
|
||||
void show_preferences(gint tab)
|
||||
{
|
||||
/* Declare some variables */
|
||||
GtkWidget *frame, *label,
|
||||
|
@ -56,11 +56,9 @@ G_BEGIN_DECLS
|
||||
#define PREFERENCES_FILE ".config/clipit/clipitrc"
|
||||
#define THEMES_FOLDER ".config/clipit/themes"
|
||||
|
||||
void
|
||||
read_preferences();
|
||||
void read_preferences();
|
||||
|
||||
void
|
||||
show_preferences(gint tab);
|
||||
void show_preferences(gint tab);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
441
src/utils.c
441
src/utils.c
@ -12,11 +12,11 @@
|
||||
*
|
||||
* ClipIt 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
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
@ -31,223 +31,256 @@
|
||||
void
|
||||
check_dirs()
|
||||
{
|
||||
gchar* data_dir = g_build_path("/", g_get_home_dir(), DATA_DIR, NULL);
|
||||
gchar* config_dir = g_build_path("/", g_get_home_dir(), CONFIG_DIR, NULL);
|
||||
/* Check if data directory exists */
|
||||
if (!g_file_test(data_dir, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
/* Try to make data directory */
|
||||
if (g_mkdir_with_parents(data_dir, 0755) != 0)
|
||||
g_warning(_("Couldn't create directory: %s\n"), data_dir);
|
||||
}
|
||||
/* Check if config directory exists */
|
||||
if (!g_file_test(config_dir, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
/* Try to make config directory */
|
||||
if (g_mkdir_with_parents(config_dir, 0755) != 0)
|
||||
g_warning(_("Couldn't create directory: %s\n"), config_dir);
|
||||
}
|
||||
/* Cleanup */
|
||||
g_free(data_dir);
|
||||
g_free(config_dir);
|
||||
gchar *data_dir = g_build_path("/", g_get_home_dir(), DATA_DIR, NULL);
|
||||
gchar *config_dir = g_build_path("/", g_get_home_dir(), CONFIG_DIR, NULL);
|
||||
/* Check if data directory exists */
|
||||
if (!g_file_test(data_dir, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
/* Try to make data directory */
|
||||
if (g_mkdir_with_parents(data_dir, 0755) != 0)
|
||||
g_warning(_("Couldn't create directory: %s\n"), data_dir);
|
||||
}
|
||||
/* Check if config directory exists */
|
||||
if (!g_file_test(config_dir, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
/* Try to make config directory */
|
||||
if (g_mkdir_with_parents(config_dir, 0755) != 0)
|
||||
g_warning(_("Couldn't create directory: %s\n"), config_dir);
|
||||
}
|
||||
/* Cleanup */
|
||||
g_free(data_dir);
|
||||
g_free(config_dir);
|
||||
}
|
||||
|
||||
/* Returns TRUE if text is a hyperlink */
|
||||
gboolean
|
||||
is_hyperlink(gchar* text)
|
||||
is_hyperlink(gchar *text)
|
||||
{
|
||||
/* TODO: I need a better regex, this one is poor */
|
||||
GRegex* regex = g_regex_new("([A-Za-z][A-Za-z0-9+.-]{1,120}:[A-Za-z0-9/]" \
|
||||
"(([A-Za-z0-9$_.+!*,;/?:@&~=-])|%[A-Fa-f0-9]{2}){1,333}" \
|
||||
"(#([a-zA-Z0-9][a-zA-Z0-9$_.+!*,;/?:@&~=%-]{0,1000}))?)",
|
||||
G_REGEX_CASELESS, 0, NULL);
|
||||
|
||||
gboolean result = g_regex_match(regex, text, 0, NULL);
|
||||
g_regex_unref(regex);
|
||||
return result;
|
||||
/* TODO: I need a better regex, this one is poor */
|
||||
GRegex *regex = g_regex_new("([A-Za-z][A-Za-z0-9+.-]{1,120}:[A-Za-z0-9/]" \
|
||||
"(([A-Za-z0-9$_.+!*,;/?:@&~=-])|%[A-Fa-f0-9]{2}){1,333}" \
|
||||
"(#([a-zA-Z0-9][a-zA-Z0-9$_.+!*,;/?:@&~=%-]{0,1000}))?)",
|
||||
G_REGEX_CASELESS, 0, NULL);
|
||||
|
||||
gboolean result = g_regex_match(regex, text, 0, NULL);
|
||||
g_regex_unref(regex);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Returns TRUE if text should be excluded from history */
|
||||
gboolean
|
||||
is_excluded(gchar* text)
|
||||
gboolean is_excluded(gchar *text)
|
||||
{
|
||||
/* Open the file for reading */
|
||||
gchar* path = g_build_filename(g_get_home_dir(), EXCLUDES_FILE, NULL);
|
||||
FILE* excludes_file = fopen(path, "rb");
|
||||
g_free(path);
|
||||
/* Check that it opened and begin read */
|
||||
if (excludes_file)
|
||||
{
|
||||
/* Keep a row reference */
|
||||
GtkTreeIter row_iter;
|
||||
/* Read the size of the first item */
|
||||
gint size;
|
||||
size_t fread_return;
|
||||
fread_return = fread(&size, 4, 1, excludes_file);
|
||||
/* Continue reading until size is 0 */
|
||||
while (size != 0)
|
||||
{
|
||||
/* Read Regex */
|
||||
gchar* regex = (gchar*)g_malloc(size + 1);
|
||||
fread_return = fread(regex, size, 1, excludes_file);
|
||||
regex[size] = '\0';
|
||||
fread_return = fread(&size, 4, 1, excludes_file);
|
||||
/* Append the read action */
|
||||
GRegex* regexp = g_regex_new(regex, G_REGEX_CASELESS, 0, NULL);
|
||||
gboolean result = g_regex_match(regexp, text, 0, NULL);
|
||||
g_regex_unref(regexp);
|
||||
g_free(regex);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
fclose(excludes_file);
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
/* Open the file for reading */
|
||||
gchar *path = g_build_filename(g_get_home_dir(), EXCLUDES_FILE, NULL);
|
||||
FILE *excludes_file = fopen(path, "rb");
|
||||
g_free(path);
|
||||
/* Check that it opened and begin read */
|
||||
if (excludes_file)
|
||||
{
|
||||
/* Keep a row reference */
|
||||
GtkTreeIter row_iter;
|
||||
/* Read the size of the first item */
|
||||
gint size;
|
||||
size_t fread_return;
|
||||
fread_return = fread(&size, 4, 1, excludes_file);
|
||||
/* Continue reading until size is 0 */
|
||||
while (size != 0)
|
||||
{
|
||||
/* Read Regex */
|
||||
gchar *regex = (gchar*)g_malloc(size + 1);
|
||||
fread_return = fread(regex, size, 1, excludes_file);
|
||||
regex[size] = '\0';
|
||||
fread_return = fread(&size, 4, 1, excludes_file);
|
||||
/* Append the read action */
|
||||
GRegex *regexp = g_regex_new(regex, G_REGEX_CASELESS, 0, NULL);
|
||||
gboolean result = g_regex_match(regexp, text, 0, NULL);
|
||||
g_regex_unref(regexp);
|
||||
g_free(regex);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
fclose(excludes_file);
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Ellipsize a string according to the settings */
|
||||
GString *ellipsize_string(GString *string)
|
||||
{
|
||||
if (string->len > prefs.item_length)
|
||||
{
|
||||
switch (prefs.ellipsize)
|
||||
{
|
||||
case PANGO_ELLIPSIZE_START:
|
||||
string = g_string_erase(string, 0, string->len-(prefs.item_length));
|
||||
string = g_string_prepend(string, "...");
|
||||
break;
|
||||
case PANGO_ELLIPSIZE_MIDDLE:
|
||||
string = g_string_erase(string, (prefs.item_length/2), string->len-(prefs.item_length));
|
||||
string = g_string_insert(string, (string->len/2), "...");
|
||||
break;
|
||||
case PANGO_ELLIPSIZE_END:
|
||||
string = g_string_truncate(string, prefs.item_length);
|
||||
string = g_string_append(string, "...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/* Remove newlines from string */
|
||||
GString *remove_newlines_string(GString *string)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < string->len)
|
||||
{
|
||||
if (string->str[i] == '\n')
|
||||
g_string_overwrite(string, i, " ");
|
||||
i++;
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/* Parses the program arguments. Returns TRUE if program needs
|
||||
* to exit after parsing is complete
|
||||
*/
|
||||
gboolean
|
||||
parse_options(int argc, char* argv[])
|
||||
gboolean parse_options(int argc, char* argv[])
|
||||
{
|
||||
/* Declare argument options and argument variables */
|
||||
gboolean icon = FALSE, daemon = FALSE,
|
||||
clipboard = FALSE, primary = FALSE,
|
||||
exit = FALSE;
|
||||
|
||||
GOptionEntry main_entries[] =
|
||||
{
|
||||
{
|
||||
"daemon", 'd',
|
||||
G_OPTION_FLAG_NO_ARG,
|
||||
G_OPTION_ARG_NONE,
|
||||
&daemon, _("Run as daemon"),
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"no-icon", 'n',
|
||||
G_OPTION_FLAG_NO_ARG,
|
||||
G_OPTION_ARG_NONE,
|
||||
&icon, _("Do not use status icon (Ctrl-Alt-P for menu)"),
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"clipboard", 'c',
|
||||
G_OPTION_FLAG_NO_ARG,
|
||||
G_OPTION_ARG_NONE,
|
||||
&clipboard, _("Print clipboard contents"),
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"primary", 'p',
|
||||
G_OPTION_FLAG_NO_ARG,
|
||||
G_OPTION_ARG_NONE,
|
||||
&primary, _("Print primary contents"),
|
||||
NULL
|
||||
},
|
||||
{
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
/* Option parsing */
|
||||
GOptionContext* context = g_option_context_new(NULL);
|
||||
/* Set summary */
|
||||
g_option_context_set_summary(context,
|
||||
_("Clipboard CLI usage examples:\n\n"
|
||||
" echo \"copied to clipboard\" | clipit\n"
|
||||
" clipit \"copied to clipboard\"\n"
|
||||
" echo \"copied to clipboard\" | clipit -c"));
|
||||
/* Set description */
|
||||
g_option_context_set_description(context,
|
||||
_("Written by Cristian Henzel.\n"
|
||||
"Report bugs to <oss@web-tm.com>."));
|
||||
/* Add entries and parse options */
|
||||
g_option_context_add_main_entries(context, main_entries, NULL);
|
||||
g_option_context_parse(context, &argc, &argv, NULL);
|
||||
g_option_context_free(context);
|
||||
|
||||
/* Check which options were parseed */
|
||||
|
||||
/* Do not display icon option */
|
||||
if (icon)
|
||||
{
|
||||
prefs.no_icon = TRUE;
|
||||
}
|
||||
/* Run as daemon option */
|
||||
else if (daemon)
|
||||
{
|
||||
init_daemon_mode();
|
||||
exit = TRUE;
|
||||
}
|
||||
/* Print clipboard option */
|
||||
else if (clipboard)
|
||||
{
|
||||
/* Grab clipboard */
|
||||
GtkClipboard* clip = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
|
||||
|
||||
/* Check if stdin has text to copy */
|
||||
if (!isatty(fileno(stdin)))
|
||||
{
|
||||
GString* piped_string = g_string_new(NULL);
|
||||
/* Append stdin to string */
|
||||
while (1)
|
||||
{
|
||||
gchar* buffer = (gchar*)g_malloc(256);
|
||||
if (fgets(buffer, 256, stdin) == NULL)
|
||||
{
|
||||
g_free(buffer);
|
||||
break;
|
||||
}
|
||||
g_string_append(piped_string, buffer);
|
||||
g_free(buffer);
|
||||
}
|
||||
/* Check if anything was piped in */
|
||||
if (piped_string->len > 0)
|
||||
{
|
||||
/* Truncate new line character */
|
||||
/* g_string_truncate(piped_string, (piped_string->len - 1)); */
|
||||
/* Copy to clipboard */
|
||||
gtk_clipboard_set_text(clip, piped_string->str, -1);
|
||||
gtk_clipboard_store(clip);
|
||||
}
|
||||
g_string_free(piped_string, TRUE);
|
||||
}
|
||||
/* Print clipboard text (if any) */
|
||||
gchar* clip_text = gtk_clipboard_wait_for_text(clip);
|
||||
if (clip_text)
|
||||
g_print("%s", clip_text);
|
||||
g_free(clip_text);
|
||||
|
||||
/* Return true so program exits when finished parsing */
|
||||
exit = TRUE;
|
||||
}
|
||||
else if (primary)
|
||||
{
|
||||
/* Grab primary */
|
||||
GtkClipboard* prim = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
|
||||
/* Print primary text (if any) */
|
||||
gchar* prim_text = gtk_clipboard_wait_for_text(prim);
|
||||
if (prim_text)
|
||||
g_print("%s", prim_text);
|
||||
g_free(prim_text);
|
||||
/* Declare argument options and argument variables */
|
||||
gboolean icon = FALSE, daemon = FALSE,
|
||||
clipboard = FALSE, primary = FALSE,
|
||||
exit = FALSE;
|
||||
|
||||
/* Return true so program exits when finished parsing */
|
||||
exit = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy from unrecognized options */
|
||||
gchar* argv_string = g_strjoinv(" ", argv + 1);
|
||||
GtkClipboard* clip = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
|
||||
gtk_clipboard_set_text(clip, argv_string, -1);
|
||||
gtk_clipboard_store(clip);
|
||||
g_free(argv_string);
|
||||
/* Return true so program exits when finished parsing */
|
||||
exit = TRUE;
|
||||
}
|
||||
return exit;
|
||||
GOptionEntry main_entries[] =
|
||||
{
|
||||
{
|
||||
"daemon", 'd',
|
||||
G_OPTION_FLAG_NO_ARG,
|
||||
G_OPTION_ARG_NONE,
|
||||
&daemon, _("Run as daemon"),
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"no-icon", 'n',
|
||||
G_OPTION_FLAG_NO_ARG,
|
||||
G_OPTION_ARG_NONE,
|
||||
&icon, _("Do not use status icon (Ctrl-Alt-P for menu)"),
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"clipboard", 'c',
|
||||
G_OPTION_FLAG_NO_ARG,
|
||||
G_OPTION_ARG_NONE,
|
||||
&clipboard, _("Print clipboard contents"),
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"primary", 'p',
|
||||
G_OPTION_FLAG_NO_ARG,
|
||||
G_OPTION_ARG_NONE,
|
||||
&primary, _("Print primary contents"),
|
||||
NULL
|
||||
},
|
||||
{
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
/* Option parsing */
|
||||
GOptionContext *context = g_option_context_new(NULL);
|
||||
/* Set summary */
|
||||
g_option_context_set_summary(context,
|
||||
_("Clipboard CLI usage examples:\n\n"
|
||||
" echo \"copied to clipboard\" | clipit\n"
|
||||
" clipit \"copied to clipboard\"\n"
|
||||
" echo \"copied to clipboard\" | clipit -c"));
|
||||
/* Set description */
|
||||
g_option_context_set_description(context,
|
||||
_("Written by Cristian Henzel.\n"
|
||||
"Report bugs to <oss@web-tm.com>."));
|
||||
/* Add entries and parse options */
|
||||
g_option_context_add_main_entries(context, main_entries, NULL);
|
||||
g_option_context_parse(context, &argc, &argv, NULL);
|
||||
g_option_context_free(context);
|
||||
|
||||
/* Check which options were parseed */
|
||||
|
||||
/* Do not display icon option */
|
||||
if (icon)
|
||||
{
|
||||
prefs.no_icon = TRUE;
|
||||
}
|
||||
/* Run as daemon option */
|
||||
else if (daemon)
|
||||
{
|
||||
init_daemon_mode();
|
||||
exit = TRUE;
|
||||
}
|
||||
/* Print clipboard option */
|
||||
else if (clipboard)
|
||||
{
|
||||
/* Grab clipboard */
|
||||
GtkClipboard *clip = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
|
||||
|
||||
/* Check if stdin has text to copy */
|
||||
if (!isatty(fileno(stdin)))
|
||||
{
|
||||
GString *piped_string = g_string_new(NULL);
|
||||
/* Append stdin to string */
|
||||
while (1)
|
||||
{
|
||||
gchar *buffer = (gchar*)g_malloc(256);
|
||||
if (fgets(buffer, 256, stdin) == NULL)
|
||||
{
|
||||
g_free(buffer);
|
||||
break;
|
||||
}
|
||||
g_string_append(piped_string, buffer);
|
||||
g_free(buffer);
|
||||
}
|
||||
/* Check if anything was piped in */
|
||||
if (piped_string->len > 0)
|
||||
{
|
||||
/* Copy to clipboard */
|
||||
gtk_clipboard_set_text(clip, piped_string->str, -1);
|
||||
gtk_clipboard_store(clip);
|
||||
}
|
||||
g_string_free(piped_string, TRUE);
|
||||
}
|
||||
/* Print clipboard text (if any) */
|
||||
gchar *clip_text = gtk_clipboard_wait_for_text(clip);
|
||||
if (clip_text)
|
||||
g_print("%s", clip_text);
|
||||
g_free(clip_text);
|
||||
|
||||
/* Return true so program exits when finished parsing */
|
||||
exit = TRUE;
|
||||
}
|
||||
else if (primary)
|
||||
{
|
||||
/* Grab primary */
|
||||
GtkClipboard *prim = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
|
||||
/* Print primary text (if any) */
|
||||
gchar *prim_text = gtk_clipboard_wait_for_text(prim);
|
||||
if (prim_text)
|
||||
g_print("%s", prim_text);
|
||||
g_free(prim_text);
|
||||
|
||||
/* Return true so program exits when finished parsing */
|
||||
exit = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy from unrecognized options */
|
||||
gchar *argv_string = g_strjoinv(" ", argv + 1);
|
||||
GtkClipboard *clip = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
|
||||
gtk_clipboard_set_text(clip, argv_string, -1);
|
||||
gtk_clipboard_store(clip);
|
||||
g_free(argv_string);
|
||||
/* Return true so program exits when finished parsing */
|
||||
exit = TRUE;
|
||||
}
|
||||
return exit;
|
||||
}
|
||||
|
||||
|
13
src/utils.h
13
src/utils.h
@ -27,14 +27,15 @@ G_BEGIN_DECLS
|
||||
#define CONFIG_DIR ".local/share/clipit"
|
||||
#define DATA_DIR ".config/clipit"
|
||||
|
||||
void
|
||||
check_dirs();
|
||||
void check_dirs();
|
||||
|
||||
gboolean
|
||||
is_hyperlink(gchar* link);
|
||||
gboolean is_hyperlink(gchar* link);
|
||||
|
||||
gboolean
|
||||
parse_options(int argc, char* argv[]);
|
||||
GString *ellipsize_string(GString *string);
|
||||
|
||||
GString *remove_newlines_string(GString *string);
|
||||
|
||||
gboolean parse_options(int argc, char* argv[]);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user