OZ++ Class: FTFileListView |
/****************************************************************************** * * Copyright (c) 2015 TOSHIYUKI ARAI. ALL RIGHTS RESERVED. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer. * * 2. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * FTFileListView.h * *****************************************************************************/ #include <oz++/motif/ScrolledWindow.h> #include <oz++/motif/BulletinBoard.h> #include <oz++/motif/Color.h> #include <oz++/motif/PixmapFile.h> #include <oz++/xft/FTFont.h> #include <oz++/xft/FTColumnLayout.h> #include <oz++/xft/FTMultiColumn.h> #include <oz++/SmartArray.h> #include <oz++/FileAttributes.h> #include <oz++/DirectoryScanner.h> #include <oz++/MonetaryFormatter.h> #include <oz++/FileAttributes.h> #include <oz++/LocalTime.h> #include <oz++/SmartPtrs.h> namespace OZ { const char* XmNsizeUnitKB = "sizeUnitKB"; const char* XmNfolderIconFile = "folderIconFile"; const char* XmNfileIconFile = "fileIconFile"; class FTFileListView: public ScrolledWindow { public: typedef enum { DIR = 1, FILE = 2, } FILE_TYPE; private: FTFont* font; PixmapFile* folderIcon; PixmapFile* fileIcon; BulletinBoard* bboard; FTColumnLayout* columnLayout; int numColumns; SmartArray<FTMultiColumn*> columns; int index; int columnHeight; int columnWidth; bool fileSizeUnitKB; private: static const int MARGIN = 2; public: FTFileListView(View* parent, const char* name, Args& args) :ScrolledWindow(parent, name, args.set(XmNscrollingPolicy, XmAUTOMATIC) .set(XmNscrollBarDisplayPolicy, XmVARIABLE) ), font(NULL), folderIcon(NULL), fileIcon(NULL), bboard(NULL), columnLayout(NULL), numColumns(0), index(0), columnHeight(0), columnWidth(0), fileSizeUnitKB(true) { Color color(this); Pixel white = color.whitePixel(); int fontsize = 12; unsigned int iconw = 0; unsigned int iconh = 0; if (args.has(XmNfolderIconFile)) { const char* filename = (const char*)args.get(XmNfolderIconFile); folderIcon = new PixmapFile(getDisplay(), filename, white, white); if (folderIcon) { folderIcon -> getGeometry(&iconw, &iconh); } } if (args.has(XmNfileIconFile)) { const char* filename = (const char*)args.get(XmNfileIconFile); fileIcon = new PixmapFile(getDisplay(), filename, white, white); } Args ar; ar.reset(); if (args.has(XftNfamily)) { ar.set(XftNfamily, (const char*)args.get(XftNfamily)); } else { ar.set(XftNfamily, "Times-12"); //Default } if (args.has(XftNweight)) { ar.set(XftNweight, (int)args.get(XftNweight)); } else { ar.set(XftNweight, FC_WEIGHT_THIN);//; } if (args.has(XftNsize)) { fontsize = (int)args.get(XftNsize); // ar.set(XftNsize, fontsize); } else { ar.set(XftNsize, fontsize); //Default } font = new FTFont(getDisplay(), ar); if (iconh > fontsize) { columnHeight = iconh + MARGIN; } else { columnHeight = fontsize *2; // } ar.reset(); ar.set(XmNmarginWidth, 0); ar.set(XmNmarginHeight, 0); ar.set(XmNbackground, white); bboard = new BulletinBoard(this, "", ar); if (args.has(XmNcolumnLayout) && args.has(XmNnumColumns) ) { columnLayout = (FTColumnLayout*)args.get(XmNcolumnLayout); numColumns = (int)args.get(XmNnumColumns); } else { throw IException("XmNcolumnLayout or XmNnumColumns is not sepecified"); } columnWidth = MARGIN*2; for (int i = 0; i<numColumns; i++) { columnWidth += columnLayout[i].width; } } ~FTFileListView() { columns.clear(); delete font; delete folderIcon; delete fileIcon; delete bboard; } void removeAllItems() { columns.removeAllItems(); index = 0; } void addItems(const char* dir, int m, char** names, int type, PixmapFile* icon) { char fullpath[PATH_MAX]; for (int i = 0; i<m; i++) { try { sprintf(fullpath, "%s/%s", dir, names[i]); FileAttributes attr(fullpath); Args ar; ar.reset(); ar.set(XmNx, MARGIN); ar.set(XmNy, (columnHeight+ MARGIN*2) * index + MARGIN); ar.set(XmNrecomputeSize, False); ar.set(XmNcolumnLayout, (XtArgVal)columnLayout); ar.set(XmNnumColumns, numColumns); ar.set(XmNwidth, columnWidth); ar.set(XftNfont, (XtArgVal)font); //ar.set(XmNhighlightOnEnter, True); ar.set(XmNuserData, type); CompoundString cs(""); ar.set(XmNlabelString, cs); ar.set(XmNlabelType, XmPIXMAP_AND_STRING); if (icon) { ar.set(XmNlabelType, XmPIXMAP_AND_STRING); ar.set(XmNlabelPixmap, (XtArgVal)icon->get()); } FTMultiColumn* col = new FTMultiColumn(bboard, "", ar); LocalTime lt(attr.changedTime()); CharString ctime = lt.toCharString(); char csize[128]; MonetaryFormatter mformatter; if (fileSizeUnitKB) { unsigned long fs = attr.getSize(); unsigned long kb = fs/1024L; if ((fs % 1024L)) { kb++; } CharString value = mformatter.toString(kb); sprintf(csize, "%s KB", (const char*)value); } else { CharString value = mformatter.toString((long)attr.getSize()); sprintf(csize, "%s B", (const char*)value); } const char* items[(const int)numColumns]; int n = 0; items[n++] = names[i]; items[n++] = (const char*)ctime; items[n++] = csize; col -> setItems(items, n); columns[index++] = col; } catch (Exception& ex) { ex.display(); } } } void addEventHandler(unsigned long eventMask, CommonObject* object, Handler handler, XtPointer unused) { for (int i = 0; i<index; i++) { FTMultiColumn* col = columns[i]; if (col) { // col -> resize(); col -> addEventHandler(eventMask, object, handler, to_voidptr(i)); } } } void listupDirectories(const char* dir, const char* pattern) { DirectoryScanner scanner(dir); DirEntryList dirList; int m = scanner.scanDir(pattern, dirList); if (m > 0) { SmartPtrs<char*> names = new char*[m]; dirList.getNames((char**)names); addItems(dir, m, names, DIR, folderIcon); } } void listupFiles(const char* dir, const char* pattern) { DirectoryScanner scanner(dir); DirEntryList dirList; int m = scanner.scanFile(pattern, dirList); if (m > 0) { SmartPtrs<char*> names = new char*[m]; dirList.getNames((char**)names); addItems(dir, m, names, FILE, fileIcon); } } }; }