13
13
#include "lib/DocActionManager.h"
14
14
#include "lib/CircularBuffer.h"
15
15
#include "DocActionAtt.h"
16
#include "lib/IniFile.h"
17
#include "lib/FilePath.h"
16
18
#include "support.h"
17
19
#include "interface.h"
24
#include <io.h> //access
25
#define access _access
20
28
extern GtkWidget *window1;
21
29
extern NoteDocument g_doc;
22
30
extern DocActionManager g_undoManager;
23
31
extern CircularBuffer g_objCrashLog;
32
extern IniFile g_objIni;
33
extern GdkAtom atomTextUriList;
25
35
void RefreshMainTitle();
26
36
void UpdateUndoRedoMenus();
37
void replaceall(std::string &strData, const char *szFind, const char *szReplace);
38
bool Utf8ToLocale(const char *szTxt, std::string &strResult);
27
39
static void on_add_file_clicked(GtkButton *button, gpointer user_data);
28
40
static void on_remove_file_clicked(GtkButton *button, gpointer user_data);
29
41
static void on_save_file_clicked(GtkButton *button, gpointer user_data);
30
42
static void on_close_clicked (GtkButton *button, gpointer user_data);
43
static gboolean att_list_on_drop(GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y, guint time, gpointer user_data);
44
static void att_list_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
45
GtkSelectionData *selection_data, guint target_type, guint time,
47
gboolean is_format_provided(GdkDragContext *context, GdkAtom target);
33
51
#define min(a,b) (((a)<(b))?(a):(b))
211
242
FileAttachmentDlg *pDlg = (FileAttachmentDlg *)user_data;
244
if(g_doc.IsReadOnly()){
245
gtkMessageBox(_("Can not change read-only document!"));
213
249
//load file to binary string
214
250
FileDialog dlg(true);
215
251
dlg.SetTitle(_("Add attachment"));
253
//set initial directory from INI (store last used)
254
std::string strDefaultDir;
256
g_objIni.GetValue("Cache", "LastAttachmentDir", strDir, "");
257
if(!strDir.empty() && 0 == access(strDir.c_str(), 00))
258
strDefaultDir = strDir;
260
strDefaultDir = GetHomeDir();
262
dlg.SetDirectory(strDefaultDir.c_str());
217
265
if(dlg.DoModal())
219
267
const gchar *filename = dlg.GetFilename();
268
strDefaultDir = dlg.GetDirectory();
222
FILE *pFile = fopen(filename, "rb");
271
//store last open directory
272
g_objIni.SetValue("Cache", "LastAttachmentDir", strDefaultDir.c_str());
275
std::string strLocaleFile;
276
Utf8ToLocale(filename, strLocaleFile);
278
replaceall(strLocaleFile, "/", "\\");
281
FILE *pFile = fopen(strLocaleFile.c_str(), "rb");
224
gtkMessageBox(_("Failed to open output file!"));
283
gtkMessageBox(_("Failed to open input file!"));
344
408
FileDialog dlg(false);
345
409
dlg.SetTitle(_("Save data"));
411
//set initial directory from INI (store last used)
412
std::string strDefaultDir;
414
g_objIni.GetValue("Cache", "LastAttachmentDir", strDir, "");
415
if(!strDir.empty() && 0 == access(strDir.c_str(), 00))
416
strDefaultDir = strDir;
418
strDefaultDir = GetHomeDir();
420
dlg.SetDirectory(strDefaultDir.c_str());
421
dlg.SetFilename(g_doc.GetNodeByIdx(pDlg->m_nNodeIdx).m_lstAttachments[nSelRow].m_strName.c_str());
347
423
if(dlg.DoModal())
349
425
const gchar *filename = dlg.GetFilename();
426
strDefaultDir = dlg.GetDirectory();
352
FILE *pFile = fopen(filename, "wb");
429
//store last open directory
430
g_objIni.SetValue("Cache", "LastAttachmentDir", strDefaultDir.c_str());
433
std::string strLocaleFile;
434
Utf8ToLocale(filename, strLocaleFile);
436
replaceall(strLocaleFile, "/", "\\");
439
FILE *pFile = fopen(strLocaleFile.c_str(), "wb");
354
441
gtkMessageBox(_("Failed to open output file!"));
389
476
//terminate dialog
390
477
gtk_dialog_response(GTK_DIALOG(pDlg->m_pDialog), GTK_RESPONSE_OK);
480
gboolean att_list_on_drop(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer user_data)
482
if(g_doc.IsReadOnly()){
483
gtkMessageBox(_("Can not change read-only document!"));
487
TRACE("DnD: att_list_on_drop\n");
489
gboolean is_valid_drop_site = TRUE;
491
// If the source offers a target
492
if (is_valid_drop_site && context->targets)
495
if(is_format_provided(context, atomTextUriList))
496
target_type = atomTextUriList;
500
// Request the data from the source, actual data will be received by 'drag-data-received' signal
501
gtk_drag_get_data( widget, context, target_type, time);
505
is_valid_drop_site = FALSE; // No target offered by source => error
508
return is_valid_drop_site;
511
void att_list_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint target_type, guint time, gpointer data)
513
TRACE("DnD: att_list_drag_data_received\n");
515
FileAttachmentDlg *pDlg = (FileAttachmentDlg *)data;
516
GtkWidget *treeview = lookup_widget(pDlg->m_pDialog, "treeview");
517
GtkListStore *store = (GtkListStore *)gtk_tree_view_get_model((GtkTreeView *)treeview);
521
gboolean dnd_success = FALSE;
522
gboolean delete_selection_data = FALSE;
524
const gchar *name = gtk_widget_get_name (widget);
525
TRACE("%s: att_list_drag_data_received\n", name);
527
// Deal with what we are given from source
528
if( (selection_data != NULL) &&
529
(selection_data->length >= 0))
531
if (context->action == GDK_ACTION_ASK)
533
// Ask the user to move or copy, then set the context action
534
context->action = GDK_ACTION_COPY;
536
if (context->action == GDK_ACTION_MOVE)
537
delete_selection_data = TRUE;
539
_sdata = (gchar*)selection_data-> data;
540
TRACE("string: %s", _sdata);
544
std::vector<std::string> lstFiles;
545
std::string strFiles(_sdata);
546
std::string::size_type nPos = strFiles.find('\n');
547
while(nPos != std::string::npos){
548
std::string strLine = strFiles.substr(0, nPos);
549
replaceall(strLine, "\r", "");
551
strFiles = strFiles.substr(nPos+1);
553
//strip "file://" prefix
554
if(strLine.substr(0, 7) == "file://"){
556
strLine = strLine.substr(8);
558
strLine = strLine.substr(7);
561
lstFiles.push_back(strLine);
563
nPos = strFiles.find('\n');
566
int nMax = lstFiles.size();
569
std::string strMsg(_("Do you want to attach files to the node?\n\n"));
570
for(int i=0; i<nMax; i++){
571
strMsg += lstFiles[i]; //_sdata;
575
gint result = gtkMessageBox(strMsg.c_str(), GTK_BUTTONS_YES_NO);
576
if(GTK_RESPONSE_YES == result)
578
int nIdx = ((FileAttachmentDlg *)data)->m_nNodeIdx;
580
for(int i=0; i<nMax; i++)
582
std::string strLocaleFile;
583
Utf8ToLocale(lstFiles[i].c_str(), strLocaleFile);
585
replaceall(strLocaleFile, "/", "\\");
588
//TOFIX duplicate of on_add_file_clicked in FileAttachmentDialog
589
FILE *pFile = fopen(strLocaleFile.c_str(), "rb");
591
TRACE("%s\n", strerror(errno));
592
std::string strMsg = _("Failed to open input file!\n");
594
strMsg += strLocaleFile;
597
gtkMessageBox(strMsg.c_str());
601
g_objCrashLog.AddMsg("ACTION: add attachment\n");
606
ProgressDlg dlg(200, _("Loading file. Please wait..."), window1);
612
while((nRead = fread(szBuffer, 1, sizeof(szBuffer), pFile)) > 0)
614
info.m_strData.append(szBuffer, nRead);
619
FormatIO_Base::RunLoop();
623
info.nDataSize = info.m_strData.size();
624
info.m_strName = lstFiles[i];
625
std::string::size_type nPos = info.m_strName.find_last_of("\\/");
626
if(nPos != std::string::npos){
627
info.m_strName = info.m_strName.substr(nPos+1);
630
g_doc.GetNodeByIdx(nIdx).m_lstAttachments.push_back(info);
634
gtk_list_store_append(store, &iter);
636
gtk_list_store_set (store, &iter,
637
0, info.m_strName.c_str(),
641
g_doc.SetModified(true);
644
//push document change into undo/redo manager
645
DocActionAtt *pAction = new DocActionAtt;
646
pAction->m_bAddOp = true;
647
pAction->m_info = info;
648
pAction->m_nNodeIdx = pDlg->m_nNodeIdx;
649
pAction->m_nAttIdx = g_doc.GetNodeByIdx(pDlg->m_nNodeIdx).m_lstAttachments.size()-1;
651
g_undoManager.AddAction(pAction);
652
UpdateUndoRedoMenus();
658
if (dnd_success == FALSE)
660
TRACE("DnD data transfer failed!\n");
663
gtk_drag_finish (context, dnd_success, delete_selection_data, time);