pane.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright 2003, 2004, 2005 Martin Fuchs
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  */
00018 
00019 
00020  //
00021  // Explorer clone
00022  //
00023  // pane.cpp
00024  //
00025  // Martin Fuchs, 23.07.2003
00026  //
00027 
00028 
00029 #include <precomp.h>
00030 
00031 #include "../resource.h"
00032 
00033 
00034 enum IMAGE {
00035     IMG_NONE=-1,    IMG_FILE=0,         IMG_DOCUMENT,   IMG_EXECUTABLE,
00036     IMG_FOLDER,     IMG_OPEN_FOLDER,    IMG_FOLDER_PLUS,IMG_OPEN_PLUS,  IMG_OPEN_MINUS,
00037     IMG_FOLDER_UP,  IMG_FOLDER_CUR
00038 };
00039 
00040 
00041 #define IMAGE_WIDTH         16
00042 #define IMAGE_HEIGHT        13
00043 
00044 
00045 static const LPTSTR g_pos_names[COLUMNS] = {
00046     TEXT(""),           /* symbol */
00047     TEXT("Name"),
00048     TEXT("Type"),
00049     TEXT("Size"),
00050     TEXT("CDate"),
00051     TEXT("ADate"),
00052     TEXT("MDate"),
00053     TEXT("Index/Inode"),
00054     TEXT("Links"),
00055     TEXT("Attributes"),
00056     TEXT("Security"),
00057     TEXT("Content")
00058 };
00059 
00060 static const int g_pos_align[] = {
00061     0,
00062     HDF_LEFT,   /* Name */
00063     HDF_LEFT,   /* Type */
00064     HDF_RIGHT,  /* Size */
00065     HDF_LEFT,   /* CDate */
00066     HDF_LEFT,   /* ADate */
00067     HDF_LEFT,   /* MDate */
00068     HDF_LEFT,   /* Index */
00069     HDF_RIGHT,  /* Links */
00070     HDF_CENTER, /* Attributes */
00071     HDF_LEFT,   /* Security */
00072     HDF_LEFT    /* Content / Description */
00073 };
00074 
00075 
00076 Pane::Pane(HWND hparent, int id, int id_header, Entry* root, bool treePane, int visible_cols)
00077  :  super(CreateWindow(TEXT("ListBox"), TEXT(""), WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|
00078             LBS_DISABLENOSCROLL|LBS_NOINTEGRALHEIGHT|LBS_OWNERDRAWFIXED|LBS_NOTIFY,
00079             0, 0, 0, 0, hparent, (HMENU)id, g_Globals._hInstance, 0)),
00080     _root(root),
00081     _visible_cols(visible_cols),
00082     _treePane(treePane)
00083 {
00084      // insert entries into listbox
00085     Entry* entry = _root;
00086 
00087     if (entry)
00088         insert_entries(entry);
00089 
00090     init();
00091 
00092     create_header(hparent, id_header);
00093 }
00094 
00095 Pane::~Pane()
00096 {
00097     ImageList_Destroy(_himl);
00098 }
00099 
00100 
00101 LRESULT Pane::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
00102 {
00103     switch(nmsg) {
00104       case WM_HSCROLL:
00105         set_header();
00106         break;
00107 
00108       case WM_SETFOCUS: {
00109         FileChildWindow* child = (FileChildWindow*) SendMessage(GetParent(_hwnd), PM_GET_FILEWND_PTR, 0, 0);
00110 
00111         child->set_focus_pane(this);
00112         ListBox_SetSel(_hwnd, TRUE, 1);
00113         /*@todo check menu items */
00114         break;}
00115 
00116       case WM_KEYDOWN: {
00117         FileChildWindow* child = (FileChildWindow*) SendMessage(GetParent(_hwnd), PM_GET_FILEWND_PTR, 0, 0);
00118 
00119         if (wparam == VK_TAB) {
00120             /*@todo SetFocus(g_Globals.hdrivebar) */
00121             child->switch_focus_pane();
00122         }
00123         break;}
00124     }
00125 
00126     return super::WndProc(nmsg, wparam, lparam);
00127 }
00128 
00129 
00130 bool Pane::create_header(HWND hparent, int id)
00131 {
00132     HWND hwnd = CreateWindow(WC_HEADER, 0, WS_CHILD|WS_VISIBLE|HDS_HORZ/*@todo |HDS_BUTTONS + sort orders*/,
00133                                 0, 0, 0, 0, hparent, (HMENU)id, g_Globals._hInstance, 0);
00134     if (!hwnd)
00135         return false;
00136 
00137     SetWindowFont(hwnd, GetStockFont(DEFAULT_GUI_FONT), FALSE);
00138 
00139     HD_ITEM hdi;
00140 
00141     hdi.mask = HDI_TEXT|HDI_WIDTH|HDI_FORMAT;
00142 
00143     for(int idx=0; idx<COLUMNS; idx++) {
00144         hdi.pszText = g_pos_names[idx];
00145         hdi.fmt = HDF_STRING | g_pos_align[idx];
00146         hdi.cxy = _widths[idx];
00147         Header_InsertItem(hwnd, idx, &hdi);
00148     }
00149 
00150     _hwndHeader = hwnd;
00151 
00152     return true;
00153 }
00154 
00155 
00156 void Pane::init()
00157 {
00158     _himl = ImageList_LoadBitmap(g_Globals._hInstance, MAKEINTRESOURCE(IDB_IMAGES), 16, 0, RGB(0,255,0));
00159 
00160     SetWindowFont(_hwnd, _out_wrkr._hfont, FALSE);
00161 
00162      // read the color for compressed files from registry
00163     HKEY hkeyExplorer = 0;
00164     DWORD len = sizeof(_clrCompressed);
00165 
00166     if (RegOpenKey(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer"), &hkeyExplorer) ||
00167         RegQueryValueEx(hkeyExplorer, TEXT("AltColor"), 0, NULL, (LPBYTE)&_clrCompressed, &len) || len!=sizeof(_clrCompressed))
00168         _clrCompressed = RGB(0,0,255);
00169 
00170     if (hkeyExplorer)
00171         RegCloseKey(hkeyExplorer);
00172 
00173      // calculate column widths
00174     _out_wrkr.init_output(_hwnd);
00175     calc_widths(true);
00176 }
00177 
00178 
00179  // calculate prefered width for all visible columns
00180 
00181 bool Pane::calc_widths(bool anyway)
00182 {
00183     int col, x, cx, spc=3*_out_wrkr._spaceSize.cx;
00184     int entries = ListBox_GetCount(_hwnd);
00185     int orgWidths[COLUMNS];
00186     int orgPositions[COLUMNS+1];
00187     HFONT hfontOld;
00188     HDC hdc;
00189     int cnt;
00190 
00191     if (!anyway) {
00192         memcpy(orgWidths, _widths, sizeof(orgWidths));
00193         memcpy(orgPositions, _positions, sizeof(orgPositions));
00194     }
00195 
00196     for(col=0; col<COLUMNS; col++)
00197         _widths[col] = 0;
00198 
00199     hdc = GetDC(_hwnd);
00200     hfontOld = SelectFont(hdc, _out_wrkr._hfont);
00201 
00202     for(cnt=0; cnt<entries; cnt++) {
00203         Entry* entry = (Entry*) ListBox_GetItemData(_hwnd, cnt);
00204 
00205         DRAWITEMSTRUCT dis;
00206 
00207         dis.CtlType       = 0;
00208         dis.CtlID         = 0;
00209         dis.itemID        = 0;
00210         dis.itemAction    = 0;
00211         dis.itemState     = 0;
00212         dis.hwndItem      = _hwnd;
00213         dis.hDC           = hdc;
00214         dis.rcItem.left   = 0;
00215         dis.rcItem.top    = 0;
00216         dis.rcItem.right  = 0;
00217         dis.rcItem.bottom = 0;
00218         /*dis.itemData    = 0; */
00219 
00220         draw_item(&dis, entry, COLUMNS);
00221     }
00222 
00223     SelectObject(hdc, hfontOld);
00224     ReleaseDC(_hwnd, hdc);
00225 
00226     x = 0;
00227     for(col=0; col<COLUMNS; col++) {
00228         _positions[col] = x;
00229         cx = _widths[col];
00230 
00231         if (cx) {
00232             cx += spc;
00233 
00234             if (cx < IMAGE_WIDTH)
00235                 cx = IMAGE_WIDTH;
00236 
00237             _widths[col] = cx;
00238         }
00239 
00240         x += cx;
00241     }
00242 
00243     _positions[COLUMNS] = x;
00244 
00245     ListBox_SetHorizontalExtent(_hwnd, x);
00246 
00247      // no change?
00248     if (!memcmp(orgWidths, _widths, sizeof(orgWidths)))
00249         return FALSE;
00250 
00251      // don't move, if only collapsing an entry
00252     if (!anyway && _widths[0]<orgWidths[0] &&
00253         !memcmp(orgWidths+1, _widths+1, sizeof(orgWidths)-sizeof(int))) {
00254         _widths[0] = orgWidths[0];
00255         memcpy(_positions, orgPositions, sizeof(orgPositions));
00256 
00257         return FALSE;
00258     }
00259 
00260     InvalidateRect(_hwnd, 0, TRUE);
00261 
00262     return TRUE;
00263 }
00264 
00265 
00266 static void format_date(const FILETIME* ft, TCHAR* buffer, int visible_cols)
00267 {
00268     SYSTEMTIME systime;
00269     FILETIME lft;
00270     int len = 0;
00271 
00272     *buffer = TEXT('\0');
00273 
00274     if (!ft->dwLowDateTime && !ft->dwHighDateTime)
00275         return;
00276 
00277     if (!FileTimeToLocalFileTime(ft, &lft))
00278         {err: lstrcpy(buffer,TEXT("???")); return;}
00279 
00280     if (!FileTimeToSystemTime(&lft, &systime))
00281         goto err;
00282 
00283     if (visible_cols & COL_DATE) {
00284         len = GetDateFormat(LOCALE_USER_DEFAULT, 0, &systime, 0, buffer, BUFFER_LEN);
00285         if (!len)
00286             goto err;
00287     }
00288 
00289     if (visible_cols & COL_TIME) {
00290         if (len)
00291             buffer[len-1] = ' ';
00292 
00293         buffer[len++] = ' ';
00294 
00295         if (!GetTimeFormat(LOCALE_USER_DEFAULT, 0, &systime, 0, buffer+len, BUFFER_LEN-len))
00296             buffer[len] = TEXT('\0');
00297     }
00298 }
00299 
00300 
00301 void Pane::draw_item(LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol)
00302 {
00303     TCHAR buffer[BUFFER_LEN];
00304     DWORD attrs;
00305     int visible_cols = _visible_cols;
00306     COLORREF bkcolor, textcolor;
00307     RECT focusRect = dis->rcItem;
00308     enum IMAGE img;
00309     int img_pos, cx;
00310     int col = 0;
00311 
00312     if (entry) {
00313         attrs = entry->_data.dwFileAttributes;
00314 
00315         if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
00316             if (entry->_data.cFileName[0]==TEXT('.') && entry->_data.cFileName[1]==TEXT('.')
00317                     && entry->_data.cFileName[2]==TEXT('\0'))
00318                 img = IMG_FOLDER_UP;
00319             else if (entry->_data.cFileName[0]==TEXT('.') && entry->_data.cFileName[1]==TEXT('\0'))
00320                 img = IMG_FOLDER_CUR;
00321             else if ((_treePane && (dis->itemState&ODS_FOCUS)))
00322                 img = IMG_OPEN_FOLDER;
00323             else
00324                 img = IMG_FOLDER;
00325         } else {
00326             if (attrs & ATTRIBUTE_EXECUTABLE)
00327                 img = IMG_EXECUTABLE;
00328             else if (entry->_type_name)
00329                 img = IMG_DOCUMENT;
00330             else
00331                 img = IMG_FILE;
00332         }
00333     } else {
00334         attrs = 0;
00335         img = IMG_NONE;
00336     }
00337 
00338     if (_treePane) {
00339         if (entry) {
00340             img_pos = dis->rcItem.left + entry->_level*(IMAGE_WIDTH+_out_wrkr._spaceSize.cx);
00341 
00342             if (calcWidthCol == -1) {
00343                 int x;
00344                 int y = dis->rcItem.top + IMAGE_HEIGHT/2;
00345                 Entry* up;
00346                 RECT rt_clip;
00347                 HRGN hrgn_org = CreateRectRgn(0, 0, 0, 0);
00348                 HRGN hrgn;
00349 
00350                 rt_clip.left   = dis->rcItem.left;
00351                 rt_clip.top    = dis->rcItem.top;
00352                 rt_clip.right  = dis->rcItem.left+_widths[col];
00353                 rt_clip.bottom = dis->rcItem.bottom;
00354 
00355                 hrgn = CreateRectRgnIndirect(&rt_clip);
00356 
00357                 if (!GetClipRgn(dis->hDC, hrgn_org)) {
00358                     DeleteObject(hrgn_org);
00359                     hrgn_org = 0;
00360                 }
00361 
00362                 //HGDIOBJ holdPen = SelectObject(dis->hDC, GetStockObject(BLACK_PEN));
00363                 ExtSelectClipRgn(dis->hDC, hrgn, RGN_AND);
00364                 DeleteObject(hrgn);
00365 
00366                 if ((up=entry->_up) != NULL) {
00367                     MoveToEx(dis->hDC, img_pos-IMAGE_WIDTH/2, y, 0);
00368                     LineTo(dis->hDC, img_pos-2, y);
00369 
00370                     x = img_pos - IMAGE_WIDTH/2;
00371 
00372                     do {
00373                         x -= IMAGE_WIDTH+_out_wrkr._spaceSize.cx;
00374 
00375                         if (up->_next) {
00376 #ifndef _LEFT_FILES
00377                             bool following_child = (up->_next->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0; // a directory?
00378 
00379                             if (!following_child) {
00380                                 for(Entry*n=up->_next; n; n=n->_next)
00381                                     if (n->_down) { // any file with NTFS sub-streams?
00382                                         following_child = true;
00383                                         break;
00384                                     }
00385                             }
00386 
00387                             if (following_child)
00388 #endif
00389                             {
00390                                 MoveToEx(dis->hDC, x, dis->rcItem.top, 0);
00391                                 LineTo(dis->hDC, x, dis->rcItem.bottom);
00392                             }
00393                         }
00394                     } while((up=up->_up) != NULL);
00395                 }
00396 
00397                 x = img_pos - IMAGE_WIDTH/2;
00398 
00399                 MoveToEx(dis->hDC, x, dis->rcItem.top, 0);
00400                 LineTo(dis->hDC, x, y);
00401 
00402                 if (entry->_next) {
00403 #ifndef _LEFT_FILES
00404                     bool following_child = (entry->_next->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0;  // a directory?
00405 
00406                     if (!following_child) {
00407                         for(Entry*n=entry->_next; n; n=n->_next)
00408                             if (n->_down) { // any file with NTFS sub-streams?
00409                                 following_child = true;
00410                                 break;
00411                             }
00412                     }
00413 
00414                     if (following_child)
00415 #endif
00416                         LineTo(dis->hDC, x, dis->rcItem.bottom);
00417                 }
00418 
00419                 if (entry->_down && entry->_expanded) {
00420                     x += IMAGE_WIDTH + _out_wrkr._spaceSize.cx;
00421                     MoveToEx(dis->hDC, x, dis->rcItem.top+IMAGE_HEIGHT, 0);
00422                     LineTo(dis->hDC, x, dis->rcItem.bottom);
00423                 }
00424 
00425                 SelectClipRgn(dis->hDC, hrgn_org);
00426                 if (hrgn_org) DeleteObject(hrgn_org);
00427                 //SelectObject(dis->hDC, holdPen);
00428             } else if (calcWidthCol==col || calcWidthCol==COLUMNS) {
00429                 int right = img_pos + IMAGE_WIDTH - _out_wrkr._spaceSize.cx;
00430 
00431                 if (right > _widths[col])
00432                     _widths[col] = right;
00433             }
00434         } else  {
00435             img_pos = dis->rcItem.left;
00436         }
00437     } else {
00438         img_pos = dis->rcItem.left;
00439 
00440         if (calcWidthCol==col || calcWidthCol==COLUMNS)
00441             _widths[col] = IMAGE_WIDTH;
00442     }
00443 
00444     if (calcWidthCol == -1) {
00445         focusRect.left = img_pos -2;
00446 
00447         if (attrs & FILE_ATTRIBUTE_COMPRESSED)
00448             textcolor = _clrCompressed;
00449         else
00450             textcolor = RGB(0,0,0);
00451 
00452         if (dis->itemState & ODS_FOCUS) {
00453             textcolor = GetSysColor(COLOR_HIGHLIGHTTEXT);
00454             bkcolor = GetSysColor(COLOR_HIGHLIGHT);
00455         } else {
00456             bkcolor = GetSysColor(COLOR_WINDOW);
00457         }
00458 
00459         HBRUSH hbrush = CreateSolidBrush(bkcolor);
00460         FillRect(dis->hDC, &focusRect, hbrush);
00461         DeleteObject(hbrush);
00462 
00463         SetBkMode(dis->hDC, TRANSPARENT);
00464         SetTextColor(dis->hDC, textcolor);
00465 
00466         cx = _widths[col];
00467 
00468         if (cx && img!=IMG_NONE) {
00469             if (cx > IMAGE_WIDTH)
00470                 cx = IMAGE_WIDTH;
00471 
00472             if (entry->_icon_id > ICID_NONE)
00473                 g_Globals._icon_cache.get_icon(entry->_icon_id).draw(dis->hDC, img_pos, dis->rcItem.top, cx, GetSystemMetrics(SM_CYSMICON), bkcolor, 0);
00474             else
00475                 ImageList_DrawEx(_himl, img, dis->hDC,
00476                                  img_pos, dis->rcItem.top, cx,
00477                                  IMAGE_HEIGHT, bkcolor, CLR_DEFAULT, ILD_NORMAL);
00478         }
00479     }
00480 
00481     if (!entry)
00482         return;
00483 
00484     ++col;
00485 
00486      // output file name
00487     if (calcWidthCol == -1)
00488         _out_wrkr.output_text(dis, _positions, col, entry->_display_name, 0);
00489     else if (calcWidthCol==col || calcWidthCol==COLUMNS)
00490         calc_width(dis, col, entry->_display_name);
00491     ++col;
00492 
00493      // output type/class name
00494     if (visible_cols & COL_TYPE) {
00495         if (calcWidthCol == -1)
00496             _out_wrkr.output_text(dis, _positions, col, entry->_type_name? entry->_type_name: TEXT(""), 0);
00497         else if (calcWidthCol==col || calcWidthCol==COLUMNS)
00498             calc_width(dis, col, entry->_type_name? entry->_type_name: TEXT(""));
00499     }
00500     ++col;
00501 
00502      // display file size
00503     if (visible_cols & COL_SIZE) {
00504         ULONGLONG size = ((ULONGLONG)entry->_data.nFileSizeHigh << 32) | entry->_data.nFileSizeLow;
00505 
00506         _stprintf(buffer, TEXT("%") LONGLONGARG TEXT("d"), size);
00507 
00508         if (calcWidthCol == -1)
00509             _out_wrkr.output_number(dis, _positions, col, buffer);
00510         else if (calcWidthCol==col || calcWidthCol==COLUMNS)
00511             calc_width(dis, col, buffer);   ///@todo not in every case time enough
00512     }
00513     ++col;
00514 
00515      // display file date
00516     if (visible_cols & (COL_DATE|COL_TIME)) {
00517         format_date(&entry->_data.ftCreationTime, buffer, visible_cols);
00518         if (calcWidthCol == -1)
00519             _out_wrkr.output_text(dis, _positions, col, buffer, 0);
00520         else if (calcWidthCol==col || calcWidthCol==COLUMNS)
00521             calc_width(dis, col, buffer);
00522         ++col;
00523 
00524         format_date(&entry->_data.ftLastAccessTime, buffer, visible_cols);
00525         if (calcWidthCol == -1)
00526             _out_wrkr.output_text(dis,_positions,  col, buffer, 0);
00527         else if (calcWidthCol==col || calcWidthCol==COLUMNS)
00528             calc_width(dis, col, buffer);
00529         ++col;
00530 
00531         format_date(&entry->_data.ftLastWriteTime, buffer, visible_cols);
00532         if (calcWidthCol == -1)
00533             _out_wrkr.output_text(dis, _positions, col, buffer, 0);
00534         else if (calcWidthCol==col || calcWidthCol==COLUMNS)
00535             calc_width(dis, col, buffer);
00536         ++col;
00537     } else
00538         col += 3;
00539 
00540     if (entry->_bhfi_valid) {
00541         ULONGLONG index = ((ULONGLONG)entry->_bhfi.nFileIndexHigh << 32) | entry->_bhfi.nFileIndexLow;
00542 
00543         if (visible_cols & COL_INDEX) {
00544             _stprintf(buffer, TEXT("%") LONGLONGARG TEXT("X"), index);
00545 
00546             if (calcWidthCol == -1)
00547                 _out_wrkr.output_text(dis, _positions, col, buffer, DT_RIGHT);
00548             else if (calcWidthCol==col || calcWidthCol==COLUMNS)
00549                 calc_width(dis, col, buffer);
00550 
00551             ++col;
00552         }
00553 
00554         if (visible_cols & COL_LINKS) {
00555             wsprintf(buffer, TEXT("%d"), entry->_bhfi.nNumberOfLinks);
00556 
00557             if (calcWidthCol == -1)
00558                 _out_wrkr.output_text(dis, _positions, col, buffer, DT_RIGHT);
00559             else if (calcWidthCol==col || calcWidthCol==COLUMNS)
00560                 calc_width(dis, col, buffer);
00561 
00562             ++col;
00563         }
00564     } else
00565         col += 2;
00566 
00567      // show file attributes
00568     if (visible_cols & COL_ATTRIBUTES) {
00569         lstrcpy(buffer, TEXT(" \t \t \t \t \t \t \t \t \t \t \t \t \t \t "));
00570 
00571         if (attrs & FILE_ATTRIBUTE_NORMAL)                  buffer[ 0] = 'N';
00572         else {
00573             if (attrs & FILE_ATTRIBUTE_READONLY)            buffer[ 2] = 'R';
00574             if (attrs & FILE_ATTRIBUTE_HIDDEN)              buffer[ 4] = 'H';
00575             if (attrs & FILE_ATTRIBUTE_SYSTEM)              buffer[ 6] = 'S';
00576             if (attrs & FILE_ATTRIBUTE_ARCHIVE)             buffer[ 8] = 'A';
00577             if (attrs & FILE_ATTRIBUTE_COMPRESSED)          buffer[10] = 'C';
00578             if (attrs & FILE_ATTRIBUTE_DIRECTORY)           buffer[12] = 'D';
00579             if (attrs & FILE_ATTRIBUTE_ENCRYPTED)           buffer[14] = 'E';
00580             if (attrs & FILE_ATTRIBUTE_TEMPORARY)           buffer[16] = 'T';
00581             if (attrs & FILE_ATTRIBUTE_SPARSE_FILE)         buffer[18] = 'P';
00582             if (attrs & FILE_ATTRIBUTE_REPARSE_POINT)       buffer[20] = 'Q';
00583             if (attrs & FILE_ATTRIBUTE_OFFLINE)             buffer[22] = 'O';
00584             if (attrs & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED) buffer[24] = 'X';
00585             if (attrs & ATTRIBUTE_EXECUTABLE)               buffer[26] = 'x';
00586             if (attrs & ATTRIBUTE_SYMBOLIC_LINK)            buffer[28] = 'L';
00587         }
00588 
00589         if (calcWidthCol == -1)
00590             _out_wrkr.output_tabbed_text(dis, _positions, col, buffer);
00591         else if (calcWidthCol==col || calcWidthCol==COLUMNS)
00592             calc_tabbed_width(dis, col, buffer);
00593     }
00594     ++col;
00595 
00596 /*TODO
00597     if (flags.security) {
00598         DWORD rights = get_access_mask();
00599 
00600         tcscpy(buffer, TEXT(" \t \t \t  \t  \t \t \t  \t  \t \t \t "));
00601 
00602         if (rights & FILE_READ_DATA)            buffer[ 0] = 'R';
00603         if (rights & FILE_WRITE_DATA)           buffer[ 2] = 'W';
00604         if (rights & FILE_APPEND_DATA)          buffer[ 4] = 'A';
00605         if (rights & FILE_READ_EA)              {buffer[6] = 'entry'; buffer[ 7] = 'R';}
00606         if (rights & FILE_WRITE_EA)             {buffer[9] = 'entry'; buffer[10] = 'W';}
00607         if (rights & FILE_EXECUTE)              buffer[12] = 'X';
00608         if (rights & FILE_DELETE_CHILD)         buffer[14] = 'D';
00609         if (rights & FILE_READ_ATTRIBUTES)      {buffer[16] = 'a'; buffer[17] = 'R';}
00610         if (rights & FILE_WRITE_ATTRIBUTES)     {buffer[19] = 'a'; buffer[20] = 'W';}
00611         if (rights & WRITE_DAC)                 buffer[22] = 'C';
00612         if (rights & WRITE_OWNER)               buffer[24] = 'O';
00613         if (rights & SYNCHRONIZE)               buffer[26] = 'S';
00614 
00615         output_text(dis, col++, buffer, DT_LEFT, 3, psize);
00616     }
00617 
00618     if (flags.description) {
00619         get_description(buffer);
00620         output_text(dis, col++, buffer, 0, psize);
00621     }
00622 */
00623     ++col;
00624 
00625      // output content / symbolic link target / comment
00626     if (visible_cols & COL_CONTENT) {
00627         if (calcWidthCol == -1)
00628             _out_wrkr.output_text(dis, _positions, col, entry->_content? entry->_content: TEXT(""), 0);
00629         else if (calcWidthCol==col || calcWidthCol==COLUMNS)
00630             calc_width(dis, col, entry->_content? entry->_content: TEXT(""));
00631     }
00632 }
00633 
00634 
00635 void Pane::calc_width(LPDRAWITEMSTRUCT dis, int col, LPCTSTR str)
00636 {
00637     RECT rt = {0, 0, 0, 0};
00638 
00639     DrawText(dis->hDC, (LPTSTR)str, -1, &rt, DT_CALCRECT|DT_SINGLELINE|DT_NOPREFIX);
00640 
00641     if (rt.right > _widths[col])
00642         _widths[col] = rt.right;
00643 }
00644 
00645 void Pane::calc_tabbed_width(LPDRAWITEMSTRUCT dis, int col, LPCTSTR str)
00646 {
00647     RECT rt = {0, 0, 0, 0};
00648 
00649 /*  DRAWTEXTPARAMS dtp = {sizeof(DRAWTEXTPARAMS), 2};
00650     DrawTextEx(dis->hDC, (LPTSTR)str, -1, &rt, DT_CALCRECT|DT_SINGLELINE|DT_NOPREFIX|DT_EXPANDTABS|DT_TABSTOP, &dtp);*/
00651 
00652     DrawText(dis->hDC, (LPTSTR)str, -1, &rt, DT_CALCRECT|DT_SINGLELINE|DT_EXPANDTABS|DT_TABSTOP|(2<<8));
00653 
00654     if (rt.right > _widths[col])
00655         _widths[col] = rt.right;
00656 }
00657 
00658 
00659  // insert listbox entries after index idx
00660 
00661 int Pane::insert_entries(Entry* dir, int idx)
00662 {
00663     Entry* entry = dir;
00664 
00665     if (!entry)
00666         return idx;
00667 
00668     for(; entry; entry=entry->_next) {
00669 #ifndef _LEFT_FILES
00670         if (_treePane &&
00671             !(entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) &&    // not a directory?
00672             !entry->_down)  // not a file with NTFS sub-streams?
00673             continue;
00674 #endif
00675 
00676          // don't display entries "." and ".." in the left pane
00677         if (_treePane && (entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
00678                 && entry->_data.cFileName[0]==TEXT('.'))
00679             if (entry->_data.cFileName[1]==TEXT('\0') ||
00680                 (entry->_data.cFileName[1]==TEXT('.') && entry->_data.cFileName[2]==TEXT('\0')))
00681                 continue;
00682 
00683         if (idx != -1)
00684             ++idx;
00685 
00686         ListBox_InsertItemData(_hwnd, idx, entry);
00687 
00688         if (_treePane && entry->_expanded)
00689             idx = insert_entries(entry->_down, idx);
00690     }
00691 
00692     return idx;
00693 }
00694 
00695 
00696 void Pane::set_header()
00697 {
00698     HD_ITEM item;
00699     int scroll_pos = GetScrollPos(_hwnd, SB_HORZ);
00700     int i=0, x=0;
00701 
00702     item.mask = HDI_WIDTH;
00703     item.cxy = 0;
00704 
00705     for(; x+_widths[i]<scroll_pos && i<COLUMNS; i++) {
00706         x += _widths[i];
00707         Header_SetItem(_hwndHeader, i, &item);
00708     }
00709 
00710     if (i < COLUMNS) {
00711         x += _widths[i];
00712         item.cxy = x - scroll_pos;
00713         Header_SetItem(_hwndHeader, i++, &item);
00714 
00715         for(; i<COLUMNS; i++) {
00716             item.cxy = _widths[i];
00717             x += _widths[i];
00718             Header_SetItem(_hwndHeader, i, &item);
00719         }
00720     }
00721 }
00722 
00723 
00724  // calculate one prefered column width
00725 
00726 void Pane::calc_single_width(int col)
00727 {
00728     HFONT hfontOld;
00729     int x, cx;
00730     int cnt;
00731     HDC hdc;
00732 
00733     int entries = ListBox_GetCount(_hwnd);
00734 
00735     _widths[col] = 0;
00736 
00737     hdc = GetDC(_hwnd);
00738     hfontOld = SelectFont(hdc, _out_wrkr._hfont);
00739 
00740     for(cnt=0; cnt<entries; cnt++) {
00741         Entry* entry = (Entry*) ListBox_GetItemData(_hwnd, cnt);
00742 
00743         DRAWITEMSTRUCT dis;
00744 
00745         dis.CtlType       = 0;
00746         dis.CtlID         = 0;
00747         dis.itemID        = 0;
00748         dis.itemAction    = 0;
00749         dis.itemState     = 0;
00750         dis.hwndItem      = _hwnd;
00751         dis.hDC           = hdc;
00752         dis.rcItem.left   = 0;
00753         dis.rcItem.top    = 0;
00754         dis.rcItem.right  = 0;
00755         dis.rcItem.bottom = 0;
00756         /*dis.itemData    = 0; */
00757 
00758         draw_item(&dis, entry, col);
00759     }
00760 
00761     SelectObject(hdc, hfontOld);
00762     ReleaseDC(_hwnd, hdc);
00763 
00764     cx = _widths[col];
00765 
00766     if (cx) {
00767         cx += 3*_out_wrkr._spaceSize.cx;
00768 
00769         if (cx < IMAGE_WIDTH)
00770             cx = IMAGE_WIDTH;
00771     }
00772 
00773     _widths[col] = cx;
00774 
00775     x = _positions[col] + cx;
00776 
00777     for(; col<COLUMNS; ) {
00778         _positions[++col] = x;
00779         x += _widths[col];
00780     }
00781 
00782     ListBox_SetHorizontalExtent(_hwnd, x);
00783 }
00784 
00785 
00786 int Pane::Notify(int id, NMHDR* pnmh)
00787 {
00788     switch(pnmh->code) {
00789         case HDN_TRACK:
00790         case HDN_ENDTRACK: {
00791             HD_NOTIFY* phdn = (HD_NOTIFY*) pnmh;
00792             int idx = phdn->iItem;
00793             int dx = phdn->pitem->cxy - _widths[idx];
00794             int i;
00795 
00796             ClientRect clnt(_hwnd);
00797 
00798              // move immediate to simulate HDS_FULLDRAG (for now [04/2000] not realy needed with WINELIB)
00799             Header_SetItem(_hwndHeader, idx, phdn->pitem);
00800 
00801             _widths[idx] += dx;
00802 
00803             for(i=idx; ++i<=COLUMNS; )
00804                 _positions[i] += dx;
00805 
00806             {
00807                 int scroll_pos = GetScrollPos(_hwnd, SB_HORZ);
00808                 RECT rt_scr;
00809                 RECT rt_clip;
00810 
00811                 rt_scr.left   = _positions[idx+1]-scroll_pos;
00812                 rt_scr.top    = 0;
00813                 rt_scr.right  = clnt.right;
00814                 rt_scr.bottom = clnt.bottom;
00815 
00816                 rt_clip.left   = _positions[idx]-scroll_pos;
00817                 rt_clip.top    = 0;
00818                 rt_clip.right  = clnt.right;
00819                 rt_clip.bottom = clnt.bottom;
00820 
00821                 if (rt_scr.left < 0) rt_scr.left = 0;
00822                 if (rt_clip.left < 0) rt_clip.left = 0;
00823 
00824                 ScrollWindowEx(_hwnd, dx, 0, &rt_scr, &rt_clip, 0, 0, SW_INVALIDATE);
00825 
00826                 rt_clip.right = _positions[idx+1];
00827                 RedrawWindow(_hwnd, &rt_clip, 0, RDW_INVALIDATE|RDW_UPDATENOW);
00828 
00829                 if (pnmh->code == HDN_ENDTRACK) {
00830                     ListBox_SetHorizontalExtent(_hwnd, _positions[COLUMNS]);
00831 
00832                     if (GetScrollPos(_hwnd, SB_HORZ) != scroll_pos)
00833                         set_header();
00834                 }
00835             }
00836 
00837             return 0;
00838         }
00839 
00840         case HDN_DIVIDERDBLCLICK: {
00841             HD_NOTIFY* phdn = (HD_NOTIFY*) pnmh;
00842             HD_ITEM item;
00843 
00844             calc_single_width(phdn->iItem);
00845             item.mask = HDI_WIDTH;
00846             item.cxy = _widths[phdn->iItem];
00847 
00848             Header_SetItem(_hwndHeader, phdn->iItem, &item);
00849             InvalidateRect(_hwnd, 0, TRUE);
00850             break;}
00851 
00852         default:
00853             return super::Notify(id, pnmh);
00854     }
00855 
00856     return 0;
00857 }
00858 
00859 
00860 OutputWorker::OutputWorker()
00861 {
00862     _hfont = CreateFont(-MulDiv(8,GetDeviceCaps(WindowCanvas(0),LOGPIXELSY),72), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TEXT("MS Sans Serif"));
00863 }
00864 
00865 void OutputWorker::init_output(HWND hwnd)
00866 {
00867     TCHAR b[16];
00868 
00869     WindowCanvas canvas(hwnd);
00870 
00871     if (GetNumberFormat(LOCALE_USER_DEFAULT, 0, TEXT("1000"), 0, b, 16) > 4)
00872         _num_sep = b[1];
00873     else
00874         _num_sep = TEXT('.');
00875 
00876     FontSelection font(canvas, _hfont);
00877     GetTextExtentPoint32(canvas, TEXT(" "), 1, &_spaceSize);
00878 }
00879 
00880 
00881 void OutputWorker::output_text(LPDRAWITEMSTRUCT dis, int* positions, int col, LPCTSTR str, DWORD flags)
00882 {
00883     int x = dis->rcItem.left;
00884     RECT rt;
00885 
00886     rt.left   = x+positions[col]+_spaceSize.cx;
00887     rt.top    = dis->rcItem.top;
00888     rt.right  = x+positions[col+1]-_spaceSize.cx;
00889     rt.bottom = dis->rcItem.bottom;
00890 
00891     DrawText(dis->hDC, (LPTSTR)str, -1, &rt, DT_SINGLELINE|DT_NOPREFIX|flags);
00892 }
00893 
00894 void OutputWorker::output_tabbed_text(LPDRAWITEMSTRUCT dis, int* positions, int col, LPCTSTR str)
00895 {
00896     int x = dis->rcItem.left;
00897     RECT rt;
00898 
00899     rt.left   = x+positions[col]+_spaceSize.cx;
00900     rt.top    = dis->rcItem.top;
00901     rt.right  = x+positions[col+1]-_spaceSize.cx;
00902     rt.bottom = dis->rcItem.bottom;
00903 
00904 /*  DRAWTEXTPARAMS dtp = {sizeof(DRAWTEXTPARAMS), 2};
00905     DrawTextEx(dis->hDC, (LPTSTR)str, -1, &rt, DT_SINGLELINE|DT_NOPREFIX|DT_EXPANDTABS|DT_TABSTOP, &dtp);*/
00906 
00907     DrawText(dis->hDC, (LPTSTR)str, -1, &rt, DT_SINGLELINE|DT_EXPANDTABS|DT_TABSTOP|(2<<8));
00908 }
00909 
00910 void OutputWorker::output_number(LPDRAWITEMSTRUCT dis, int* positions, int col, LPCTSTR str)
00911 {
00912     int x = dis->rcItem.left;
00913     RECT rt;
00914     LPCTSTR s = str;
00915     TCHAR b[128];
00916     LPTSTR d = b;
00917     int pos;
00918 
00919     rt.left   = x+positions[col]+_spaceSize.cx;
00920     rt.top    = dis->rcItem.top;
00921     rt.right  = x+positions[col+1]-_spaceSize.cx;
00922     rt.bottom = dis->rcItem.bottom;
00923 
00924     if (*s)
00925         *d++ = *s++;
00926 
00927      // insert number separator characters
00928     pos = lstrlen(s) % 3;
00929 
00930     while(*s)
00931         if (pos--)
00932             *d++ = *s++;
00933         else {
00934             *d++ = _num_sep;
00935             pos = 3;
00936         }
00937 
00938     DrawText(dis->hDC, b, d-b, &rt, DT_RIGHT|DT_SINGLELINE|DT_NOPREFIX|DT_END_ELLIPSIS);
00939 }
00940 
00941 
00942 BOOL Pane::command(UINT cmd)
00943 {
00944     switch(cmd) {
00945         case ID_VIEW_NAME:
00946             if (_visible_cols) {
00947                 _visible_cols = 0;
00948                 calc_widths(true);
00949                 set_header();
00950                 InvalidateRect(_hwnd, 0, TRUE);
00951                 MenuInfo* menu_info = Frame_GetMenuInfo(GetParent(_hwnd));
00952                 if (menu_info) {
00953                     CheckMenuItem(menu_info->_hMenuView, ID_VIEW_NAME, MF_BYCOMMAND|MF_CHECKED);
00954                     CheckMenuItem(menu_info->_hMenuView, ID_VIEW_ALL_ATTRIBUTES, MF_BYCOMMAND);
00955                     CheckMenuItem(menu_info->_hMenuView, ID_VIEW_SELECTED_ATTRIBUTES, MF_BYCOMMAND);
00956                 }
00957             }
00958             break;
00959 
00960         case ID_VIEW_ALL_ATTRIBUTES:
00961             if (_visible_cols != COL_ALL) {
00962                 _visible_cols = COL_ALL;
00963                 calc_widths(true);
00964                 set_header();
00965                 InvalidateRect(_hwnd, 0, TRUE);
00966                 MenuInfo* menu_info = Frame_GetMenuInfo(GetParent(_hwnd));
00967                 if (menu_info) {
00968                     CheckMenuItem(menu_info->_hMenuView, ID_VIEW_NAME, MF_BYCOMMAND);
00969                     CheckMenuItem(menu_info->_hMenuView, ID_VIEW_ALL_ATTRIBUTES, MF_BYCOMMAND|MF_CHECKED);
00970                     CheckMenuItem(menu_info->_hMenuView, ID_VIEW_SELECTED_ATTRIBUTES, MF_BYCOMMAND);
00971                 }
00972             }
00973             break;
00974 
00975         case ID_PREFERED_SIZES: {
00976             calc_widths(true);
00977             set_header();
00978             InvalidateRect(_hwnd, 0, TRUE);
00979             break;}
00980 
00981                 /*@todo more command ids... */
00982 
00983         default:
00984             return FALSE;
00985     }
00986 
00987     return TRUE;
00988 }
00989 
00990 MainFrameBase* Pane::get_frame()
00991 {
00992     HWND owner = GetParent(_hwnd);
00993 
00994     return (MainFrameBase*)owner;
00995 }

ROS Explorer Source Code Documentation
generated on 02.01.2013 by doxygen

ROS Explorer Homepage