~ubuntu-branches/ubuntu/maverick/notecase/maverick

« back to all changes in this revision

Viewing changes to src/FileAttachmentDlg.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Mitsuya Shibata
  • Date: 2008-01-18 01:54:05 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20080118015405-id2r7kphpxlyjzfi
Tags: 1.7.6-0ubuntu1
* New Upstream Release (Closes LP: #182226)
*  Fix failed assertion when change node level (Closes LP: #137464)
* Exclude help.ncd and any .ncd file from compression (Closes LP: #113959)
* Adapted debian/ directory to upstream deb/ directory
* Add debian/watch file
* Remove debian/README.Debian because it is now unnecessary
* Bump up compat level from 4 to 5
* Updating debian/menu file to use the new menu hierarchy
* Modify debian/control file
*  Bump up Standards-Version field from 3.6.1 to 3.7.3
*  Change Section field from x11 to editors
*  Change Build-Depends debhelper version to >=5, libgtk2.0-dev to >=2.4
*  Move Homepage field from description to regular field

Show diffs side-by-side

added added

removed removed

Lines of Context:
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"
18
20
#include <string>
 
21
#include <errno.h>
 
22
 
 
23
#ifdef _WIN32
 
24
 #include <io.h> //access
 
25
 #define access _access
 
26
#endif
19
27
 
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;
24
34
 
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, 
 
46
        gpointer data);
 
47
gboolean is_format_provided(GdkDragContext *context, GdkAtom target);
 
48
 
31
49
 
32
50
#ifndef min
33
51
 #define min(a,b) (((a)<(b))?(a):(b))
63
81
                                                        1, g_doc.GetNodeByIdx(m_nNodeIdx).m_lstAttachments[i].nDataSize,
64
82
                                                        -1);
65
83
        }
 
84
 
 
85
        if(g_doc.IsReadOnly()){
 
86
                gtkMessageBox(_("The document is read-only! You won't be able to make any changes!"));
 
87
        }
66
88
}
67
89
 
68
90
int FileAttachmentDlg::GetSelRow()
112
134
                gtk_window_set_transient_for(GTK_WINDOW (attachments_dialog), GTK_WINDOW(parent));   //set parent
113
135
#if GTK_CHECK_VERSION(2,4,0) //new API TOFIX set proper version
114
136
        #ifndef _WIN32  //TOFIX API is buggy on Win32 (kills modal dialog state)
115
 
          gtk_window_set_keep_above(GTK_WINDOW (attachments_dialog), TRUE);
 
137
          //gtk_window_set_keep_above(GTK_WINDOW (attachments_dialog), TRUE);
116
138
        #endif
117
139
#endif
118
140
        gtk_widget_realize(attachments_dialog);
128
150
 
129
151
        gtk_widget_set_size_request(treeview, -1, 100);
130
152
 
 
153
        //make the "textview1" a DnD destination
 
154
        static const GtkTargetEntry targets[] = {
 
155
                { "text/uri-list", 0, 0 },
 
156
        };
 
157
        gtk_drag_dest_set(GTK_WIDGET(treeview), GTK_DEST_DEFAULT_ALL, targets, G_N_ELEMENTS (targets), GdkDragAction(GDK_ACTION_COPY));
 
158
 
131
159
        gtk_box_pack_start (GTK_BOX (dialog_vbox6), treeview, FALSE, FALSE, 0);
132
160
        gtk_widget_show (treeview);
133
161
        gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), TRUE);
186
214
        gtk_container_add (GTK_CONTAINER(dialog_action_area6), close_btn);
187
215
        GTK_WIDGET_SET_FLAGS (close_btn, GTK_CAN_DEFAULT);
188
216
 
 
217
        g_signal_connect (G_OBJECT (treeview), "drag-drop",                             G_CALLBACK (att_list_on_drop), this);
 
218
        g_signal_connect (G_OBJECT (treeview), "drag-data-received",    G_CALLBACK (att_list_drag_data_received), this);
 
219
 
189
220
        g_signal_connect(add_btn,   "clicked", G_CALLBACK (on_add_file_clicked), this);
190
221
        g_signal_connect(remove_btn,"clicked", G_CALLBACK (on_remove_file_clicked), this);
191
222
        g_signal_connect(save_btn,  "clicked", G_CALLBACK (on_save_file_clicked), this);
