source: trunk/Lucide/gui/docInfoDlg.cpp @ 406

Last change on this file since 406 was 406, checked in by dmik, 12 years ago

Added support for copying text from the document information dialog to the clipboard (fixes ticket:142).

File size: 9.5 KB
Line 
1/* ***** BEGIN LICENSE BLOCK *****
2 * Version: CDDL 1.0/LGPL 2.1
3 *
4 * The contents of this file are subject to the COMMON DEVELOPMENT AND
5 * DISTRIBUTION LICENSE (CDDL) Version 1.0 (the "License"); you may not use
6 * this file except in compliance with the License. You may obtain a copy of
7 * the License at http://www.sun.com/cddl/
8 *
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
13 *
14 * The Initial Developer of the Original Code is
15 * Eugene Romanenko, netlabs.org.
16 * Portions created by the Initial Developer are Copyright (C) 2006
17 * the Initial Developer. All Rights Reserved.
18 *
19 * Contributor(s):
20 *
21 * Alternatively, the contents of this file may be used under the terms of
22 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
23 * in which case the provisions of the LGPL are applicable instead of those
24 * above. If you wish to allow use of your version of this file only under the
25 * terms of the LGPL, and not to allow others to use your version of this file
26 * under the terms of the CDDL, indicate your decision by deleting the
27 * provisions above and replace them with the notice and other provisions
28 * required by the LGPL. If you do not delete the provisions above, a recipient
29 * may use your version of this file under the terms of any one of the CDDL
30 * or the LGPL.
31 *
32 * ***** END LICENSE BLOCK ***** */
33
34
35#include "os2all.h"
36
37#include <string>
38
39#include <ludoc.xh>
40
41#include "globals.h"
42#include "luutils.h"
43#include "docInfoDlg.h"
44#include "Lucide_res.h"
45#include "messages.h"
46#include "cpconv.h"
47
48
49DocInfoDlg::DocInfoDlg( HWND hWndFrame, LuDocumentInfo *_dinfo )
50{
51    hFrame   = hWndFrame;
52    dinfo    = _dinfo;
53}
54
55DocInfoDlg::~DocInfoDlg()
56{
57}
58
59void DocInfoDlg::doDialog()
60{
61    WinDlgBox( HWND_DESKTOP, hFrame, docInfoDlgProc,
62               _hmod, IDD_DOCINFO, this );
63    delete this;
64}
65
66
67struct ListRec
68{
69    MINIRECORDCORE miniRecordCore;
70    PSZ value;
71};
72
73
74void DocInfoDlg::insertPair( HWND cntr, const char *key, const char *value )
75{
76    ListRec *r = (ListRec *)WinSendMsg( cntr, CM_ALLOCRECORD,
77        MPFROMLONG( ( sizeof( ListRec ) - sizeof( MINIRECORDCORE ) ) ),
78                                MPFROMSHORT( 1 ) );
79
80    r->miniRecordCore.cb = sizeof( MINIRECORDCORE );
81    r->miniRecordCore.flRecordAttr = 0;
82    r->miniRecordCore.ptlIcon.x = 0;
83    r->miniRecordCore.ptlIcon.y = 0;
84    r->miniRecordCore.pszIcon = newstrdupL( key );
85    r->miniRecordCore.hptrIcon = NULLHANDLE;
86    r->value = newstrdup( value );
87
88    RECORDINSERT ri;
89    ri.cb = sizeof( RECORDINSERT );
90    ri.pRecordParent= NULL;
91    ri.pRecordOrder = (PRECORDCORE)CMA_END;
92    ri.zOrder = (USHORT)CMA_TOP;
93    ri.cRecordsInsert = 1;
94    ri.fInvalidateRecord = TRUE;
95    WinSendMsg( cntr, CM_INSERTRECORD, MPFROMP( r ), MPFROMP( &ri ) );
96}
97
98
99void DocInfoDlg::loadValues( HWND cntr )
100{
101    if ( dinfo == NULL ) {
102        return;
103    }
104
105    if ( dinfo->fields_mask & LU_DOCUMENT_INFO_TITLE ) {
106        insertPair( cntr, DOCINFO_TITLE, dinfo->title );
107    }
108    if ( dinfo->fields_mask & LU_DOCUMENT_INFO_FORMAT ) {
109        insertPair( cntr, DOCINFO_FORMAT, dinfo->format );
110    }
111    if ( dinfo->fields_mask & LU_DOCUMENT_INFO_AUTHOR ) {
112        insertPair( cntr, DOCINFO_AUTHOR, dinfo->author );
113    }
114    if ( dinfo->fields_mask & LU_DOCUMENT_INFO_SUBJECT ) {
115        insertPair( cntr, DOCINFO_SUBJECT, dinfo->subject );
116    }
117    if ( dinfo->fields_mask & LU_DOCUMENT_INFO_KEYWORDS ) {
118        insertPair( cntr, DOCINFO_KEYWORDS, dinfo->keywords );
119    }
120    if ( dinfo->fields_mask & LU_DOCUMENT_INFO_CREATOR ) {
121        insertPair( cntr, DOCINFO_CREATOR, dinfo->creator );
122    }
123    if ( dinfo->fields_mask & LU_DOCUMENT_INFO_PRODUCER ) {
124        insertPair( cntr, DOCINFO_PRODUCER, dinfo->producer );
125    }
126    if ( dinfo->fields_mask & LU_DOCUMENT_INFO_CREATION_DATE ) {
127        insertPair( cntr, DOCINFO_CREATION_DATE,
128                    time2string( dinfo->creation_date ).c_str() );
129    }
130    if ( dinfo->fields_mask & LU_DOCUMENT_INFO_MOD_DATE ) {
131        insertPair( cntr, DOCINFO_MOD_DATE,
132                    time2string( dinfo->modified_date ).c_str() );
133    }
134}
135
136static bool addPropToString( HWND hwndCntr, PRECORDCORE pRec, void *pUser )
137{
138    ListRec *rec = reinterpret_cast<ListRec *>( pRec );
139    std::string *str = static_cast<std::string *>( pUser );
140    if ( !str->empty() )
141        *str += '\n';
142    *str += rec->miniRecordCore.pszIcon;
143    *str += ' ';
144    *str += rec->value;
145    return true;
146}
147
148static bool selectProp( HWND hwndCntr, PRECORDCORE pRec, void *pUser )
149{
150    ListRec *rec = reinterpret_cast<ListRec *>( pRec );
151    return WinSendMsg( hwndCntr, CM_SETRECORDEMPHASIS,
152                       MPFROMP( &rec->miniRecordCore ),
153                       MPFROM2SHORT( TRUE, CRA_SELECTED ) ) == (MRESULT)TRUE;
154}
155
156MRESULT EXPENTRY DocInfoDlg::docInfoDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
157{
158    // This is a static method, so we don't know which instantiation we're
159    // dealing with. But we can get a pseudo-this from the parameter to
160    // WM_INITDLG, which we therafter store with the window and retrieve
161    // as follows:
162    DocInfoDlg *_this = (DocInfoDlg *)WinQueryWindowULong( hwnd, QWL_USER );
163
164    switch (msg)
165    {
166
167        // Dialog has just been created
168        case WM_INITDLG:
169        {
170            // Save the mp2 into our user data so that subsequent calls have
171            // access to the parent C++ object
172            WinSetWindowULong( hwnd, QWL_USER, (ULONG)mp2 );
173            _this = (DocInfoDlg *)mp2;
174            localizeDialog( hwnd );
175            centerWindow( _this->hFrame, hwnd );
176
177            // setup the accelerators
178            WinSetAccelTable( hab, WinLoadAccelTable( hab, _hmod, IDA_DOCINFOACCEL ), hwnd );
179
180            // init container
181            HWND cntr = WinWindowFromID( hwnd, IDC_PROPSLIST );
182            CNRINFO ci;
183            ci.cb = sizeof( CNRINFO );
184            WinSendMsg( cntr, CM_QUERYCNRINFO, MPFROMP( &ci ), MPFROMSHORT( ci.cb ) );
185            ci.flWindowAttr &= ~( CV_NAME | CV_FLOW | CV_TEXT | CV_ICON | CA_DETAILSVIEWTITLES );
186            ci.flWindowAttr |= ( CV_DETAIL | CV_MINI );
187            WinSendMsg( cntr, CM_SETCNRINFO, MPFROMP( &ci ), MPFROMLONG( CMA_FLWINDOWATTR ) );
188
189            PFIELDINFO pFieldInfo = (PFIELDINFO)WinSendMsg( cntr, CM_ALLOCDETAILFIELDINFO,
190                                             MPFROMSHORT( 2 ), MPVOID );
191            PFIELDINFO pFldInfo = pFieldInfo;
192            pFldInfo->cb = sizeof( FIELDINFO );
193            pFldInfo->flData = CFA_STRING | CFA_HORZSEPARATOR;
194            pFldInfo->flTitle = CFA_CENTER;
195            pFldInfo->pTitleData = NULL;
196            pFldInfo->offStruct = FIELDOFFSET( ListRec, miniRecordCore.pszIcon );
197            pFldInfo = pFldInfo->pNextFieldInfo;
198            pFldInfo->cb = sizeof( FIELDINFO );
199            pFldInfo->flData = CFA_STRING | CFA_HORZSEPARATOR;
200            pFldInfo->flTitle = CFA_CENTER;
201            pFldInfo->pTitleData = NULL;
202            pFldInfo->offStruct = FIELDOFFSET( ListRec, value );
203
204            FIELDINFOINSERT fieldInfoInsert;
205            fieldInfoInsert.cb = sizeof( FIELDINFOINSERT );
206            fieldInfoInsert.pFieldInfoOrder = (PFIELDINFO)CMA_FIRST;
207            fieldInfoInsert.cFieldInfoInsert = 2;
208            fieldInfoInsert.fInvalidateFieldInfo = TRUE;
209            WinSendMsg( cntr, CM_INSERTDETAILFIELDINFO,
210                   MPFROMP( pFieldInfo ), MPFROMP( &fieldInfoInsert ) );
211
212            _this->loadValues( cntr );
213
214            return (MRESULT)FALSE;
215        }
216
217        case WM_DESTROY:
218        {
219            HWND cntr = WinWindowFromID( hwnd, IDC_PROPSLIST );
220            ListRec *pRecords = (ListRec *)WinSendMsg( cntr, CM_QUERYRECORD,
221                                MPFROMP( NULL ), MPFROM2SHORT( CMA_FIRST, CMA_ITEMORDER ) );
222            ListRec *pr = pRecords;
223
224            while ( pr != NULL )
225            {
226                delete pr->miniRecordCore.pszIcon;
227                delete pr->value;
228                pr = (ListRec *)WinSendMsg( cntr, CM_QUERYRECORD,
229                                    MPFROMP( pr ), MPFROM2SHORT( CMA_NEXT, CMA_ITEMORDER ) );
230            }
231            WinSendMsg( cntr, CM_REMOVERECORD, MPFROMP( NULL ), MPFROM2SHORT( 0, CMA_FREE ) );
232        }
233        break;
234
235        case WM_COMMAND:
236        {
237            switch( SHORT1FROMMP(mp1) )
238            {
239                case CM_COPY:
240                {
241                    HWND cntr = WinWindowFromID( hwnd, IDC_PROPSLIST );
242                    std::string props;
243                    enumCntrEmphasis( cntr, CRA_SELECTED, addPropToString, &props );
244                    if ( !props.empty()) {
245                        char *utf8 = uniSysToUtf8( props.c_str(), NULL, NULL );
246                        if ( utf8 )
247                            textToClipbrd( hab, utf8 );
248                        delete[] utf8;
249                    }
250                }
251                return (MRESULT)FALSE;
252
253                case CM_SELECTALL:
254                {
255                    HWND cntr = WinWindowFromID( hwnd, IDC_PROPSLIST );
256                    enumCntrRecords( cntr, selectProp, NULL );
257                }
258                return (MRESULT)FALSE;
259
260                default:
261                    break;
262            }
263        }
264        break;
265    }
266    return WinDefDlgProc( hwnd, msg, mp1, mp2 );
267}
268
269
Note: See TracBrowser for help on using the repository browser.