Build custom columns support with Makefile
[git-cheetah/bosko.git] / columns.c
blobd280428fcb4ce1389df0420a066234bae56545ee
2 #include "cache.h"
3 #include "exec.h"
5 #include <shlobj.h>
6 #include "menuengine.h"
7 #include "ext.h"
8 #include "columns.h"
10 #ifndef _MSC_VER
12 * this flag, not defined in mingw's ShlObj.h, is a hint that the file
13 * has changed since the last call to GetItemData
15 #define SHCDF_UPDATEITEM 0x00000001
17 /* convenience macro, not defined in mingw's OleAuto.h */
18 #define V_I1REF(X) V_UNION(X, pcVal)
19 #endif
21 #define CHEETAH_COLUMN_FLAGS (SHCOLSTATE_TYPE_STR)
24 * If a non-standard FMT is specified, the column will be accessible
25 * only in repo folders. But if FMTID_SummaryInformation is used,
26 * the column's info will be "merged" into CHEETAH_PID_* and may
27 * be visible in the Details on folder's task pane
29 #define CHEETAH_FMTID IID_git_columns
32 * column's id, that can be matched to one of standard FMTs
33 * for example, if FMTID is FMTID_SummaryInformation than
34 * PID can be PIDSI_AUTHOR, so the status is provided in the
35 * Author column and visible in the Details
37 #define CHEETAH_STATUS_PID 0
39 /* names and descriptions MUST be wchar * */
40 #define CHEETAH_STATUS_NAME L"Git Status"
41 #define CHEETAH_STATUS_DESC L"Status of the file in a Git repository"
43 STDMETHODIMP initialize_columns(void *p, LPCSHCOLUMNINIT psci)
45 struct git_data *this_ = ((struct git_columns *)p)->git_data;
46 int status;
48 wcstombs(this_->name, psci->wszFolder, MAX_PATH);
51 * don't try to do anything about cache here, because
52 * we're called even if get_item_data will not be called
54 status = exec_program(this_->name, NULL, NULL, WAITMODE,
55 "git", "rev-parse", "--show-prefix", NULL);
58 * if something went terribly wrong or not a repo,
59 * return E_FAIL to prevent calls to get_column_info
61 return status ? E_FAIL : S_OK;
64 STDMETHODIMP get_column_info(void *p, DWORD dwIndex, SHCOLUMNINFO *psci)
66 struct git_data *this_ = ((struct git_columns *)p)->git_data;
68 /* do NOT FORGET to increase this when adding more columns */
69 if (0 < dwIndex)
70 return S_FALSE;
72 psci->scid.fmtid = CHEETAH_FMTID;
73 psci->scid.pid = CHEETAH_STATUS_PID;
74 psci->vt = VT_LPSTR;
75 psci->fmt = LVCFMT_LEFT;
76 psci->cChars = 15;
77 psci->csFlags = CHEETAH_COLUMN_FLAGS;
79 lstrcpynW(psci->wszTitle,
80 CHEETAH_STATUS_NAME, MAX_COLUMN_NAME_LEN);
81 lstrcpynW(psci->wszDescription,
82 CHEETAH_STATUS_DESC, MAX_COLUMN_DESC_LEN);
84 return S_OK;
88 * cache files' status, and return non-zero on the first failure
89 * because if something goes wrong, there is no need to try other statuses
91 static int cache(struct git_data *this_)
93 /* if everything succeeded, return success */
94 return 0;
97 static char *parse_status(struct git_data *this_, char *file)
99 /* if no status was found, return NULL string */
100 return NULL;
104 STDMETHODIMP get_item_data(void *p,
105 LPCSHCOLUMNID pscid,
106 LPCSHCOLUMNDATA pscd,
107 VARIANT *pvarData)
109 struct git_data *this_ = ((struct git_columns *)p)->git_data;
110 char file_path[MAX_PATH], *file = file_path;
111 char *result;
113 /* directories don't have status */
114 if (pscd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
115 return S_FALSE;
117 /* update cache and bail out on failure */
118 if (cache(this_))
119 return S_FALSE;
121 if (pscd->dwFlags & SHCDF_UPDATEITEM) {
123 * we can add the file to the usual ls-files
124 * or we can refresh the whole cache
128 wcstombs(file, pscd->wszFile, MAX_PATH);
129 file += strlen(this_->name) + 1;
131 /* get the status from cache and return if any */
132 if (result = parse_status(this_, file)) {
133 V_VT(pvarData) = VT_LPSTR;
134 V_I1REF(pvarData) = result;
135 return S_OK;
138 return S_FALSE;
141 DEFINE_STANDARD_METHODS(git_columns)
143 struct git_columns_virtual_table git_columns_virtual_table = {
144 query_interface_git_columns,
145 add_ref_git_columns,
146 release_git_columns,
147 initialize_columns,
148 get_column_info,
149 get_item_data