210
241
{
211
242
        FileAttachmentDlg *pDlg = (FileAttachmentDlg *)user_data;
212
243
 
 
244
        if(g_doc.IsReadOnly()){
 
245
                gtkMessageBox(_("Can not change read-only document!"));
 
246
                return;
 
247
        }
 
248
 
213
249
        //load file to binary string
214
250
        FileDialog dlg(true);
215
251
        dlg.SetTitle(_("Add attachment"));
216
252
 
 
253
        //set initial directory from INI (store last used)
 
254
        std::string strDefaultDir;
 
255
        std::string strDir;
 
256
        g_objIni.GetValue("Cache", "LastAttachmentDir", strDir, "");
 
257
        if(!strDir.empty() && 0 == access(strDir.c_str(), 00))
 
258
                strDefaultDir = strDir;
 
259
        else
 
260
                strDefaultDir = GetHomeDir();
 
261
 
 
262
        dlg.SetDirectory(strDefaultDir.c_str());
 
263
 
 
264
 
217
265
        if(dlg.DoModal())
218
266
        {
219
267
                const gchar *filename = dlg.GetFilename();
 
268
                strDefaultDir = dlg.GetDirectory();
220
269
                dlg.Close();
221
270
 
222
 
                FILE *pFile = fopen(filename, "rb");
 
271
                //store last open directory
 
272
                g_objIni.SetValue("Cache", "LastAttachmentDir", strDefaultDir.c_str());
 
273
                g_objIni.Save();
 
274
 
 
275
                std::string strLocaleFile;
 
276
                Utf8ToLocale(filename, strLocaleFile);
 
277
        #ifdef _WIN32
 
278
                replaceall(strLocaleFile, "/", "\\");
 
279
        #endif
 
280
 
 
281
                FILE *pFile = fopen(strLocaleFile.c_str(), "rb");
223
282
                if(!pFile){
224
 
                        gtkMessageBox(_("Failed to open output file!"));
 
283
                        gtkMessageBox(_("Failed to open input file!"));
225
284
                        return;
226
285
                }
227
286
 
287
346
{
288
347
        FileAttachmentDlg *pDlg = (FileAttachmentDlg *)user_data;
289
348
 
 
349
        if(g_doc.IsReadOnly()){
 
350
                gtkMessageBox(_("Can not change read-only document!"));
 
351
                return;
 
352
        }
 
353
 
290
354
        int nSelIdx = pDlg->GetSelRow();
291
355
        if(nSelIdx >= 0)
292
356
        {
344
408
        FileDialog dlg(false);
345
409
        dlg.SetTitle(_("Save data"));
346
410
 
 
411
        //set initial directory from INI (store last used)
 
412
        std::string strDefaultDir;
 
413
        std::string strDir;
 
414
        g_objIni.GetValue("Cache", "LastAttachmentDir", strDir, "");
 
415
        if(!strDir.empty() && 0 == access(strDir.c_str(), 00))
 
416
                strDefaultDir = strDir;
 
417
        else
 
418
                strDefaultDir = GetHomeDir();
 
419
 
 
420
        dlg.SetDirectory(strDefaultDir.c_str());
 
421
        dlg.SetFilename(g_doc.GetNodeByIdx(pDlg->m_nNodeIdx).m_lstAttachments[nSelRow].m_strName.c_str());
 
422
 
347
423
        if(dlg.DoModal())
348
424
        {
349
425
                const gchar *filename = dlg.GetFilename();
 
426
                strDefaultDir = dlg.GetDirectory();
350
427
                dlg.Close();
351
428
 
352
 
                FILE *pFile = fopen(filename, "wb");
 
429
                //store last open directory
 
430
                g_objIni.SetValue("Cache", "LastAttachmentDir", strDefaultDir.c_str());
 
431
                g_objIni.Save();
 
432
 
 
433
                std::string strLocaleFile;
 
434
                Utf8ToLocale(filename, strLocaleFile);
 
435
        #ifdef _WIN32
 
436
                replaceall(strLocaleFile, "/", "\\");
 
437
        #endif
 
438
 
 
439
                FILE *pFile = fopen(strLocaleFile.c_str(), "wb");
353
440
                if(!pFile){
354
441
                        gtkMessageBox(_("Failed to open output file!"));
355
442
                        return;
389
476
        //terminate dialog
390
477
        gtk_dialog_response(GTK_DIALOG(pDlg->m_pDialog), GTK_RESPONSE_OK);
391
478
}
 
479
 
 
480
gboolean att_list_on_drop(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer user_data)
 
481
{
 
482
        if(g_doc.IsReadOnly()){
 
483
                gtkMessageBox(_("Can not change read-only document!"));
 
484
                return FALSE;
 
485
        }
 
486
    
 
487
        TRACE("DnD: att_list_on_drop\n");
 
488
 
 
489
        gboolean  is_valid_drop_site = TRUE;
 
490
 
 
491
        // If the source offers a target
 
492
    if (is_valid_drop_site && context->targets)
 
493
    {
 
494
        GdkAtom target_type;
 
495
                if(is_format_provided(context, atomTextUriList))
 
496
                        target_type = atomTextUriList;
 
497
                else
 
498
                        return FALSE;
 
499
        
 
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);
 
502
    }
 
503
    else
 
504
        {
 
505
                is_valid_drop_site = FALSE;     // No target offered by source => error
 
506
        }
 
507
        
 
508
        return  is_valid_drop_site;
 
509
}
 
510
 
 
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)
 
512
{       
 
513
        TRACE("DnD: att_list_drag_data_received\n");
 
514
 
 
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);
 
518
 
 
519
        gchar   *_sdata;
 
520
 
 
521
        gboolean dnd_success = FALSE;
 
522
        gboolean delete_selection_data = FALSE;
 
523
 
 
524
        const gchar *name = gtk_widget_get_name (widget);
 
525
        TRACE("%s: att_list_drag_data_received\n", name);
 
526
 
 
527
        // Deal with what we are given from source
 
528
        if( (selection_data != NULL) && 
 
529
                (selection_data->length >= 0))
 
530
        {
 
531
                if (context->action == GDK_ACTION_ASK)
 
532
                {
 
533
                        // Ask the user to move or copy, then set the context action
 
534
                        context->action = GDK_ACTION_COPY;
 
535
                }
 
536
                if (context->action == GDK_ACTION_MOVE)
 
537
                        delete_selection_data = TRUE;
 
538
 
 
539
                _sdata = (gchar*)selection_data-> data;
 
540
                TRACE("string: %s", _sdata);
 
541
                dnd_success = TRUE;
 
542
 
 
543
                //
 
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", "");
 
550
 
 
551
                        strFiles = strFiles.substr(nPos+1);
 
552
 
 
553
                        //strip "file://" prefix
 
554
                        if(strLine.substr(0, 7) == "file://"){
 
555
                                #ifdef _WIN32
 
556
                                        strLine = strLine.substr(8);
 
557
                                #else
 
558
                                        strLine = strLine.substr(7);
 
559
                                #endif
 
560
                        }
 
561
                        lstFiles.push_back(strLine);
 
562
 
 
563
                        nPos = strFiles.find('\n');
 
564
                }
 
565
 
 
566
                int nMax = lstFiles.size();
 
567
                if(nMax > 0)
 
568
                {
 
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;
 
572
                                strMsg += "\n";
 
573
                        }
 
574
 
 
575
                        gint result = gtkMessageBox(strMsg.c_str(), GTK_BUTTONS_YES_NO);
 
576
                        if(GTK_RESPONSE_YES == result)
 
577
                        {
 
578
                                int nIdx = ((FileAttachmentDlg *)data)->m_nNodeIdx;
 
579
 
 
580
                                for(int i=0; i<nMax; i++)
 
581
                                {
 
582
                                        std::string strLocaleFile;
 
583
                                        Utf8ToLocale(lstFiles[i].c_str(), strLocaleFile);
 
584
        #ifdef _WIN32
 
585
                                        replaceall(strLocaleFile, "/", "\\");
 
586
        #endif
 
587
 
 
588
                                        //TOFIX duplicate of on_add_file_clicked in FileAttachmentDialog
 
589
                                        FILE *pFile = fopen(strLocaleFile.c_str(), "rb");
 
590
                                        if(!pFile){
 
591
                                                TRACE("%s\n", strerror(errno));
 
592
                                                std::string strMsg = _("Failed to open input file!\n");
 
593
                                                strMsg += "(";
 
594
                                                strMsg += strLocaleFile;
 
595
                                                strMsg += ")";
 
596
 
 
597
                                                gtkMessageBox(strMsg.c_str());
 
598
                                                continue;
 
599
                                        }
 
600
 
 
601
                                        g_objCrashLog.AddMsg("ACTION: add attachment\n");
 
602
 
 
603
                                        AttInfo info;
 
604
 
 
605
                                        //show wait dialog
 
606
                                        ProgressDlg dlg(200, _("Loading file. Please wait..."), window1);
 
607
 
 
608
                                        int nTotal = 0;
 
609
                                        int nLoopCnt = 0;
 
610
                                        char szBuffer[2000];
 
611
                                        size_t nRead = 0;
 
612
                                        while((nRead = fread(szBuffer, 1, sizeof(szBuffer), pFile)) > 0)
 
613
                                        {
 
614
                                                info.m_strData.append(szBuffer, nRead);
 
615
                                                nTotal += nRead;
 
616
                                                nLoopCnt++;
 
617
 
 
618
                                                if(nLoopCnt%10 == 0)
 
619
                                                        FormatIO_Base::RunLoop();
 
620
                                        }
 
621
                                        fclose(pFile);
 
622
 
 
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);
 
628
                                        }
 
629
 
 
630
                                        g_doc.GetNodeByIdx(nIdx).m_lstAttachments.push_back(info);
 
631
 
 
632
                                        //refresh GUI list
 
633
                                        GtkTreeIter iter;
 
634
                                        gtk_list_store_append(store, &iter);
 
635
 
 
636
                                        gtk_list_store_set (store, &iter,
 
637
                                                                                0, info.m_strName.c_str(),
 
638
                                                                                1, info.nDataSize,
 
639
                                                                                -1);
 
640
 
 
641
                                        g_doc.SetModified(true);
 
642
                                        RefreshMainTitle();
 
643
 
 
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;
 
650
 
 
651
                                        g_undoManager.AddAction(pAction);
 
652
                                        UpdateUndoRedoMenus();
 
653
                                }
 
654
                        }
 
655
                }
 
656
        }
 
657
 
 
658
        if (dnd_success == FALSE)
 
659
        {
 
660
                TRACE("DnD data transfer failed!\n");
 
661
        }
 
662
 
 
663
        gtk_drag_finish (context, dnd_success, delete_selection_data, time);
 
664
}